summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorDave Houlton <euclid@lindenlab.com>2022-01-27 12:57:30 -0700
committerDave Houlton <euclid@lindenlab.com>2022-01-27 17:09:29 -0700
commit8d0efb54db96c87a2adb4a824998870ff397846e (patch)
tree929ccf5fb9d7ce49c3ddd18e179f878cadab4cc5 /indra/llrender
parent7dcca7f180c2204daefbc3648ebe766a46c7cf85 (diff)
SL-16418 rename media tex image per-update to avoid contention stall
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llimagegl.cpp66
-rw-r--r--indra/llrender/llimagegl.h10
2 files changed, 61 insertions, 15 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 1e9b9f642e..4b4f071171 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1215,9 +1215,8 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE)
{ //GL_ALPHA is deprecated, convert to RGBA
use_scratch = true;
- scratch = new U32[width * height];
-
U32 pixel_count = (U32)(width * height);
+ scratch = new U32[pixel_count];
for (U32 i = 0; i < pixel_count; i++)
{
U8* pix = (U8*)&scratch[i];
@@ -1232,9 +1231,8 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE)
{ //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA
use_scratch = true;
- scratch = new U32[width * height];
-
U32 pixel_count = (U32)(width * height);
+ scratch = new U32[pixel_count];
for (U32 i = 0; i < pixel_count; i++)
{
U8 lum = ((U8*)pixels)[i * 2 + 0];
@@ -1252,9 +1250,8 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE)
{ //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
use_scratch = true;
- scratch = new U32[width * height];
-
U32 pixel_count = (U32)(width * height);
+ scratch = new U32[pixel_count];
for (U32 i = 0; i < pixel_count; i++)
{
U8 lum = ((U8*)pixels)[i];
@@ -1314,10 +1311,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
}
stop_glerror();
- if (use_scratch)
- {
- delete[] scratch;
- }
+ if (scratch) delete[] scratch;
}
//create an empty GL texture: just create a texture name
@@ -1471,7 +1465,49 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
return createGLTexture(discard_level, rawdata, FALSE, usename);
}
-BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
+// Create a new GL name and allocate tex storage (unitialized) for it
+// Used to break resource contention stall in background media tex updates
+void LLImageGL::allocNewTexName()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ if (on_main_thread()) return; // Should only be called on bg update thread
+ if (!mGLTextureCreated) return;
+ if (0 != mNewTexName) return; // only 1 rename in flight at a time
+
+ generateTextures(1, &mNewTexName); // create new GL name
+
+ mHasMipMaps = false; // Media textures aren't mipped
+ mMipLevels = 0;
+ // Set state to match current
+ gGL.getTexUnit(0)->bind(this, false, false, mNewTexName);
+ glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel);
+ glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WIDTH, mWidth);
+ glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_HEIGHT, mHeight);
+ gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
+ gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
+ gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
+
+ setManualImage(mTarget, 0, mFormatInternal, mWidth, mHeight, mFormatPrimary, mFormatType,
+ (GLvoid *) nullptr, mAllowCompression);
+
+ gGL.getTexUnit(0)->unbind(mBindTarget);
+
+ mLastBindTime = sLastFrameTime;
+}
+
+// Delete no-longer-needed GL tex name (on main thread)
+void LLImageGL::swapTexName()
+{
+ if (mNewTexName)
+ {
+ deleteTextures(1, &mTexName);
+ mTexName = mNewTexName;
+ mNewTexName = 0;
+ }
+}
+
+BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips /* = FALSE */, S32 usename /* = 0 */)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
checkActiveThread();
@@ -1715,6 +1751,14 @@ void LLImageGL::destroyGLTexture()
mTexName = 0;
mGLTextureCreated = FALSE ;
}
+
+ // clean up any in-flight name change
+ if (0 != mNewTexName)
+ {
+ // Memory is transient, not tracked by sGlobalTextuerMemory
+ LLImageGL::deleteTextures(1, &mNewTexName);
+ mNewTexName = 0;
+ }
}
//force to invalidate the gl texture, most likely a sculpty texture
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index d6f4b13a51..f311170823 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -109,15 +109,17 @@ public:
static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
BOOL createGLTexture() ;
- BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
- S32 category = sMaxCategories-1);
+ BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = sMaxCategories-1);
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
- void setImage(const LLImageRaw* imageraw);
+ void setImage(const LLImageRaw* imageraw);
BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0);
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
-
+
+ void allocNewTexName();
+ void swapTexName();
+
// Read back a raw image for this discard level, if it exists
BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
void destroyGLTexture();