summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolbump.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lldrawpoolbump.cpp')
-rw-r--r--indra/newview/lldrawpoolbump.cpp432
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)