diff options
author | Mark Palange <palange@lindenlab.com> | 2008-11-07 17:51:03 +0000 |
---|---|---|
committer | Mark Palange <palange@lindenlab.com> | 2008-11-07 17:51:03 +0000 |
commit | f89f19990cbb9f3f2e7473ac6c159098bdfabec7 (patch) | |
tree | e7fa406e2db5e9adc2e24e00557d7b3d3f93203a /indra/llrender/llimagegl.cpp | |
parent | b2bfb128e7d30e1cdb293a2ac192a0cbe63fe528 (diff) |
QAR-992 Merging revisions 101012-101170,101686-101687 of svn+ssh://svn.lindenlab.com/svn/linden/qa/viewer_combo_1-22-merge into linden/release
Diffstat (limited to 'indra/llrender/llimagegl.cpp')
-rw-r--r-- | indra/llrender/llimagegl.cpp | 266 |
1 files changed, 138 insertions, 128 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 1c9b4d9693..2ef2bae1ab 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -125,49 +125,6 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) //---------------------------------------------------------------------------- // static -void LLImageGL::bindExternalTexture(LLGLuint gl_name, S32 stage, LLGLenum bind_target ) -{ - gGL.flush(); - if (stage > 0) - { - gGL.getTexUnit(stage)->activate(); - } - glBindTexture(bind_target, gl_name); - sCurrentBoundTextures[stage] = gl_name; - if (stage > 0) - { - gGL.getTexUnit(0)->activate(); - } -} - -// static -void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target) -{ - // LLGLSLShader can return -1 - if (stage >= 0) - { - gGL.flush(); - if (stage > 0) - { - gGL.getTexUnit(stage)->activate(); - glBindTexture(GL_TEXTURE_2D, 0); - gGL.getTexUnit(0)->activate(); - } - else - { - glBindTexture(GL_TEXTURE_2D, 0); - } - sCurrentBoundTextures[stage] = 0; - } -} - -// static (duplicated for speed and to avoid GL_TEXTURE_2D default argument which requires GL header dependency) -void LLImageGL::unbindTexture(S32 stage) -{ - unbindTexture(stage, GL_TEXTURE_2D); -} - -// static void LLImageGL::updateStats(F32 current_time) { sLastFrameTime = current_time; @@ -189,7 +146,7 @@ void LLImageGL::destroyGL(BOOL save_state) { for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++) { - LLImageGL::unbindTexture(stage, GL_TEXTURE_2D); + gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); } for (std::set<LLImageGL*>::iterator iter = sImageList.begin(); iter != sImageList.end(); iter++) @@ -284,6 +241,8 @@ LLImageGL::~LLImageGL() { LLImageGL::cleanup(); sImageList.erase(this); + delete [] mPickMask; + mPickMask = NULL; sCount--; } @@ -293,11 +252,12 @@ void LLImageGL::init(BOOL usemipmaps) mMissed = FALSE; #endif + mPickMask = NULL; mTextureMemory = 0; mLastBindTime = 0.f; mTarget = GL_TEXTURE_2D; - mBindTarget = GL_TEXTURE_2D; + mBindTarget = LLTexUnit::TT_TEXTURE; mUseMipMaps = usemipmaps; mHasMipMaps = FALSE; mAutoGenMips = FALSE; @@ -321,6 +281,8 @@ void LLImageGL::init(BOOL usemipmaps) mFormatType = GL_UNSIGNED_BYTE; mFormatSwapBytes = FALSE; mHasExplicitFormat = FALSE; + + mInitialized = true; } void LLImageGL::cleanup() @@ -421,41 +383,14 @@ void LLImageGL::dump() //---------------------------------------------------------------------------- -BOOL LLImageGL::bindTextureInternal(const S32 stage) const +void LLImageGL::updateBindStats(void) const { - if (gGLManager.mIsDisabled) - { - llwarns << "Trying to bind a texture while GL is disabled!" << llendl; - } - - - if (sCurrentBoundTextures[stage] && sCurrentBoundTextures[stage] == mTexName) - { - // already set! - return TRUE; - } - if (mTexName != 0) { #ifdef DEBUG_MISS mMissed = ! getIsResident(TRUE); #endif - - gGL.flush(); - if (stage > 0) - { - gGL.getTexUnit(stage)->activate(); - } - - glBindTexture(mBindTarget, mTexName); - sCurrentBoundTextures[stage] = mTexName; sBindCount++; - - if (stage > 0) - { - gGL.getTexUnit(0)->activate(); - } - if (mLastBindTime != sLastFrameTime) { // we haven't accounted for this texture yet this frame @@ -463,38 +398,22 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const updateBoundTexMem(mTextureMemory); mLastBindTime = sLastFrameTime; } - - return TRUE; - } - else - { - gGL.flush(); - if (stage > 0) - { - gGL.getTexUnit(stage)->activate(); - } - glBindTexture(mBindTarget, 0); - if (stage > 0) - { - gGL.getTexUnit(0)->activate(); - } - sCurrentBoundTextures[stage] = 0; - return FALSE; } } //virtual -BOOL LLImageGL::bind(const S32 stage) const +bool LLImageGL::bindError(const S32 stage) const { - if (stage == -1) - { - return FALSE; - } - BOOL res = bindTextureInternal(stage); - //llassert(res); - return res; + return false; +} + +//virtual +bool LLImageGL::bindDefaultImage(const S32 stage) const +{ + return false; } + void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes ) { // Note: must be called before createTexture() @@ -532,7 +451,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) { // LLFastTimer t2(LLFastTimer::FTM_TEMP2); - llverify(bindTextureInternal(0)); + llverify(gGL.getTexUnit(0)->bind(this)); } if (mUseMipMaps) @@ -569,7 +488,8 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } glTexImage2D(mTarget, gl_level, mFormatInternal, w, h, 0, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in); - + updatePickMask(w, h, data_in); + if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); @@ -585,7 +505,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) { if (mAutoGenMips) { - glTexParameteri(mBindTarget, GL_GENERATE_MIPMAP_SGIS, TRUE); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE); stop_glerror(); { // LLFastTimer t2(LLFastTimer::FTM_TEMP4); @@ -596,12 +516,17 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) stop_glerror(); } + S32 w = getWidth(mCurrentDiscardLevel); + S32 h = getHeight(mCurrentDiscardLevel); + glTexImage2D(mTarget, 0, mFormatInternal, - getWidth(mCurrentDiscardLevel), getHeight(mCurrentDiscardLevel), 0, + w, h, 0, mFormatPrimary, mFormatType, data_in); stop_glerror(); + updatePickMask(w, h, data_in); + if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); @@ -651,6 +576,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) glTexImage2D(mTarget, m, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, cur_mip_data); stop_glerror(); + if (m == 0) + { + updatePickMask(w, h, cur_mip_data); + } if(mFormatSwapBytes) { @@ -701,6 +630,8 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) glTexImage2D(mTarget, 0, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, (GLvoid *)data_in); + updatePickMask(w, h, data_in); + stop_glerror(); if(mFormatSwapBytes) @@ -713,6 +644,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) mHasMipMaps = FALSE; } stop_glerror(); + mInitialized = true; } BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) @@ -786,12 +718,10 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 datap += (y_pos * data_width + x_pos) * getComponents(); // Update the GL texture - BOOL res = bindTextureInternal(0); + BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName); if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl; stop_glerror(); - LLGLEnable tex( GL_TEXTURE_2D ); - glTexSubImage2D(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, datap); stop_glerror(); @@ -804,6 +734,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); stop_glerror(); + mInitialized = true; } return TRUE; @@ -817,9 +748,10 @@ BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S3 // Copy sub image from frame buffer BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height) { - if (bindTextureInternal(0)) + if (gGL.getTexUnit(0)->bind(this)) { glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); + mInitialized = true; stop_glerror(); return TRUE; } @@ -919,9 +851,9 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ stop_glerror(); { // LLFastTimer t1(LLFastTimer::FTM_TEMP6); - llverify(bindTextureInternal(0)); - glTexParameteri(mBindTarget, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(mBindTarget, GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level); + llverify(gGL.getTexUnit(0)->bind(this)); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level); } } if (!mTexName) @@ -949,7 +881,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ setMipFilterNearest(mMagFilterNearest); // things will break if we don't unbind after creation - unbindTexture(0, mBindTarget); + gGL.getTexUnit(0)->unbind(mBindTarget); stop_glerror(); if (old_name != 0) @@ -1050,8 +982,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre S32 gl_discard = discard_level - mCurrentDiscardLevel; //explicitly unbind texture - LLImageGL::unbindTexture(0, mTarget); - llverify(bindTextureInternal(0)); + gGL.getTexUnit(0)->unbind(mBindTarget); + llverify(gGL.getTexUnit(0)->bind(this)); if (gDebugGL) { @@ -1148,15 +1080,15 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre void LLImageGL::destroyGLTexture() { - stop_glerror(); - if (mTexName != 0) { + stop_glerror(); + for (int i = 0; i < gGLManager.mNumTextureUnits; i++) { if (sCurrentBoundTextures[i] == mTexName) { - unbindTexture(i, GL_TEXTURE_2D); + gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE); stop_glerror(); } } @@ -1184,8 +1116,8 @@ void LLImageGL::glClamp (BOOL clamps, BOOL clampt) { if (mTexName != 0) { - glTexParameteri (mBindTarget, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); - glTexParameteri (mBindTarget, GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT); + glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); + glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT); } } @@ -1223,23 +1155,23 @@ void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest) { if (mMinFilterNearest) { - glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_NEAREST); } else if (mHasMipMaps) { - glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { - glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR); } if (mMagFilterNearest) { - glTexParameteri(mBindTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_NEAREST); } else { - glTexParameteri(mBindTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_LINEAR); } if (gGLManager.mHasAnisotropic) { @@ -1247,16 +1179,15 @@ void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest) { F32 largest_anisotropy; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_anisotropy); - glTexParameterf(mBindTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_anisotropy); + glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_anisotropy); } else { - glTexParameterf(mBindTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); + glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); } } - } - - stop_glerror(); + stop_glerror(); + } } BOOL LLImageGL::getIsResident(BOOL test_now) @@ -1337,14 +1268,93 @@ BOOL LLImageGL::getBoundRecently() const return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME); } -void LLImageGL::setTarget(const LLGLenum target, const LLGLenum bind_target) +void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target) { mTarget = target; mBindTarget = bind_target; } +void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) +{ + if (mFormatType != GL_UNSIGNED_BYTE || + mFormatPrimary != GL_RGBA) + { + //cannot generate a pick mask for this texture + delete [] mPickMask; + mPickMask = NULL; + return; + } + + U32 pick_width = width/2; + U32 pick_height = height/2; + + U32 size = llmax(pick_width, (U32) 1) * llmax(pick_height, (U32) 1); + + size = size/8 + 1; + + delete[] mPickMask; + mPickMask = new U8[size]; + + memset(mPickMask, 0, sizeof(U8) * size); + + U32 pick_bit = 0; + + for (S32 y = 0; y < height; y += 2) + { + for (S32 x = 0; x < width; x += 2) + { + U8 alpha = data_in[(y*width+x)*4+3]; + + if (alpha > 32) + { + U32 pick_idx = pick_bit/8; + U32 pick_offset = pick_bit%8; + if (pick_idx >= size) + { + llerrs << "WTF?" << llendl; + } + + mPickMask[pick_idx] |= 1 << pick_offset; + } + + ++pick_bit; + } + } +} + +BOOL LLImageGL::getMask(const LLVector2 &tc) +{ + BOOL res = TRUE; + + if (mPickMask) + { + S32 width = getWidth()/2; + S32 height = getHeight()/2; + + F32 u = tc.mV[0] - floorf(tc.mV[0]); + F32 v = tc.mV[1] - floorf(tc.mV[1]); + + if (u < 0.f || u > 1.f || + v < 0.f || v > 1.f) + { + llerrs << "WTF?" << llendl; + } + + S32 x = (S32)(u * width); + S32 y = (S32)(v * height); + + S32 idx = y*width+x; + S32 offset = idx%8; + + res = mPickMask[idx/8] & (1 << offset) ? TRUE : FALSE; + } + + return res; +} + //---------------------------------------------------------------------------- + // Manual Mip Generation /* S32 width = getWidth(discard_level); |