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.cpp226
1 files changed, 148 insertions, 78 deletions
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 471b0e2c48..1d5419b515 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -54,6 +54,8 @@
// static
LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT];
+LL::WorkQueue::weak_t LLBumpImageList::sMainQueue;
+LL::WorkQueue::weak_t LLBumpImageList::sTexUpdateQueue;
// static
U32 LLStandardBumpmap::sStandardBumpmapCount = 0;
@@ -74,6 +76,8 @@ static S32 cube_channel = -1;
static S32 diffuse_channel = -1;
static S32 bump_channel = -1;
+#define LL_BUMPLIST_MULTITHREADED 0
+
// static
void LLStandardBumpmap::init()
{
@@ -761,6 +765,8 @@ void LLBumpImageList::init()
LLStandardBumpmap::init();
LLStandardBumpmap::restoreGL();
+ sMainQueue = LL::WorkQueue::getInstance("mainloop");
+ sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.
}
void LLBumpImageList::clear()
@@ -909,10 +915,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
}
else
{
- LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
- raw->clear(0x77, 0x77, 0xFF, 0xFF);
-
- (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
+ (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( TRUE );
bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image
}
@@ -1043,16 +1046,13 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
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
- LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1);
- raw->clear(0x77, 0x77, 0xFF, 0xFF);
-
- entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE);
+ 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
+ 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();
@@ -1166,108 +1166,178 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
}
//---------------------------------------------------
- // immediately assign bump to a global smart pointer in case some local smart pointer
+ // immediately assign bump to a smart pointer in case some local smart pointer
// accidentally releases it.
- LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE );
+ LLPointer<LLViewerTexture> bump = iter->second;
if (!LLPipeline::sRenderDeferred)
{
bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
- bump->createGLTexture(0, dst_image);
+
+#if LL_BUMPLIST_MULTITHREADED
+ auto tex_queue = LLImageGLThread::sEnabled ? 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
//disable compression on normal maps to prevent errors below
bump->getGLTexture()->setAllowCompression(false);
+ bump->getGLTexture()->setUseMipMaps(TRUE);
- {
- bump->setExplicitFormat(GL_RGBA8, GL_ALPHA);
- bump->createGLTexture(0, dst_image);
- }
+ auto* bump_ptr = bump.get();
+ auto* dst_ptr = dst_image.get();
- {
- gPipeline.mScreen.bindTarget();
-
- LLGLDepthTest depth(GL_FALSE);
- LLGLDisable cull(GL_CULL_FACE);
- LLGLDisable blend(GL_BLEND);
- gGL.setColorMask(TRUE, TRUE);
- gNormalMapGenProgram.bind();
+#if LL_BUMPLIST_MULTITHREADED
+ bump_ptr->ref();
+ dst_ptr->ref();
+#endif
- static LLStaticHashedString sNormScale("norm_scale");
- static LLStaticHashedString sStepX("stepX");
- static LLStaticHashedString sStepY("stepY");
+ bump_ptr->setExplicitFormat(GL_RGBA8, GL_ALPHA);
- gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
- gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getWidth());
- gNormalMapGenProgram.uniform1f(sStepY, 1.f/bump->getHeight());
+ auto create_texture = [=]()
+ {
+#if LL_IMAGEGL_THREAD_CHECK
+ bump_ptr->getGLTexture()->mActiveThread = LLThread::currentID();
+#endif
+ LL_PROFILE_ZONE_NAMED("bil - create texture deferred");
+ bump_ptr->createGLTexture(0, dst_ptr);
+ };
+
+ auto gen_normal_map = [=]()
+ {
+#if LL_IMAGEGL_THREAD_CHECK
+ bump_ptr->getGLTexture()->mActiveThread = LLThread::currentID();
+#endif
+ LL_PROFILE_ZONE_NAMED("bil - generate normal map");
+ if (gNormalMapGenProgram.mProgramObject == 0)
+ {
+#if LL_BUMPLIST_MULTITHREADED
+ bump_ptr->unref();
+ dst_ptr->unref();
+#endif
+ return;
+ }
+ gPipeline.mScreen.bindTarget();
- LLVector2 v((F32) bump->getWidth()/gPipeline.mScreen.getWidth(),
- (F32) bump->getHeight()/gPipeline.mScreen.getHeight());
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable cull(GL_CULL_FACE);
+ LLGLDisable blend(GL_BLEND);
+ gGL.setColorMask(TRUE, TRUE);
+ gNormalMapGenProgram.bind();
- gGL.getTexUnit(0)->bind(bump);
-
- S32 width = bump->getWidth();
- S32 height = bump->getHeight();
+ static LLStaticHashedString sNormScale("norm_scale");
+ static LLStaticHashedString sStepX("stepX");
+ static LLStaticHashedString sStepY("stepY");
- S32 screen_width = gPipeline.mScreen.getWidth();
- S32 screen_height = gPipeline.mScreen.getHeight();
+ gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
+ gNormalMapGenProgram.uniform1f(sStepX, 1.f / bump_ptr->getWidth());
+ gNormalMapGenProgram.uniform1f(sStepY, 1.f / bump_ptr->getHeight());
- glViewport(0, 0, screen_width, screen_height);
+ LLVector2 v((F32)bump_ptr->getWidth() / gPipeline.mScreen.getWidth(),
+ (F32)bump_ptr->getHeight() / gPipeline.mScreen.getHeight());
- for (S32 left = 0; left < width; left += screen_width)
- {
- S32 right = left + screen_width;
- right = llmin(right, width);
-
- F32 left_tc = (F32) left/ width;
- F32 right_tc = (F32) right/width;
+ gGL.getTexUnit(0)->bind(bump_ptr);
- for (S32 bottom = 0; bottom < height; bottom += screen_height)
- {
- S32 top = bottom+screen_height;
- top = llmin(top, height);
+ S32 width = bump_ptr->getWidth();
+ S32 height = bump_ptr->getHeight();
- F32 bottom_tc = (F32) bottom/height;
- F32 top_tc = (F32)(bottom+screen_height)/height;
- top_tc = llmin(top_tc, 1.f);
+ S32 screen_width = gPipeline.mScreen.getWidth();
+ S32 screen_height = gPipeline.mScreen.getHeight();
- F32 screen_right = (F32) (right-left)/screen_width;
- F32 screen_top = (F32) (top-bottom)/screen_height;
+ glViewport(0, 0, screen_width, screen_height);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(left_tc, bottom_tc);
- gGL.vertex2f(0, 0);
+ for (S32 left = 0; left < width; left += screen_width)
+ {
+ S32 right = left + screen_width;
+ right = llmin(right, width);
- gGL.texCoord2f(left_tc, top_tc);
- gGL.vertex2f(0, screen_top);
+ F32 left_tc = (F32)left / width;
+ F32 right_tc = (F32)right / width;
- gGL.texCoord2f(right_tc, bottom_tc);
- gGL.vertex2f(screen_right, 0);
+ for (S32 bottom = 0; bottom < height; bottom += screen_height)
+ {
+ S32 top = bottom + screen_height;
+ top = llmin(top, height);
- gGL.texCoord2f(right_tc, top_tc);
- gGL.vertex2f(screen_right, screen_top);
+ F32 bottom_tc = (F32)bottom / height;
+ F32 top_tc = (F32)(bottom + screen_height) / height;
+ top_tc = llmin(top_tc, 1.f);
- gGL.end();
+ F32 screen_right = (F32)(right - left) / screen_width;
+ F32 screen_top = (F32)(top - bottom) / screen_height;
- gGL.flush();
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(left_tc, bottom_tc);
+ gGL.vertex2f(0, 0);
- S32 w = right-left;
- S32 h = top-bottom;
+ gGL.texCoord2f(left_tc, top_tc);
+ gGL.vertex2f(0, screen_top);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, left, bottom, 0, 0, w, h);
- }
- }
+ gGL.texCoord2f(right_tc, bottom_tc);
+ gGL.vertex2f(screen_right, 0);
- glGenerateMipmap(GL_TEXTURE_2D);
+ gGL.texCoord2f(right_tc, top_tc);
+ gGL.vertex2f(screen_right, screen_top);
- gPipeline.mScreen.flush();
+ gGL.end();
- gNormalMapGenProgram.unbind();
-
- //generateNormalMapFromAlpha(dst_image, nrm_image);
- }
+ gGL.flush();
+
+ S32 w = right - left;
+ S32 h = top - bottom;
+
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, left, bottom, 0, 0, w, h);
+ }
+ }
+
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+ gPipeline.mScreen.flush();
+
+ gNormalMapGenProgram.unbind();
+
+ //generateNormalMapFromAlpha(dst_image, nrm_image);
+#if LL_BUMPLIST_MULTITHREADED
+ bump_ptr->unref();
+ dst_ptr->unref();
+#endif
+ };
+
+#if LL_BUMPLIST_MULTITHREADED
+ auto main_queue = sMainQueue.lock();
+
+ if (LLImageGLThread::sEnabled)
+ { //dispatch creation to background thread
+ main_queue->postTo(sTexUpdateQueue, create_texture, gen_normal_map);
+ }
+ else
+#endif
+ {
+ create_texture();
+ gen_normal_map();
+ }
}
iter->second = bump; // derefs (and deletes) old image