diff options
Diffstat (limited to 'indra/newview/lldrawpoolbump.cpp')
-rw-r--r-- | indra/newview/lldrawpoolbump.cpp | 432 |
1 files changed, 108 insertions, 324 deletions
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index eec17149e7..7289e95b6e 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -77,12 +77,7 @@ static LLGLSLShader* shader = NULL; static S32 cube_channel = -1; static S32 diffuse_channel = -1; static S32 bump_channel = -1; -static BOOL shiny = FALSE; - -// Enabled after changing LLViewerTexture::mNeedsCreateTexture to an -// LLAtomicBool; this should work just fine, now. HB -#define LL_BUMPLIST_MULTITHREADED 1 - +static bool shiny = false; // static void LLStandardBumpmap::shutdown() @@ -165,7 +160,7 @@ void LLStandardBumpmap::addstandard() gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id)); gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ; - gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL ); + gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, true, false, NULL, NULL ); gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0, 30.f) ; LLStandardBumpmap::sStandardBumpmapCount++; } @@ -198,7 +193,7 @@ void LLStandardBumpmap::destroyGL() LLDrawPoolBump::LLDrawPoolBump() : LLRenderPass(LLDrawPool::POOL_BUMP) { - shiny = FALSE; + shiny = false; } @@ -354,7 +349,7 @@ void LLDrawPoolBump::beginFullbrightShiny() diffuse_channel = 0; } - shiny = TRUE; + shiny = true; } void LLDrawPoolBump::renderFullbrightShiny() @@ -406,7 +401,7 @@ void LLDrawPoolBump::endFullbrightShiny() diffuse_channel = -1; cube_channel = 0; - shiny = FALSE; + shiny = false; } void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, bool texture = true) @@ -426,7 +421,7 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, bool texture = // static -BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) +bool LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) { U8 bump_code = params.mBump; @@ -434,7 +429,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) } //static -BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel) +bool LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel) { const LLTextureEntry* te = face->getTextureEntry(); if (te) @@ -443,11 +438,11 @@ BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel) return bindBumpMap(bump_code, face->getTexture(), channel); } - return FALSE; + return false; } //static -BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, S32 channel) +bool LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, S32 channel) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //Note: texture atlas does not support bump texture now. @@ -455,7 +450,7 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, S32 cha if(!tex) { //if the texture is not a fetched texture - return FALSE; + return false; } LLViewerTexture* bump = NULL; @@ -491,10 +486,10 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, S32 cha gGL.getTexUnit(channel)->bind(bump); } - return TRUE; + return true; } - return FALSE; + return false; } //static @@ -549,7 +544,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - shiny = TRUE; + shiny = true; for (int i = 0; i < 2; ++i) { bool rigged = i == 1; @@ -597,7 +592,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass) gGL.getTexUnit(0)->activate(); } - shiny = FALSE; + shiny = false; } @@ -699,17 +694,19 @@ void LLBumpImageList::addTextureStats(U8 bump, const LLUUID& base_image_id, F32 void LLBumpImageList::updateImages() { + llassert(LLCoros::on_main_thread_main_coro()); // This code is not thread safe + for (bump_image_map_t::iterator iter = mBrightnessEntries.begin(); iter != mBrightnessEntries.end(); ) { LLViewerTexture* image = iter->second; if( image ) { - BOOL destroy = TRUE; + bool destroy = true; if( image->hasGLTexture()) { if( image->getBoundRecently() ) { - destroy = FALSE; + destroy = false; } else { @@ -733,12 +730,12 @@ void LLBumpImageList::updateImages() LLViewerTexture* image = curiter->second; if( image ) { - BOOL destroy = TRUE; + bool destroy = true; if( image->hasGLTexture()) { if( image->getBoundRecently() ) { - destroy = FALSE; + destroy = false; } else { @@ -762,24 +759,21 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; llassert( (bump_code == BE_BRIGHTNESS) || (bump_code == BE_DARKNESS) ); - LLViewerTexture* bump = NULL; + LLViewerTexture* bump = nullptr; - bump_image_map_t* entries_list = NULL; - void (*callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) = NULL; + bump_image_map_t* entries_list = nullptr; switch( bump_code ) { case BE_BRIGHTNESS: entries_list = &mBrightnessEntries; - callback_func = LLBumpImageList::onSourceBrightnessLoaded; break; case BE_DARKNESS: entries_list = &mDarknessEntries; - callback_func = LLBumpImageList::onSourceDarknessLoaded; break; default: llassert(0); - return NULL; + return nullptr; } bump_image_map_t::iterator iter = entries_list->find(src_image->getID()); @@ -787,52 +781,19 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText { bump = iter->second; } - else - { - (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE ); - bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image - } - - if (!src_image->hasCallbacks()) - { //if image has no callbacks but resolutions don't match, trigger raw image loaded callback again - if (src_image->getWidth() != bump->getWidth() || - src_image->getHeight() != bump->getHeight())// || - //(LLPipeline::sRenderDeferred && bump->getComponents() != 4)) - { - src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ; - src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL ); - src_image->forceToSaveRawImage(0) ; - } - } - - return bump; -} - -// static -void LLBumpImageList::onSourceBrightnessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - LLUUID* source_asset_id = (LLUUID*)userdata; - LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_BRIGHTNESS ); - if( final ) + if (bump == nullptr || + src_image->getWidth() != bump->getWidth() || + src_image->getHeight() != bump->getHeight()) { - delete source_asset_id; + onSourceUpdated(src_image, (EBumpEffect) bump_code); } -} -// static -void LLBumpImageList::onSourceDarknessLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) -{ - LLUUID* source_asset_id = (LLUUID*)userdata; - LLBumpImageList::onSourceLoaded( success, src_vi, src, *source_asset_id, BE_DARKNESS ); - if( final ) - { - delete source_asset_id; - } + return (*entries_list)[src_image->getID()]; } -void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) + +void LLBumpImageList::onSourceStandardLoaded( bool success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, bool final, void* userdata) { if (success && LLPipeline::sRenderDeferred) { @@ -850,11 +811,14 @@ void LLBumpImageList::onSourceStandardLoaded( BOOL success, LLViewerFetchedTextu void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nrm_image) { + LLImageDataSharedLock lockIn(src); + LLImageDataLock lockOut(nrm_image); + U8* nrm_data = nrm_image->getData(); S32 resX = src->getWidth(); S32 resY = src->getHeight(); - U8* src_data = src->getData(); + const U8* src_data = src->getData(); S32 src_cmp = src->getComponents(); @@ -904,288 +868,108 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr } // static -void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code ) +void LLBumpImageList::onSourceUpdated(LLViewerTexture* src, EBumpEffect bump_code) { - LL_PROFILE_ZONE_SCOPED; - - if( success ) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - - - bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries ); - bump_image_map_t::iterator iter = entries_list.find(source_asset_id); - - { - if (iter == entries_list.end() || - iter->second.isNull() || - iter->second->getWidth() != src->getWidth() || - iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution - { //make sure an entry exists for this image - entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture(TRUE); - iter = entries_list.find(src_vi->getID()); - } - } - - if (iter->second->getWidth() != src->getWidth() || - iter->second->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution - { - LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1); - U8* dst_data = dst_image->getData(); - S32 dst_data_size = dst_image->getDataSize(); - - U8* src_data = src->getData(); - S32 src_data_size = src->getDataSize(); - - S32 src_components = src->getComponents(); - - // Convert to luminance and then scale and bias that to get ready for - // embossed bump mapping. (0-255 maps to 127-255) - - // Convert to fixed point so we don't have to worry about precision/clamping. - const S32 FIXED_PT = 8; - const S32 R_WEIGHT = S32(0.2995f * (1<<FIXED_PT)); - const S32 G_WEIGHT = S32(0.5875f * (1<<FIXED_PT)); - const S32 B_WEIGHT = S32(0.1145f * (1<<FIXED_PT)); - - S32 minimum = 255; - S32 maximum = 0; - - switch( src_components ) - { - case 1: - case 2: - { - if( src_data_size == dst_data_size * src_components ) - { - for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) - { - dst_data[i] = src_data[j]; - if( dst_data[i] < minimum ) - { - minimum = dst_data[i]; - } - if( dst_data[i] > maximum ) - { - maximum = dst_data[i]; - } - } - } - else - { - llassert(0); - dst_image->clear(); - } - } - break; - case 3: - case 4: - { - if( src_data_size == dst_data_size * src_components ) - { - for( S32 i = 0, j=0; i < dst_data_size; i++, j+= src_components ) - { - // RGB to luminance - dst_data[i] = (R_WEIGHT * src_data[j] + G_WEIGHT * src_data[j+1] + B_WEIGHT * src_data[j+2]) >> FIXED_PT; - //llassert( dst_data[i] <= 255 );true because it's 8bit - if( dst_data[i] < minimum ) - { - minimum = dst_data[i]; - } - if( dst_data[i] > maximum ) - { - maximum = dst_data[i]; - } - } - } - else - { - llassert(0); - dst_image->clear(); - } - } - break; - default: - llassert(0); - dst_image->clear(); - break; - } - - if( maximum > minimum ) - { - U8 bias_and_scale_lut[256]; - F32 twice_one_over_range = 2.f / (maximum - minimum); - S32 i; - - const F32 ARTIFICIAL_SCALE = 2.f; // Advantage: exaggerates the effect in midrange. Disadvantage: clamps at the extremes. - if (BE_DARKNESS == bump_code) - { - for( i = minimum; i <= maximum; i++ ) - { - F32 minus_one_to_one = F32(maximum - i) * twice_one_over_range - 1.f; - bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); - } - } - else - { - for( i = minimum; i <= maximum; i++ ) - { - F32 minus_one_to_one = F32(i - minimum) * twice_one_over_range - 1.f; - bias_and_scale_lut[i] = llclampb(ll_round(127 * minus_one_to_one * ARTIFICIAL_SCALE + 128)); - } - } - - for( i = 0; i < dst_data_size; i++ ) - { - dst_data[i] = bias_and_scale_lut[dst_data[i]]; - } - } - - //--------------------------------------------------- - // immediately assign bump to a smart pointer in case some local smart pointer - // accidentally releases it. - LLPointer<LLViewerTexture> bump = iter->second; - - if (!LLPipeline::sRenderDeferred) - { - bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA); - -#if LL_BUMPLIST_MULTITHREADED - auto tex_queue = LLImageGLThread::sEnabledTextures ? sTexUpdateQueue.lock() : nullptr; - - if (tex_queue) - { //dispatch creation to background thread - LLImageRaw* dst_ptr = dst_image; - LLViewerTexture* bump_ptr = bump; - dst_ptr->ref(); - bump_ptr->ref(); - tex_queue->post( - [=]() - { - LL_PROFILE_ZONE_NAMED("bil - create texture"); - bump_ptr->createGLTexture(0, dst_ptr); - bump_ptr->unref(); - dst_ptr->unref(); - }); - - } - else -#endif - { - bump->createGLTexture(0, dst_image); - } - } - else - { //convert to normal map - LL_PROFILE_ZONE_NAMED("bil - create normal map"); - LLImageGL* img = bump->getGLTexture(); - LLImageRaw* dst_ptr = dst_image.get(); - LLGLTexture* bump_ptr = bump.get(); - - dst_ptr->ref(); - img->ref(); - bump_ptr->ref(); - auto create_func = [=]() - { - img->setUseMipMaps(TRUE); - // upload dst_image to GPU (greyscale in red channel) - img->setExplicitFormat(GL_RED, GL_RED); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - bump_ptr->createGLTexture(0, dst_ptr); - dst_ptr->unref(); - }; + const LLUUID& src_id = src->getID(); - auto generate_func = [=]() - { - // Allocate an empty RGBA texture at "tex_name" the same size as bump - // Note: bump will still point at GPU copy of dst_image - bump_ptr->setExplicitFormat(GL_RGBA, GL_RGBA); - LLGLuint tex_name; - img->createGLTexture(0, nullptr, 0, 0, true, &tex_name); + bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries); + bump_image_map_t::iterator iter = entries_list.find(src_id); - // point render target at empty buffer - sRenderTarget.setColorAttachment(img, tex_name); + if (iter == entries_list.end()) + { //make sure an entry exists for this image + entries_list[src_id] = LLViewerTextureManager::getLocalTexture(true); + iter = entries_list.find(src_id); + } - // generate normal map in empty texture - { - sRenderTarget.bindTarget(); + //--------------------------------------------------- + // immediately assign bump to a smart pointer in case some local smart pointer + // accidentally releases it. + LLPointer<LLViewerTexture> bump = iter->second; - LLGLDepthTest depth(GL_FALSE); - LLGLDisable cull(GL_CULL_FACE); - LLGLDisable blend(GL_BLEND); - gGL.setColorMask(TRUE, TRUE); + if (bump->getWidth() != src->getWidth() || + bump->getHeight() != src->getHeight()) // bump not cached yet or has changed resolution + { + //convert to normal map + LL_PROFILE_ZONE_NAMED("bil - create normal map"); - gNormalMapGenProgram.bind(); + bump->setExplicitFormat(GL_RGBA, GL_RGBA); - static LLStaticHashedString sNormScale("norm_scale"); - static LLStaticHashedString sStepX("stepX"); - static LLStaticHashedString sStepY("stepY"); + LLImageGL* src_img = src->getGLTexture(); + LLImageGL* dst_img = bump->getGLTexture(); + dst_img->setSize(src->getWidth(), src->getHeight(), 4, 0); + dst_img->setUseMipMaps(true); + dst_img->setDiscardLevel(0); + dst_img->createGLTexture(); - gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale")); - gNormalMapGenProgram.uniform1f(sStepX, 1.f / bump_ptr->getWidth()); - gNormalMapGenProgram.uniform1f(sStepY, 1.f / bump_ptr->getHeight()); + gGL.getTexUnit(0)->bind(bump); - gGL.getTexUnit(0)->bind(bump_ptr); + LLImageGL::setManualImage(GL_TEXTURE_2D, 0, dst_img->getPrimaryFormat(), dst_img->getWidth(), dst_img->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false); - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(0, 0); - gGL.vertex2f(0, 0); + LLGLuint tex_name = dst_img->getTexName(); + // point render target at empty buffer + sRenderTarget.setColorAttachment(bump->getGLTexture(), tex_name); - gGL.texCoord2f(0, 1); - gGL.vertex2f(0, 1); + // generate normal map in empty texture + { + sRenderTarget.bindTarget(); - gGL.texCoord2f(1, 0); - gGL.vertex2f(1, 0); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable cull(GL_CULL_FACE); + LLGLDisable blend(GL_BLEND); + gGL.setColorMask(true, true); - gGL.texCoord2f(1, 1); - gGL.vertex2f(1, 1); + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + gNormalMapGenProgram.bind(); - gGL.end(); + static LLStaticHashedString sNormScale("norm_scale"); + static LLStaticHashedString sStepX("stepX"); + static LLStaticHashedString sStepY("stepY"); + static LLStaticHashedString sBumpCode("bump_code"); - gGL.flush(); + gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale")); + gNormalMapGenProgram.uniform1f(sStepX, 1.f / bump->getWidth()); + gNormalMapGenProgram.uniform1f(sStepY, 1.f / bump->getHeight()); + gNormalMapGenProgram.uniform1i(sBumpCode, bump_code); - gNormalMapGenProgram.unbind(); + gGL.getTexUnit(0)->bind(src); - sRenderTarget.flush(); - sRenderTarget.releaseColorAttachment(); - } + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(0, 0); + gGL.vertex2f(0, 0); - // point bump at normal map and free gpu copy of dst_image - img->syncTexName(tex_name); + gGL.texCoord2f(0, 1); + gGL.vertex2f(0, 1); - // generate mipmap - gGL.getTexUnit(0)->bind(img); - glGenerateMipmap(GL_TEXTURE_2D); - gGL.getTexUnit(0)->disable(); + gGL.texCoord2f(1, 0); + gGL.vertex2f(1, 0); - bump_ptr->unref(); - img->unref(); - }; + gGL.texCoord2f(1, 1); + gGL.vertex2f(1, 1); -#if LL_BUMPLIST_MULTITHREADED - auto main_queue = LLImageGLThread::sEnabledTextures ? sMainQueue.lock() : nullptr; + gGL.end(); - if (main_queue) - { //dispatch texture upload to background thread, issue GPU commands to generate normal map on main thread - main_queue->postTo( - sTexUpdateQueue, - create_func, - generate_func); - } - else -#endif - { // immediate upload texture and generate normal map - create_func(); - generate_func(); - } + gGL.flush(); + sRenderTarget.flush(); + sRenderTarget.releaseColorAttachment(); + if (shader) + { + shader->bind(); } - - iter->second = bump; // derefs (and deletes) old image - //--------------------------------------------------- } + + // generate mipmap + gGL.getTexUnit(0)->bind(bump); + glGenerateMipmap(GL_TEXTURE_2D); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } + + iter->second = bump; // derefs (and deletes) old image + //--------------------------------------------------- + } void LLDrawPoolBump::pushBumpBatches(U32 type) |