diff options
Diffstat (limited to 'indra/llrender/llimagegl.cpp')
-rw-r--r-- | indra/llrender/llimagegl.cpp | 153 |
1 files changed, 114 insertions, 39 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index ff47c57c70..9d037f2565 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -2,31 +2,25 @@ * @file llimagegl.cpp * @brief Generic GL image handler * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -109,11 +103,20 @@ void LLImageGL::checkTexSize(bool forced) const { if ((forced || gDebugGL) && mTarget == GL_TEXTURE_2D) { + { + //check viewport + GLint vp[4] ; + glGetIntegerv(GL_VIEWPORT, vp) ; + llcallstacks << "viewport: " << vp[0] << " : " << vp[1] << " : " << vp[2] << " : " << vp[3] << llcallstacksendl ; + } + GLint texname; glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname); BOOL error = FALSE; if (texname != mTexName) { + llinfos << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << llendl; + error = TRUE; if (gDebugSession) { @@ -141,12 +144,12 @@ void LLImageGL::checkTexSize(bool forced) const if (gDebugSession) { gFailLog << "wrong texture size and discard level!" << - mWidth << " Height: " << mHeight << " Current Level: " << mCurrentDiscardLevel << std::endl; + mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << std::endl; } else { llerrs << "wrong texture size and discard level: width: " << - mWidth << " Height: " << mHeight << " Current Level: " << mCurrentDiscardLevel << llendl ; + mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << llendl ; } } @@ -1048,8 +1051,13 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_ { if (gGL.getTexUnit(0)->bind(this, false, true)) { - checkTexSize(true) ; - llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << llcallstacksendl ; + if(gGLManager.mDebugGPU) + { + llinfos << "Calling glCopyTexSubImage2D(...)" << llendl ; + checkTexSize(true) ; + llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << + " : " << (S32)mComponents << llcallstacksendl ; + } glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); mGLTextureCreated = true; @@ -1645,7 +1653,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() } } -void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) +void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h) { if(!mNeedsAlphaAndPickMask) { @@ -1653,26 +1661,91 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) } U32 length = w * h; - const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset ; + U32 alphatotal = 0; - S32 sample[16]; - memset(sample, 0, sizeof(S32)*16); - - for (U32 i = 0; i < length; i++) + U32 sample[16]; + memset(sample, 0, sizeof(U32)*16); + + // generate histogram of quantized alpha. + // also add-in the histogram of a 2x2 box-sampled version. The idea is + // this will mid-skew the data (and thus increase the chances of not + // being used as a mask) from high-frequency alpha maps which + // suffer the worst from aliasing when used as alpha masks. + if (w >= 2 && h >= 2) + { + llassert(w%2 == 0); + llassert(h%2 == 0); + const GLubyte* rowstart = ((const GLubyte*) data_in) + mAlphaOffset; + for (U32 y = 0; y < h; y+=2) + { + const GLubyte* current = rowstart; + for (U32 x = 0; x < w; x+=2) + { + const U32 s1 = current[0]; + alphatotal += s1; + const U32 s2 = current[w * mAlphaStride]; + alphatotal += s2; + current += mAlphaStride; + const U32 s3 = current[0]; + alphatotal += s3; + const U32 s4 = current[w * mAlphaStride]; + alphatotal += s4; + current += mAlphaStride; + + ++sample[s1/16]; + ++sample[s2/16]; + ++sample[s3/16]; + ++sample[s4/16]; + + const U32 asum = (s1+s2+s3+s4); + alphatotal += asum; + sample[asum/(16*4)] += 4; + } + + rowstart += 2 * w * mAlphaStride; + } + length *= 2; // we sampled everything twice, essentially + } + else { - ++sample[*current/16]; - current += mAlphaStride ; + const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset; + for (U32 i = 0; i < length; i++) + { + const U32 s1 = *current; + alphatotal += s1; + ++sample[s1/16]; + current += mAlphaStride; + } } + + // if more than 1/16th of alpha samples are mid-range, this + // shouldn't be treated as a 1-bit mask - U32 total = 0; + // also, if all of the alpha samples are clumped on one half + // of the range (but not at an absolute extreme), then consider + // this to be an intentional effect and don't treat as a mask. + + U32 midrangetotal = 0; for (U32 i = 4; i < 11; i++) { - total += sample[i]; + midrangetotal += sample[i]; + } + U32 lowerhalftotal = 0; + for (U32 i = 0; i < 8; i++) + { + lowerhalftotal += sample[i]; + } + U32 upperhalftotal = 0; + for (U32 i = 8; i < 16; i++) + { + upperhalftotal += sample[i]; } - if (total > length/16) + if (midrangetotal > length/16 || // lots of midrange, or + (lowerhalftotal == length && alphatotal != 0) || // all close to transparent but not all totally transparent, or + (upperhalftotal == length && alphatotal != 255*length)) // all close to opaque but not all totally opaque { - mIsMask = FALSE; + mIsMask = FALSE; // not suitable for masking } else { @@ -1748,7 +1821,8 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) { LL_WARNS_ONCE("render") << "Ugh, non-finite u/v in mask pick" << LL_ENDL; u = v = 0.f; - llassert(false); + // removing assert per EXT-4388 + // llassert(false); } if (LL_UNLIKELY(u < 0.f || u > 1.f || @@ -1756,7 +1830,8 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) { LL_WARNS_ONCE("render") << "Ugh, u/v out of range in image mask pick" << LL_ENDL; u = v = 0.f; - llassert(false); + // removing assert per EXT-4388 + // llassert(false); } S32 x = llfloor(u * mPickMaskWidth); |