summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorcosmic-linden <111533034+cosmic-linden@users.noreply.github.com>2023-04-05 09:55:33 -0700
committerGitHub <noreply@github.com>2023-04-05 11:55:33 -0500
commitd6d634d29ff351450306e211982a98a0050f1b42 (patch)
tree3c4b5a6779669756277fffaab320074476e17543 /indra
parentb28971e4bf8cb41ea9eecead2b5676720355e30b (diff)
SL-19331: Move media updates off-thread on select hardware (#153)
* SL-19331: Have media updates on the LLImageGL thread even when texture updates are on the main thread. Add config. Off-thread media updates seem work best performance-wise when using glTexImage2D, not sub_image_lines. Otherwise, there are lots of main thread stalls. * SL-19331: Bump featuretable * SL-19331: Cleanup, annotate comment
Diffstat (limited to 'indra')
-rw-r--r--indra/llrender/llimagegl.cpp44
-rw-r--r--indra/llrender/llimagegl.h9
-rw-r--r--indra/newview/app_settings/settings.xml15
-rw-r--r--indra/newview/featuretable.txt8
-rw-r--r--indra/newview/featuretable_mac.txt5
-rw-r--r--indra/newview/lldrawpoolbump.cpp4
-rw-r--r--indra/newview/llstartup.cpp2
-rw-r--r--indra/newview/llviewermedia.cpp7
-rw-r--r--indra/newview/llviewertexture.cpp2
-rw-r--r--indra/newview/llviewertexturelist.cpp4
-rw-r--r--indra/newview/llviewerwindow.cpp4
11 files changed, 63 insertions, 41 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 5b0690bc79..3e3a3095e3 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -42,6 +42,8 @@
#include "llwindow.h"
#include "llframetimer.h"
+extern LL_COMMON_API bool on_main_thread();
+
#if !LL_IMAGEGL_THREAD_CHECK
#define checkActiveThread()
#endif
@@ -132,7 +134,8 @@ bool LLImageGL::sCompressTextures = false;
std::set<LLImageGL*> LLImageGL::sImageList;
-bool LLImageGLThread::sEnabled = false;
+bool LLImageGLThread::sEnabledTextures = false;
+bool LLImageGLThread::sEnabledMedia = false;
//****************************************************************************************************
//The below for texture auditing use only
@@ -242,14 +245,16 @@ BOOL is_little_endian()
}
//static
-void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha /* = false */, bool multi_threaded /* = false */)
+void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha /* = false */, bool thread_texture_loads /* = false */, bool thread_media_updates /* = false */)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
sSkipAnalyzeAlpha = skip_analyze_alpha;
- if (multi_threaded)
+ if (thread_texture_loads || thread_media_updates)
{
LLImageGLThread::createInstance(window);
+ LLImageGLThread::sEnabledTextures = thread_texture_loads;
+ LLImageGLThread::sEnabledMedia = thread_media_updates;
}
}
@@ -260,6 +265,7 @@ void LLImageGL::cleanupClass()
LLImageGLThread::deleteSingleton();
}
+
//static
S32 LLImageGL::dataFormatBits(S32 dataformat)
{
@@ -1125,9 +1131,20 @@ U32 type_width_from_pixtype(U32 pixtype)
return type_width;
}
+bool should_stagger_image_set(bool compressed)
+{
+#if LL_DARWIN
+ return false;
+#else
+ // glTexSubImage2D doesn't work with compressed textures on select tested Nvidia GPUs on Windows 10 -Cosmic,2023-03-08
+ // Setting media textures off-thread seems faster when not using sub_image_lines (Nvidia/Windows 10) -Cosmic,2023-03-31
+ return !compressed && on_main_thread();
+#endif
+}
+
// Equivalent to calling glSetSubImage2D(target, miplevel, x_offset, y_offset, width, height, pixformat, pixtype, src), assuming the total width of the image is data_width
// However, instead there are multiple calls to glSetSubImage2D on smaller slices of the image
-void subImageLines(U32 target, S32 miplevel, S32 x_offset, S32 y_offset, S32 width, S32 height, U32 pixformat, U32 pixtype, const U8* src, S32 data_width)
+void sub_image_lines(U32 target, S32 miplevel, S32 x_offset, S32 y_offset, S32 width, S32 height, U32 pixformat, U32 pixtype, const U8* src, S32 data_width)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
@@ -1223,11 +1240,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL;
stop_glerror();
-#if LL_DARWIN
- const bool use_sub_image = false;
-#else
- const bool use_sub_image = !isCompressed();
-#endif
+ const bool use_sub_image = should_stagger_image_set(isCompressed());
if (!use_sub_image)
{
// *TODO: Why does this work here, in setSubImage, but not in
@@ -1238,7 +1251,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
}
else
{
- subImageLines(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, sub_datap, data_width);
+ sub_image_lines(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, sub_datap, data_width);
}
gGL.getTexUnit(0)->disable();
stop_glerror();
@@ -1455,13 +1468,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
LL_PROFILE_ZONE_NUM(height);
free_cur_tex_image();
-#if LL_DARWIN
- const bool use_sub_image = false;
-#else
- // glTexSubImage2D doesn't work with compressed textures on select tested Nvidia GPUs on Windows 10 -Cosmic,2023-03-08
- // *TODO: Small chance that glCompressedTexImage2D/glCompressedTexSubImage2D may work better here
- const bool use_sub_image = !compress;
-#endif
+ const bool use_sub_image = should_stagger_image_set(compress);
if (!use_sub_image)
{
LL_PROFILE_ZONE_NAMED("glTexImage2D alloc + copy");
@@ -1479,7 +1486,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (src)
{
LL_PROFILE_ZONE_NAMED("glTexImage2D copy");
- subImageLines(target, miplevel, 0, 0, width, height, pixformat, pixtype, src, width);
+ sub_image_lines(target, miplevel, 0, 0, width, height, pixformat, pixtype, src, width);
}
}
alloc_tex_image(width, height, pixformat);
@@ -2504,7 +2511,6 @@ LLImageGLThread::LLImageGLThread(LLWindow* window)
, mWindow(window)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- sEnabled = true;
mFinished = false;
mContext = mWindow->createSharedContext();
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 42f6efef77..87fb9e363e 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -287,7 +287,7 @@ public:
#endif
public:
- static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false, bool multi_threaded = false);
+ static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false, bool thread_texture_loads = false, bool thread_media_updates = false);
static void cleanupClass() ;
private:
@@ -329,8 +329,10 @@ public:
class LLImageGLThread : public LLSimpleton<LLImageGLThread>, LL::ThreadPool
{
public:
- // follows gSavedSettings "RenderGLMultiThreaded"
- static bool sEnabled;
+ // follows gSavedSettings "RenderGLMultiThreadedTextures"
+ static bool sEnabledTextures;
+ // follows gSavedSettings "RenderGLMultiThreadedMedia"
+ static bool sEnabledMedia;
LLImageGLThread(LLWindow* window);
@@ -349,5 +351,4 @@ private:
LLAtomicBool mFinished;
};
-
#endif // LL_LLIMAGEGL_H
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4490e3eec2..9ae33a85b4 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9909,10 +9909,21 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderGLMultiThreaded</key>
+ <key>RenderGLMultiThreadedTextures</key>
<map>
<key>Comment</key>
- <string>Allow OpenGL to use multiple render contexts (reduces frame stutters from loading textures, doesn't play nice with Intel drivers).</string>
+ <string>Allow OpenGL to use multiple render contexts for loading textures (may reduce frame stutters, doesn't play nice with Intel drivers).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderGLMultiThreadedMedia</key>
+ <map>
+ <key>Comment</key>
+ <string>Allow OpenGL to use multiple render contexts for playing media (may reduce frame stutters, doesn't play nice with Intel drivers)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 3d634c7484..99007d52c2 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 53
+version 54
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -70,7 +70,8 @@ RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
RenderGLContextCoreProfile 1 1
-RenderGLMultiThreaded 1 0
+RenderGLMultiThreadedTextures 1 0
+RenderGLMultiThreadedMedia 1 1
RenderReflectionProbeResolution 1 128
RenderScreenSpaceReflections 1 1
@@ -311,9 +312,10 @@ list Intel
RenderAnisotropic 1 0
RenderFSAASamples 1 0
RenderGLContextCoreProfile 1 0
+RenderGLMultiThreadedMedia 1 0
list AMD
-RenderGLMultiThreaded 1 1
+RenderGLMultiThreadedTextures 1 1
list GL3
RenderFSAASamples 0 0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index eed790ddac..24023901d9 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 48
+version 49
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -67,7 +67,8 @@ RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
RenderGLContextCoreProfile 1 1
-RenderGLMultiThreaded 1 0
+RenderGLMultiThreadedTextures 1 0
+RenderGLMultiThreadedMedia 1 0
RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 2
RenderScreenSpaceReflections 1 1
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 763943f9cc..45c74776e1 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -1042,7 +1042,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
#if LL_BUMPLIST_MULTITHREADED
- auto tex_queue = LLImageGLThread::sEnabled ? sTexUpdateQueue.lock() : nullptr;
+ auto tex_queue = LLImageGLThread::sEnabledTextures ? sTexUpdateQueue.lock() : nullptr;
if (tex_queue)
{ //dispatch creation to background thread
@@ -1154,7 +1154,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
};
#if LL_BUMPLIST_MULTITHREADED
- auto main_queue = LLImageGLThread::sEnabled ? sMainQueue.lock() : nullptr;
+ auto main_queue = LLImageGLThread::sEnabledTextures ? sMainQueue.lock() : nullptr;
if (main_queue)
{ //dispatch texture upload to background thread, issue GPU commands to generate normal map on main thread
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 0dc4746123..6bcee31b72 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -312,7 +312,7 @@ void update_texture_fetch()
LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
gTextureList.updateImages(0.10f);
- if (LLImageGLThread::sEnabled)
+ if (LLImageGLThread::sEnabledTextures)
{
std::shared_ptr<LL::WorkQueue> main_queue = LL::WorkQueue::getInstance("mainloop");
main_queue->runFor(std::chrono::milliseconds(1));
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index aae3bd7f25..c8e279c991 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -2878,7 +2878,7 @@ void LLViewerMediaImpl::update()
if (preMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height))
{
// Push update to worker thread
- auto main_queue = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr;
+ auto main_queue = LLImageGLThread::sEnabledMedia ? mMainQueue.lock() : nullptr;
if (main_queue)
{
mTextureUpdatePending = true;
@@ -2967,11 +2967,12 @@ void LLViewerMediaImpl::doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* da
// wrap "data" in an LLImageRaw but do NOT make a copy
LLPointer<LLImageRaw> raw = new LLImageRaw(data, media_tex->getWidth(), media_tex->getHeight(), media_tex->getComponents(), true);
-
+
// *NOTE: Recreating the GL texture each media update may seem wasteful
// (note the texture creation in preMediaTexUpdate), however, it apparently
// prevents GL calls from blocking, due to poor bookkeeping of state of
- // updated textures by the OpenGL implementation.
+ // updated textures by the OpenGL implementation. (Windows 10/Nvidia)
+ // -Cosmic,2023-04-04
// Allocate GL texture based on LLImageRaw but do NOT copy to GL
LLGLuint tex_name = 0;
media_tex->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER, true, &tex_name);
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index ca8cdbaea9..29c8700105 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1578,7 +1578,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
}
#endif
mNeedsCreateTexture = true;
- auto mainq = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr;
+ auto mainq = LLImageGLThread::sEnabledTextures ? mMainQueue.lock() : nullptr;
if (mainq)
{
ref();
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 09a1cd5148..1449844588 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1230,7 +1230,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
LLViewerFetchedTexture* imagep = *iter++;
imagep->updateFetch();
}
- std::shared_ptr<LL::WorkQueue> main_queue = LLImageGLThread::sEnabled ? LL::WorkQueue::getInstance("mainloop") : NULL;
+ std::shared_ptr<LL::WorkQueue> main_queue = LLImageGLThread::sEnabledTextures ? LL::WorkQueue::getInstance("mainloop") : NULL;
// Run threads
S32 fetch_pending = 0;
while (1)
@@ -1239,7 +1239,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
LLAppViewer::instance()->getImageDecodeThread()->update(1); // unpauses the image thread
fetch_pending = LLAppViewer::instance()->getTextureFetch()->update(1); // unpauses the texture fetch thread
- if (LLImageGLThread::sEnabled)
+ if (LLImageGLThread::sEnabledTextures)
{
main_queue->runFor(std::chrono::milliseconds(1));
fetch_pending += main_queue->size();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ad9e3da379..3fee3766a9 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1975,8 +1975,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
}
// Init the image list. Must happen after GL is initialized and before the images that
- // LLViewerWindow needs are requested.
- LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY, false, gSavedSettings.getBOOL("RenderGLMultiThreaded"));
+ // LLViewerWindow needs are requested, as well as before LLViewerMedia starts updating images.
+ LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY, false, gSavedSettings.getBOOL("RenderGLMultiThreadedTextures"), gSavedSettings.getBOOL("RenderGLMultiThreadedMedia"));
gTextureList.init();
LLViewerTextureManager::init() ;
gBumpImageList.init();