summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2021-10-11 16:03:40 +0000
committerDave Parks <davep@lindenlab.com>2021-10-11 16:03:40 +0000
commitd00272e0cc9974f35a46f0c313ee2c0e11cddbda (patch)
tree48e1e3cc9c89107c28e58b69a35e25802c84014c
parent2238f89db70a754614b01bb85adc5f16a63e7eb4 (diff)
SL-16099 Multi-threaded OpenGL usage on Windows, enable Core Profile and VAOs by default.
-rw-r--r--indra/llcommon/llthreadsafequeue.h3
-rw-r--r--indra/llimage/llimageworker.cpp4
-rw-r--r--indra/llrender/llcubemap.cpp2
-rw-r--r--indra/llrender/llfontfreetype.cpp1
-rw-r--r--indra/llrender/llglslshader.cpp2
-rw-r--r--indra/llrender/llgltexture.cpp2
-rw-r--r--indra/llrender/llimagegl.cpp330
-rw-r--r--indra/llrender/llimagegl.h35
-rw-r--r--indra/llrender/llrender.cpp2
-rw-r--r--indra/llrender/llrender.h2
-rw-r--r--indra/llwindow/llopenglview-objc.mm3
-rw-r--r--indra/llwindow/llwindow.h12
-rw-r--r--indra/llwindow/llwindowheadless.h3
-rw-r--r--indra/llwindow/llwindowmacosx.cpp28
-rw-r--r--indra/llwindow/llwindowmacosx.h144
-rw-r--r--indra/llwindow/llwindowwin32.cpp129
-rw-r--r--indra/llwindow/llwindowwin32.h3
-rw-r--r--indra/newview/app_settings/settings.xml4
-rw-r--r--indra/newview/llappviewer.cpp3
-rw-r--r--indra/newview/llnetmap.cpp1
-rw-r--r--indra/newview/lltexturefetch.cpp4
-rw-r--r--indra/newview/llviewertexture.cpp311
-rw-r--r--indra/newview/llviewertexture.h8
-rw-r--r--indra/newview/llviewertexturelist.cpp36
-rw-r--r--indra/newview/llviewerwindow.cpp2
25 files changed, 718 insertions, 356 deletions
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 719edcd579..06e8d8f609 100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -154,6 +154,9 @@ public:
// Returns the size of the queue.
size_t size();
+ //Returns the capacity of the queue.
+ U32 capacity() { return mCapacity; }
+
// closes the queue:
// - every subsequent push() call will throw LLThreadSafeQueueInterrupt
// - every subsequent tryPush() call will return false
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 5f42fba866..33f8dce6ee 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -48,6 +48,7 @@ LLImageDecodeThread::~LLImageDecodeThread()
// virtual
S32 LLImageDecodeThread::update(F32 max_time_ms)
{
+ LL_PROFILE_ZONE_SCOPED;
LLMutexLock lock(mCreationMutex);
for (creation_list_t::iterator iter = mCreationList.begin();
iter != mCreationList.end(); ++iter)
@@ -71,6 +72,7 @@ S32 LLImageDecodeThread::update(F32 max_time_ms)
LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
{
+ LL_PROFILE_ZONE_SCOPED;
LLMutexLock lock(mCreationMutex);
handle_t handle = generateHandle();
mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
@@ -118,6 +120,7 @@ LLImageDecodeThread::ImageRequest::~ImageRequest()
// Returns true when done, whether or not decode was successful.
bool LLImageDecodeThread::ImageRequest::processRequest()
{
+ LL_PROFILE_ZONE_SCOPED;
const F32 decode_time_slice = .1f;
bool done = true;
if (!mDecodedRaw && mFormattedImage.notNull())
@@ -164,6 +167,7 @@ bool LLImageDecodeThread::ImageRequest::processRequest()
void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
{
+ LL_PROFILE_ZONE_SCOPED;
if (mResponder.notNull())
{
bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 5947bca670..d7f7b2f58e 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -150,6 +150,7 @@ void LLCubeMap::initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages
void LLCubeMap::initGLData()
{
+ LL_PROFILE_ZONE_SCOPED;
for (int i = 0; i < 6; i++)
{
mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION);
@@ -453,6 +454,7 @@ BOOL LLCubeMap::project(F32& v_min, F32& v_max, F32& h_min, F32& h_max,
void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col)
{
+ LL_PROFILE_ZONE_SCOPED;
F32 v_min, v_max, h_min, h_max;
LLVector3 center = dir[0] + dir[1] + dir[2] + dir[3];
center.normVec();
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index c41730ebaa..e18161e53c 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -460,6 +460,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch) const
LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const
{
+ LL_PROFILE_ZONE_SCOPED;
if (mFTFace == NULL)
return NULL;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 2fb3b8257d..394fcd2b2f 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -208,6 +208,7 @@ void LLGLSLShader::dumpStats()
//static
void LLGLSLShader::startProfile()
{
+ LL_PROFILE_ZONE_SCOPED;
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->placeProfileQuery();
@@ -218,6 +219,7 @@ void LLGLSLShader::startProfile()
//static
void LLGLSLShader::stopProfile(U32 count, U32 mode)
{
+ LL_PROFILE_ZONE_SCOPED;
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->readProfileQuery(count, mode);
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index ad501687ed..a279e85bae 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -262,6 +262,7 @@ LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(mGLTexturep.notNull()) ;
return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
@@ -269,6 +270,7 @@ BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos,
BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(mGLTexturep.notNull()) ;
return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 276fa55e15..aff29bd857 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -39,6 +39,7 @@
#include "llgl.h"
#include "llglslshader.h"
#include "llrender.h"
+#include "llwindow.h"
//----------------------------------------------------------------------------
const F32 MIN_TEXTURE_LIFETIME = 10.f;
@@ -170,15 +171,32 @@ BOOL is_little_endian()
return (*c == 0x78) ;
}
+
+LLImageGLThread* LLImageGLThread::sInstance = nullptr;
+
//static
-void LLImageGL::initClass(S32 num_catagories, BOOL skip_analyze_alpha /* = false */)
+void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha /* = false */)
{
+ LL_PROFILE_ZONE_SCOPED;
sSkipAnalyzeAlpha = skip_analyze_alpha;
+ LLImageGLThread::sInstance = new LLImageGLThread(window);
+ LLImageGLThread::sInstance->start();
+}
+
+//static
+void LLImageGL::updateClass()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ LLImageGLThread::sInstance->executeCallbacks();
}
//static
void LLImageGL::cleanupClass()
-{
+{
+ LL_PROFILE_ZONE_SCOPED;
+ LLImageGLThread::sInstance->mFunctionQueue.close();
+ delete LLImageGLThread::sInstance;
+ LLImageGLThread::sInstance = nullptr;
}
//static
@@ -656,6 +674,7 @@ void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_for
void LLImageGL::setImage(const LLImageRaw* imageraw)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert((imageraw->getWidth() == getWidth(mCurrentDiscardLevel)) &&
(imageraw->getHeight() == getHeight(mCurrentDiscardLevel)) &&
(imageraw->getComponents() == getComponents()));
@@ -699,9 +718,8 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
llverify(gGL.getTexUnit(0)->bind(this));
-
-
- if (mUseMipMaps)
+
+ if (mUseMipMaps)
{
if (data_hasmips)
{
@@ -781,7 +799,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
}
- LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
+ LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
data_in, mAllowCompression);
@@ -878,7 +896,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
stop_glerror();
}
- LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
+ LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
if (m == 0)
{
analyzeAlpha(data_in, w, h);
@@ -1067,6 +1085,7 @@ void LLImageGL::postAddToAtlas()
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!width || !height)
{
return TRUE;
@@ -1163,6 +1182,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
{
+ LL_PROFILE_ZONE_SCOPED;
return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update);
}
@@ -1201,119 +1221,119 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
// static
static LLTrace::BlockTimerStatHandle FTM_SET_MANUAL_IMAGE("setManualImage");
-void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
+void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void* pixels, bool allow_compression)
{
- LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE);
- bool use_scratch = false;
- U32* scratch = NULL;
- if (LLRender::sGLCoreProfile)
- {
- if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE)
- { //GL_ALPHA is deprecated, convert to RGBA
- use_scratch = true;
- scratch = new U32[width*height];
+ LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE);
+ bool use_scratch = false;
+ U32* scratch = NULL;
+ if (LLRender::sGLCoreProfile)
+ {
+ 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);
- for (U32 i = 0; i < pixel_count; i++)
- {
- U8* pix = (U8*) &scratch[i];
- pix[0] = pix[1] = pix[2] = 0;
- pix[3] = ((U8*) pixels)[i];
- }
-
- pixformat = GL_RGBA;
- intformat = GL_RGBA8;
- }
+ U32 pixel_count = (U32)(width * height);
+ for (U32 i = 0; i < pixel_count; i++)
+ {
+ U8* pix = (U8*)&scratch[i];
+ pix[0] = pix[1] = pix[2] = 0;
+ pix[3] = ((U8*)pixels)[i];
+ }
- 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];
+ pixformat = GL_RGBA;
+ intformat = GL_RGBA8;
+ }
- U32 pixel_count = (U32) (width*height);
- for (U32 i = 0; i < pixel_count; i++)
- {
- U8 lum = ((U8*) pixels)[i*2+0];
- U8 alpha = ((U8*) pixels)[i*2+1];
+ 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];
- U8* pix = (U8*) &scratch[i];
- pix[0] = pix[1] = pix[2] = lum;
- pix[3] = alpha;
- }
-
- pixformat = GL_RGBA;
- intformat = GL_RGBA8;
- }
+ U32 pixel_count = (U32)(width * height);
+ for (U32 i = 0; i < pixel_count; i++)
+ {
+ U8 lum = ((U8*)pixels)[i * 2 + 0];
+ U8 alpha = ((U8*)pixels)[i * 2 + 1];
- if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE)
- { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
- use_scratch = true;
- scratch = new U32[width*height];
+ U8* pix = (U8*)&scratch[i];
+ pix[0] = pix[1] = pix[2] = lum;
+ pix[3] = alpha;
+ }
- U32 pixel_count = (U32) (width*height);
- for (U32 i = 0; i < pixel_count; i++)
- {
- U8 lum = ((U8*) pixels)[i];
-
- U8* pix = (U8*) &scratch[i];
- pix[0] = pix[1] = pix[2] = lum;
- pix[3] = 255;
- }
-
- pixformat = GL_RGBA;
- intformat = GL_RGB8;
- }
- }
+ pixformat = GL_RGBA;
+ intformat = GL_RGBA8;
+ }
- if (LLImageGL::sCompressTextures && allow_compression)
- {
- switch (intformat)
- {
- case GL_RGB:
- case GL_RGB8:
- intformat = GL_COMPRESSED_RGB;
- break;
- case GL_SRGB:
- case GL_SRGB8:
- intformat = GL_COMPRESSED_SRGB;
- break;
- case GL_RGBA:
- case GL_RGBA8:
- intformat = GL_COMPRESSED_RGBA;
- break;
- case GL_SRGB_ALPHA:
- case GL_SRGB8_ALPHA8:
- intformat = GL_COMPRESSED_SRGB_ALPHA;
- break;
- case GL_LUMINANCE:
- case GL_LUMINANCE8:
- intformat = GL_COMPRESSED_LUMINANCE;
- break;
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE8_ALPHA8:
- intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
- break;
- case GL_ALPHA:
- case GL_ALPHA8:
- intformat = GL_COMPRESSED_ALPHA;
- break;
- default:
- LL_WARNS() << "Could not compress format: " << std::hex << intformat << LL_ENDL;
- break;
- }
- }
+ if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE)
+ { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
+ use_scratch = true;
+ scratch = new U32[width * height];
- stop_glerror();
- {
- LL_PROFILE_ZONE_NAMED("glTexImage2D");
- glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
- }
- stop_glerror();
+ U32 pixel_count = (U32)(width * height);
+ for (U32 i = 0; i < pixel_count; i++)
+ {
+ U8 lum = ((U8*)pixels)[i];
- if (use_scratch)
- {
- delete [] scratch;
- }
+ U8* pix = (U8*)&scratch[i];
+ pix[0] = pix[1] = pix[2] = lum;
+ pix[3] = 255;
+ }
+
+ pixformat = GL_RGBA;
+ intformat = GL_RGB8;
+ }
+ }
+
+ if (LLImageGL::sCompressTextures && allow_compression)
+ {
+ switch (intformat)
+ {
+ case GL_RGB:
+ case GL_RGB8:
+ intformat = GL_COMPRESSED_RGB;
+ break;
+ case GL_SRGB:
+ case GL_SRGB8:
+ intformat = GL_COMPRESSED_SRGB;
+ break;
+ case GL_RGBA:
+ case GL_RGBA8:
+ intformat = GL_COMPRESSED_RGBA;
+ break;
+ case GL_SRGB_ALPHA:
+ case GL_SRGB8_ALPHA8:
+ intformat = GL_COMPRESSED_SRGB_ALPHA;
+ break;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE8:
+ intformat = GL_COMPRESSED_LUMINANCE;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE8_ALPHA8:
+ intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
+ break;
+ case GL_ALPHA:
+ case GL_ALPHA8:
+ intformat = GL_COMPRESSED_ALPHA;
+ break;
+ default:
+ LL_WARNS() << "Could not compress format: " << std::hex << intformat << LL_ENDL;
+ break;
+ }
+ }
+
+ stop_glerror();
+ {
+ LL_PROFILE_ZONE_NAMED("glTexImage2D");
+ glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
+ }
+ stop_glerror();
+
+ if (use_scratch)
+ {
+ delete[] scratch;
+ }
}
//create an empty GL texture: just create a texture name
@@ -1336,6 +1356,7 @@ BOOL LLImageGL::createGLTexture()
if(mTexName)
{
LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+ mTexName = 0;
}
@@ -1697,7 +1718,7 @@ void LLImageGL::destroyGLTexture()
mTextureMemory = (S32Bytes)0;
}
- LLImageGL::deleteTextures(1, &mTexName);
+ LLImageGL::deleteTextures(1, &mTexName);
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mTexName = 0;
mGLTextureCreated = FALSE ;
@@ -2238,3 +2259,90 @@ void LLImageGL::resetCurTexSizebar()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips);
*/
+
+LLImageGLThread::LLImageGLThread(LLWindow* window)
+ : LLThread("LLImageGL"), mWindow(window)
+{
+ mFinished = false;
+
+ mContext = mWindow->createSharedContext();
+}
+
+// post a function to be executed on the LLImageGL background thread
+
+bool LLImageGLThread::post(const std::function<void()>& func)
+{
+ try
+ {
+ if (mFunctionQueue.size() < mFunctionQueue.capacity())
+ {
+ //NOTE: tryPushFront will return immediately if the lock is held
+ // desired behavior here is to push and return true unless the
+ // queue is full or closed
+ mFunctionQueue.pushFront(func);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ catch (LLThreadSafeQueueInterrupt e)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//post a callback to be executed on the main thread
+
+bool LLImageGLThread::postCallback(const std::function<void()>& callback)
+{
+ try
+ {
+ mCallbackQueue.pushFront(callback);
+ }
+ catch (LLThreadSafeQueueInterrupt e)
+ {
+ //thread is closing, drop request
+ return false;
+ }
+
+ return true;
+}
+
+void LLImageGLThread::executeCallbacks()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ //executed from main thread
+ std::function<void()> callback;
+ while (mCallbackQueue.tryPopBack(callback))
+ {
+ LL_PROFILE_ZONE_NAMED("iglt - callback");
+ callback();
+ }
+}
+
+void LLImageGLThread::run()
+{
+ mWindow->makeContextCurrent(mContext);
+ gGL.init();
+ try
+ {
+ while (true)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ std::function<void()> curFunc = mFunctionQueue.popBack();
+ {
+ LL_PROFILE_ZONE_NAMED("iglt - function")
+ curFunc();
+ }
+ }
+ }
+ catch (LLThreadSafeQueueInterrupt e)
+ {
+ //queue is closed, fall out of run loop
+ }
+ gGL.shutdown();
+ mWindow->destroySharedContext(mContext);
+}
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 61ddc8d59b..8e9b483c2d 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -35,9 +35,11 @@
#include "llrefcount.h"
#include "v2math.h"
#include "llunits.h"
-
+#include "llthreadsafequeue.h"
#include "llrender.h"
class LLTextureAtlas ;
+class LLWindow;
+
#define BYTES_TO_MEGA_BYTES(x) ((x) >> 20)
#define MEGA_BYTES_TO_BYTES(x) ((x) << 20)
@@ -102,7 +104,7 @@ public:
void setAllowCompression(bool allow) { mAllowCompression = allow; }
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);
@@ -265,7 +267,8 @@ public:
#endif
public:
- static void initClass(S32 num_catagories, BOOL skip_analyze_alpha = false);
+ static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false);
+ static void updateClass();
static void cleanupClass() ;
private:
@@ -301,4 +304,30 @@ public:
};
+class LLImageGLThread : public LLThread
+{
+public:
+ LLImageGLThread(LLWindow* window);
+
+ // post a function to be executed on the LLImageGL background thread
+ bool post(const std::function<void()>& func);
+
+ //post a callback to be executed on the main thread
+ bool postCallback(const std::function<void()>& callback);
+
+ void executeCallbacks();
+
+ void run() override;
+
+ LLThreadSafeQueue<std::function<void()>> mFunctionQueue;
+ LLThreadSafeQueue<std::function<void()>> mCallbackQueue;
+
+ LLWindow* mWindow;
+ void* mContext;
+ LLAtomicBool mFinished;
+
+ static LLImageGLThread* sInstance;
+};
+
+
#endif // LL_LLIMAGEGL_H
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 43b4441ea8..b6711e44e3 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -36,7 +36,7 @@
#include "lltexture.h"
#include "llshadermgr.h"
-LLRender gGL;
+thread_local LLRender gGL;
// Handy copies of last good GL matrices
F32 gGLModelView[16];
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index af8568f8a3..c08c2d6881 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -511,7 +511,7 @@ extern F32 gGLLastProjection[16];
extern F32 gGLProjection[16];
extern S32 gGLViewport[4];
-extern LLRender gGL;
+extern thread_local LLRender gGL;
// This rotation matrix moves the default OpenGL reference frame
// (-Z at, Y up) to Cory's favorite reference frame (X at, Z up)
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index d2c5b11c3d..b647085b7e 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -288,7 +288,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
if (vsync)
{
- [glContext setValues:(const GLint*)1 forParameter:NSOpenGLCPSwapInterval];
+ GLint value = 1;
+ [glContext setValues:&value forParameter:NSOpenGLCPSwapInterval];
} else {
// supress this error after move to Xcode 7:
// error: null passed to a callee that requires a non-null argument [-Werror,-Wnonnull]
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index d4d5b76937..10c0b6a424 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -78,7 +78,17 @@ public:
BOOL setSize(LLCoordWindow size);
virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true);
virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) = 0;
- virtual BOOL setCursorPosition(LLCoordWindow position) = 0;
+
+ //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread
+ // returns a pointer to be handed back to destroySharedConext/makeContextCurrent
+ virtual void* createSharedContext() = 0;
+ //make the given context current on the current thread
+ virtual void makeContextCurrent(void* context) = 0;
+ //destroy the given context that was retrieved by createSharedContext()
+ //Must be called on the same thread that called createSharedContext()
+ virtual void destroySharedContext(void* context) = 0;
+
+ virtual BOOL setCursorPosition(LLCoordWindow position) = 0;
virtual BOOL getCursorPosition(LLCoordWindow *position) = 0;
virtual void showCursor() = 0;
virtual void hideCursor() = 0;
diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h
index c692666df1..a7ae28aa24 100644
--- a/indra/llwindow/llwindowheadless.h
+++ b/indra/llwindow/llwindowheadless.h
@@ -49,6 +49,9 @@ public:
/*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;};
/*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;};
/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;};
+ void* createSharedContext() { return nullptr; }
+ void makeContextCurrent(void*) {}
+ void destroySharedContext(void*) {}
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;};
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;};
/*virtual*/ void showCursor() {};
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 0d0607a0bb..23830dd24e 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1907,6 +1907,34 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
allowDirectMarkedTextInput(b, mGLView); // mLanguageTextInputAllowed and mMarkedTextAllowed should be updated at once (by Pell Smit
}
+class sharedContext
+{
+public:
+ CGLContextObj mContext;
+};
+
+void* LLWindowMacOSX::createSharedContext()
+{
+ sharedContext* sc = new sharedContext();
+ CGLCreateContext(mPixelFormat, mContext, &(sc->mContext));
+
+ return (void *)sc;
+}
+
+void LLWindowMacOSX::makeContextCurrent(void* context)
+{
+ CGLSetCurrentContext(((sharedContext*)context)->mContext);
+}
+
+void LLWindowMacOSX::destroySharedContext(void* context)
+{
+ sharedContext* sc = (sharedContext*)context;
+
+ CGLDestroyContext(sc->mContext);
+
+ delete sc;
+}
+
void LLWindowMacOSX::interruptLanguageTextInput()
{
commitCurrentPreedit(mGLView);
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index bf45238c8d..ede2b453d5 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -41,85 +41,84 @@
#undef verify
#undef require
-
class LLWindowMacOSX : public LLWindow
{
public:
- /*virtual*/ void show();
- /*virtual*/ void hide();
- /*virtual*/ void close();
- /*virtual*/ BOOL getVisible();
- /*virtual*/ BOOL getMinimized();
- /*virtual*/ BOOL getMaximized();
- /*virtual*/ BOOL maximize();
- /*virtual*/ void minimize();
- /*virtual*/ void restore();
- /*virtual*/ BOOL getFullscreen();
- /*virtual*/ BOOL getPosition(LLCoordScreen *position);
- /*virtual*/ BOOL getSize(LLCoordScreen *size);
- /*virtual*/ BOOL getSize(LLCoordWindow *size);
- /*virtual*/ BOOL setPosition(LLCoordScreen position);
- /*virtual*/ BOOL setSizeImpl(LLCoordScreen size);
- /*virtual*/ BOOL setSizeImpl(LLCoordWindow size);
- /*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL);
- /*virtual*/ BOOL setCursorPosition(LLCoordWindow position);
- /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position);
- /*virtual*/ void showCursor();
- /*virtual*/ void hideCursor();
- /*virtual*/ void showCursorFromMouseMove();
- /*virtual*/ void hideCursorUntilMouseMove();
- /*virtual*/ BOOL isCursorHidden();
- /*virtual*/ void updateCursor();
- /*virtual*/ ECursorType getCursor() const;
- /*virtual*/ void captureMouse();
- /*virtual*/ void releaseMouse();
- /*virtual*/ void setMouseClipping( BOOL b );
- /*virtual*/ BOOL isClipboardTextAvailable();
- /*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst);
- /*virtual*/ BOOL copyTextToClipboard(const LLWString & src);
- /*virtual*/ void flashIcon(F32 seconds);
- /*virtual*/ F32 getGamma();
- /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma
- /*virtual*/ U32 getFSAASamples();
- /*virtual*/ void setFSAASamples(const U32 fsaa_samples);
- /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma)
- /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; }
- /*virtual*/ void gatherInput();
- /*virtual*/ void delayInputProcessing() {};
- /*virtual*/ void swapBuffers();
+ void show() override;
+ void hide() override;
+ void close() override;
+ BOOL getVisible() override;
+ BOOL getMinimized() override;
+ BOOL getMaximized() override;
+ BOOL maximize() override;
+ void minimize() override;
+ void restore() override;
+ BOOL getFullscreen();
+ BOOL getPosition(LLCoordScreen *position) override;
+ BOOL getSize(LLCoordScreen *size) override;
+ BOOL getSize(LLCoordWindow *size) override;
+ BOOL setPosition(LLCoordScreen position) override;
+ BOOL setSizeImpl(LLCoordScreen size) override;
+ BOOL setSizeImpl(LLCoordWindow size) override;
+ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) override;
+ BOOL setCursorPosition(LLCoordWindow position) override;
+ BOOL getCursorPosition(LLCoordWindow *position) override;
+ void showCursor() override;
+ void hideCursor() override;
+ void showCursorFromMouseMove() override;
+ void hideCursorUntilMouseMove() override;
+ BOOL isCursorHidden() override;
+ void updateCursor() override;
+ ECursorType getCursor() const override;
+ void captureMouse() override;
+ void releaseMouse() override;
+ void setMouseClipping( BOOL b ) override;
+ BOOL isClipboardTextAvailable() override;
+ BOOL pasteTextFromClipboard(LLWString &dst) override;
+ BOOL copyTextToClipboard(const LLWString & src) override;
+ void flashIcon(F32 seconds) override;
+ F32 getGamma() override;
+ BOOL setGamma(const F32 gamma) override; // Set the gamma
+ U32 getFSAASamples() override;
+ void setFSAASamples(const U32 fsaa_samples) override;
+ BOOL restoreGamma() override; // Restore original gamma table (before updating gamma)
+ ESwapMethod getSwapMethod() override { return mSwapMethod; }
+ void gatherInput() override;
+ void delayInputProcessing() override {};
+ void swapBuffers() override;
// handy coordinate space conversion routines
- /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to);
- /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to);
- /*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to);
- /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to);
- /*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to);
- /*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to);
+ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) override;
+ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) override;
+ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) override;
+ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) override;
+ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) override;
+ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) override;
- /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions);
- /*virtual*/ F32 getNativeAspectRatio();
- /*virtual*/ F32 getPixelAspectRatio();
- /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; }
+ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override;
+ F32 getNativeAspectRatio() override;
+ F32 getPixelAspectRatio() override;
+ void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; }
- /*virtual*/ void beforeDialog();
- /*virtual*/ void afterDialog();
+ void beforeDialog() override;
+ void afterDialog() override;
- /*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b);
+ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b) override;
- /*virtual*/ void *getPlatformWindow();
- /*virtual*/ void bringToFront() {};
+ void *getPlatformWindow() override;
+ void bringToFront() override {};
- /*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
- /*virtual*/ void interruptLanguageTextInput();
- /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
- /*virtual*/ F32 getSystemUISize();
+ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) override;
+ void interruptLanguageTextInput() override;
+ void spawnWebBrowser(const std::string& escaped_url, bool async) override;
+ F32 getSystemUISize() override;
static std::vector<std::string> getDisplaysResolutionList();
static std::vector<std::string> getDynamicFallbackFontList();
// Provide native key event data
- /*virtual*/ LLSD getNativeKeyData();
+ LLSD getNativeKeyData() override;
void* getWindow() { return mWindow; }
LLWindowCallbacks* getCallbacks() { return mCallbacks; }
@@ -132,6 +131,15 @@ public:
bool allowsLanguageInput() { return mLanguageTextInputAllowed; }
+ //create a new GL context that shares a namespace with this Window's main GL context and make it current on the current thread
+ // returns a pointer to be handed back to destroySharedConext/makeContextCurrent
+ void* createSharedContext() override;
+ //make the given context current on the current thread
+ void makeContextCurrent(void* context) override;
+ //destroy the given context that was retrieved by createSharedContext()
+ //Must be called on the same thread that called createSharedContext()
+ void destroySharedContext(void* context) override;
+
protected:
LLWindowMacOSX(LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags,
@@ -141,7 +149,7 @@ protected:
~LLWindowMacOSX();
void initCursors();
- BOOL isValid();
+ BOOL isValid() override;
void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size);
@@ -157,7 +165,7 @@ protected:
BOOL shouldPostQuit() { return mPostQuit; }
//Satisfy MAINT-3135 and MAINT-3288 with a flag.
- /*virtual */ void setOldResize(bool oldresize) {setResizeMode(oldresize, mGLView); }
+ /*virtual */ void setOldResize(bool oldresize) override {setResizeMode(oldresize, mGLView); }
private:
void restoreGLContext();
@@ -231,9 +239,9 @@ public:
LLSplashScreenMacOSX();
virtual ~LLSplashScreenMacOSX();
- /*virtual*/ void showImpl();
- /*virtual*/ void updateImpl(const std::string& mesg);
- /*virtual*/ void hideImpl();
+ void showImpl();
+ void updateImpl(const std::string& mesg);
+ void hideImpl();
private:
WindowRef mWindow;
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 4ce7c30bef..12d4c6c30e 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -1774,58 +1774,11 @@ const S32 max_format = (S32)num_formats - 1;
mhRC = 0;
if (wglCreateContextAttribsARB)
{ //attempt to create a specific versioned context
- S32 attribs[] =
- { //start at 4.2
- WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
- WGL_CONTEXT_MINOR_VERSION_ARB, 2,
- WGL_CONTEXT_PROFILE_MASK_ARB, LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
- WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
- 0
- };
-
- bool done = false;
- while (!done)
- {
- mhRC = wglCreateContextAttribsARB(mhDC, mhRC, attribs);
-
- if (!mhRC)
- {
- if (attribs[3] > 0)
- { //decrement minor version
- attribs[3]--;
- }
- else if (attribs[1] > 3)
- { //decrement major version and start minor version over at 3
- attribs[1]--;
- attribs[3] = 3;
- }
- else
- { //we reached 3.0 and still failed, bail out
- done = true;
- }
- }
- else
- {
- LL_INFOS() << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) <<
- (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << LL_ENDL;
- done = true;
-
- // force sNoFixedFunction iff we're trying to use nsight debugging which does not support many legacy API uses
-
- // nSight doesn't support use of legacy API funcs in the fixed function pipe
- if (LLRender::sGLCoreProfile || LLRender::sNsightDebugSupport)
- {
- LLGLSLShader::sNoFixedFunction = true;
- }
- }
- }
- }
-
- if (!mhRC && !(mhRC = wglCreateContext(mhDC)))
- {
- close();
- OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
- return FALSE;
+ mhRC = (HGLRC) createSharedContext();
+ if (!mhRC)
+ {
+ return FALSE;
+ }
}
if (!wglMakeCurrent(mhDC, mhRC))
@@ -1880,6 +1833,75 @@ const S32 max_format = (S32)num_formats - 1;
return TRUE;
}
+void* LLWindowWin32::createSharedContext()
+{
+ S32 attribs[] =
+ {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
+ WGL_CONTEXT_MINOR_VERSION_ARB, 2,
+ WGL_CONTEXT_PROFILE_MASK_ARB, LLRender::sGLCoreProfile ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+ WGL_CONTEXT_FLAGS_ARB, gDebugGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
+ 0
+ };
+
+ HGLRC rc = wglCreateContextAttribsARB(mhDC, mhRC, attribs);
+
+ bool done = false;
+ while (!done)
+ {
+ rc = wglCreateContextAttribsARB(mhDC, mhRC, attribs);
+
+ if (!rc)
+ {
+ if (attribs[3] > 0)
+ { //decrement minor version
+ attribs[3]--;
+ }
+ else if (attribs[1] > 3)
+ { //decrement major version and start minor version over at 3
+ attribs[1]--;
+ attribs[3] = 3;
+ }
+ else
+ { //we reached 3.0 and still failed, bail out
+ done = true;
+ }
+ }
+ else
+ {
+ LL_INFOS() << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) <<
+ (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << LL_ENDL;
+ done = true;
+
+ // force sNoFixedFunction iff we're trying to use nsight debugging which does not support many legacy API uses
+
+ // nSight doesn't support use of legacy API funcs in the fixed function pipe
+ if (LLRender::sGLCoreProfile || LLRender::sNsightDebugSupport)
+ {
+ LLGLSLShader::sNoFixedFunction = true;
+ }
+ }
+ }
+
+ if (!rc && !(rc = wglCreateContext(mhDC)))
+ {
+ close();
+ OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
+ }
+
+ return rc;
+}
+
+void LLWindowWin32::makeContextCurrent(void* contextPtr)
+{
+ wglMakeCurrent(mhDC, (HGLRC) contextPtr);
+}
+
+void LLWindowWin32::destroySharedContext(void* contextPtr)
+{
+ wglDeleteContext((HGLRC)contextPtr);
+}
+
void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScreen& size )
{
if( mIsMouseClipping )
@@ -3720,6 +3742,7 @@ BOOL LLWindowWin32::resetDisplayResolution()
void LLWindowWin32::swapBuffers()
{
+ LL_PROFILE_ZONE_SCOPED;
ASSERT_MAIN_THREAD();
SwapBuffers(mhDC);
@@ -4731,4 +4754,4 @@ void LLWindowWin32::post(const std::function<void()>& func)
#else
mFunctionQueue.pushFront(func);
#endif
-} \ No newline at end of file
+}
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 66647459b2..5f253b5df3 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -93,6 +93,9 @@ public:
/*virtual*/ BOOL setSizeImpl(LLCoordScreen size);
/*virtual*/ BOOL setSizeImpl(LLCoordWindow size);
/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL);
+ void* createSharedContext() override;
+ void makeContextCurrent(void* context) override;
+ void destroySharedContext(void* context) override;
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position);
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position);
/*virtual*/ void showCursor();
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 05c3fc3bfe..d05d100ddf 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9814,7 +9814,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>RenderGlow</key>
<map>
@@ -10599,7 +10599,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>RenderUseTransformFeedback</key>
<map>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 722a6caa65..e46e8feb14 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -613,7 +613,7 @@ static void settings_modify()
LLPipeline::sRenderDeferred = LLPipeline::sRenderTransparentWater && LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
- gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
+ gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
}
@@ -4831,6 +4831,7 @@ void LLAppViewer::idle()
LLNotificationsUI::LLToast::updateClass();
LLSmoothInterpolation::updateInterpolants();
LLMortician::updateClass();
+ LLImageGL::updateClass();
LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify()
LLDirPickerThread::clearDead();
F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 112da55682..111b45612e 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -147,6 +147,7 @@ void LLNetMap::setScale( F32 scale )
void LLNetMap::draw()
{
+ LL_PROFILE_ZONE_SCOPED;
static LLFrameTimer map_timer;
static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white);
static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white);
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index f64db7beb5..63e561147d 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -314,6 +314,7 @@ private:
// Threads: Ttc
virtual void completed(bool success)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
if (worker)
{
@@ -338,6 +339,7 @@ private:
// Threads: Ttc
virtual void completed(bool success)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
if (worker)
{
@@ -362,6 +364,7 @@ private:
// Threads: Tid
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
if (worker)
{
@@ -1139,6 +1142,7 @@ void LLTextureFetchWorker::startWork(S32 param)
// Threads: Ttf
bool LLTextureFetchWorker::doWork(S32 param)
{
+ LL_PROFILE_ZONE_SCOPED;
static const LLCore::HttpStatus http_not_found(HTTP_NOT_FOUND); // 404
static const LLCore::HttpStatus http_service_unavail(HTTP_SERVICE_UNAVAILABLE); // 503
static const LLCore::HttpStatus http_not_sat(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE); // 416;
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index af55f68cd2..274f53a160 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -184,6 +184,7 @@ void LLViewerTextureManager::findFetchedTextures(const LLUUID& id, std::vector<L
void LLViewerTextureManager::findTextures(const LLUUID& id, std::vector<LLViewerTexture*> &output)
{
+ LL_PROFILE_ZONE_SCOPED;
std::vector<LLViewerFetchedTexture*> fetched_output;
gTextureList.findTexturesByID(id, fetched_output);
std::vector<LLViewerFetchedTexture*>::iterator iter = fetched_output.begin();
@@ -485,6 +486,7 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_MEMORY_CHECK("Memory Check");
//static
bool LLViewerTexture::isMemoryForTextureLow()
{
+ LL_PROFILE_ZONE_SCOPED;
// Note: we need to figure out a better source for 'min' values,
// what is free for low end at minimal settings is 'nothing left'
// for higher end gpus at high settings.
@@ -501,6 +503,7 @@ bool LLViewerTexture::isMemoryForTextureLow()
//static
bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
{
+ LL_PROFILE_ZONE_SCOPED;
const S32Megabytes DESIRED_FREE_TEXTURE_MEMORY(50);
const S32Megabytes DESIRED_FREE_MAIN_MEMORY(200);
@@ -514,6 +517,7 @@ bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
//static
void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical)
{
+ LL_PROFILE_ZONE_SCOPED;
static LLFrameTimer timer;
static S32Megabytes gpu_res = S32Megabytes(S32_MAX);
static S32Megabytes physical_res = S32Megabytes(S32_MAX);
@@ -526,27 +530,29 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p
}
timer.reset();
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK);
-
- if (gGLManager.mHasATIMemInfo)
{
- S32 meminfo[4];
- glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
- gpu_res = (S32Megabytes)meminfo[0];
+ LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK);
- //check main memory, only works for windows.
- LLMemory::updateMemoryInfo();
- physical_res = LLMemory::getAvailableMemKB();
- }
- else if (gGLManager.mHasNVXMemInfo)
- {
- S32 free_memory;
- glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
- gpu_res = (S32Megabytes)(free_memory / 1024);
- }
+ if (gGLManager.mHasATIMemInfo)
+ {
+ S32 meminfo[4];
+ glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
+ gpu_res = (S32Megabytes)meminfo[0];
- gpu = gpu_res;
- physical = physical_res;
+ //check main memory, only works for windows.
+ LLMemory::updateMemoryInfo();
+ physical_res = LLMemory::getAvailableMemKB();
+ }
+ else if (gGLManager.mHasNVXMemInfo)
+ {
+ S32 free_memory;
+ glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
+ gpu_res = (S32Megabytes)(free_memory / 1024);
+ }
+
+ gpu = gpu_res;
+ physical = physical_res;
+ }
}
static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_MEDIA("Media");
@@ -555,6 +561,7 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_TEST("Test");
//static
void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity)
{
+ LL_PROFILE_ZONE_SCOPED;
sCurrentTime = gFrameTimeSeconds;
LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
@@ -704,6 +711,7 @@ void LLViewerTexture::cleanup()
void LLViewerTexture::notifyAboutCreatingTexture()
{
+ LL_PROFILE_ZONE_SCOPED;
for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
for(U32 f = 0; f < mNumFaces[ch]; f++)
@@ -715,6 +723,7 @@ void LLViewerTexture::notifyAboutCreatingTexture()
void LLViewerTexture::notifyAboutMissingAsset()
{
+ LL_PROFILE_ZONE_SCOPED;
for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
for(U32 f = 0; f < mNumFaces[ch]; f++)
@@ -727,6 +736,7 @@ void LLViewerTexture::notifyAboutMissingAsset()
// virtual
void LLViewerTexture::dump()
{
+ LL_PROFILE_ZONE_SCOPED;
LLGLTexture::dump();
LL_INFOS() << "LLViewerTexture"
@@ -762,6 +772,7 @@ bool LLViewerTexture::isActiveFetching()
bool LLViewerTexture::bindDebugImage(const S32 stage)
{
+ LL_PROFILE_ZONE_SCOPED;
if (stage < 0) return false;
bool res = true;
@@ -780,6 +791,7 @@ bool LLViewerTexture::bindDebugImage(const S32 stage)
bool LLViewerTexture::bindDefaultImage(S32 stage)
{
+ LL_PROFILE_ZONE_SCOPED;
if (stage < 0) return false;
bool res = true;
@@ -822,6 +834,7 @@ void LLViewerTexture::forceImmediateUpdate()
void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const
{
+ LL_PROFILE_ZONE_SCOPED;
if(needs_gltexture)
{
mNeedsGLTexture = TRUE;
@@ -864,6 +877,7 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
//virtual
void LLViewerTexture::addFace(U32 ch, LLFace* facep)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
if(mNumFaces[ch] >= mFaceList[ch].size())
@@ -879,6 +893,7 @@ void LLViewerTexture::addFace(U32 ch, LLFace* facep)
//virtual
void LLViewerTexture::removeFace(U32 ch, LLFace* facep)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
if(mNumFaces[ch] > 1)
@@ -919,6 +934,7 @@ S32 LLViewerTexture::getNumFaces(U32 ch) const
//virtual
void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep)
{
+ LL_PROFILE_ZONE_SCOPED;
if (mNumVolumes[ch] >= mVolumeList[ch].size())
{
mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1);
@@ -932,6 +948,7 @@ void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep)
//virtual
void LLViewerTexture::removeVolume(U32 ch, LLVOVolume* volumep)
{
+ LL_PROFILE_ZONE_SCOPED;
if (mNumVolumes[ch] > 1)
{
S32 index = volumep->getIndexInTex(ch);
@@ -955,6 +972,7 @@ S32 LLViewerTexture::getNumVolumes(U32 ch) const
void LLViewerTexture::reorganizeFaceList()
{
+ LL_PROFILE_ZONE_SCOPED;
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
@@ -978,6 +996,7 @@ void LLViewerTexture::reorganizeFaceList()
void LLViewerTexture::reorganizeVolumeList()
{
+ LL_PROFILE_ZONE_SCOPED;
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
@@ -1180,6 +1199,7 @@ FTType LLViewerFetchedTexture::getFTType() const
void LLViewerFetchedTexture::cleanup()
{
+ LL_PROFILE_ZONE_SCOPED;
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
iter != mLoadedCallbackList.end(); )
{
@@ -1205,6 +1225,7 @@ void LLViewerFetchedTexture::cleanup()
//access the fast cache
void LLViewerFetchedTexture::loadFromFastCache()
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInFastCacheList)
{
return; //no need to access the fast cache.
@@ -1350,6 +1371,7 @@ void LLViewerFetchedTexture::dump()
// ONLY called from LLViewerFetchedTextureList
void LLViewerFetchedTexture::destroyTexture()
{
+ LL_PROFILE_ZONE_SCOPED;
if(LLImageGL::sGlobalTextureMemory < sMaxDesiredTextureMem * 0.95f)//not ready to release unused memory.
{
return ;
@@ -1366,6 +1388,7 @@ void LLViewerFetchedTexture::destroyTexture()
void LLViewerFetchedTexture::addToCreateTexture()
{
+ LL_PROFILE_ZONE_SCOPED;
bool force_update = false;
if (getComponents() != mRawImage->getComponents())
{
@@ -1407,6 +1430,7 @@ void LLViewerFetchedTexture::addToCreateTexture()
}
else
{
+ LL_PROFILE_ZONE_SCOPED;
#if 1
//
//if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up,
@@ -1451,99 +1475,100 @@ void LLViewerFetchedTexture::addToCreateTexture()
}
}
#endif
- mNeedsCreateTexture = TRUE;
- gTextureList.mCreateTextureList.insert(this);
- }
+ scheduleCreateTexture();
+ }
return;
}
// ONLY called from LLViewerTextureList
-BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
+BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/)
{
- if (!mNeedsCreateTexture)
- {
- destroyRawImage();
- return FALSE;
- }
- mNeedsCreateTexture = FALSE;
- if (mRawImage.isNull())
- {
- LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL;
- }
- if (mRawImage->isBufferInvalid())
- {
- LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL;
- destroyRawImage();
- return FALSE;
- }
-// LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
-// mRawDiscardLevel,
-// mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
-// << mID.getString() << LL_ENDL;
- BOOL res = TRUE;
+ LL_PROFILE_ZONE_SCOPED;
+ if (!mNeedsCreateTexture)
+ {
+ destroyRawImage();
+ return FALSE;
+ }
+ mNeedsCreateTexture = FALSE;
- // store original size only for locally-sourced images
- if (mUrl.compare(0, 7, "file://") == 0)
- {
- mOrigWidth = mRawImage->getWidth();
- mOrigHeight = mRawImage->getHeight();
+ if (mRawImage.isNull())
+ {
+ LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL;
+ }
+ if (mRawImage->isBufferInvalid())
+ {
+ LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL;
+ destroyRawImage();
+ return FALSE;
+ }
+ // LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
+ // mRawDiscardLevel,
+ // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
+ // << mID.getString() << LL_ENDL;
+ BOOL res = TRUE;
+
+ // store original size only for locally-sourced images
+ if (mUrl.compare(0, 7, "file://") == 0)
+ {
+ mOrigWidth = mRawImage->getWidth();
+ mOrigHeight = mRawImage->getHeight();
// This is only safe because it's a local image and fetcher doesn't use raw data
// from local images, but this might become unsafe in case of changes to fetcher
- if (mBoostLevel == BOOST_PREVIEW)
- {
- mRawImage->biasedScaleToPowerOfTwo(1024);
- }
- else
- { // leave black border, do not scale image content
- mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
- }
-
- mFullWidth = mRawImage->getWidth();
- mFullHeight = mRawImage->getHeight();
- setTexelsPerImage();
- }
- else
- {
- mOrigWidth = mFullWidth;
- mOrigHeight = mFullHeight;
- }
+ if (mBoostLevel == BOOST_PREVIEW)
+ {
+ mRawImage->biasedScaleToPowerOfTwo(1024);
+ }
+ else
+ { // leave black border, do not scale image content
+ mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
+ }
- bool size_okay = true;
+ mFullWidth = mRawImage->getWidth();
+ mFullHeight = mRawImage->getHeight();
+ setTexelsPerImage();
+ }
+ else
+ {
+ mOrigWidth = mFullWidth;
+ mOrigHeight = mFullHeight;
+ }
- S32 discard_level = mRawDiscardLevel;
- if (mRawDiscardLevel < 0)
- {
- LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL;
- discard_level = 0;
- }
+ bool size_okay = true;
- U32 raw_width = mRawImage->getWidth() << discard_level;
- U32 raw_height = mRawImage->getHeight() << discard_level;
+ S32 discard_level = mRawDiscardLevel;
+ if (mRawDiscardLevel < 0)
+ {
+ LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL;
+ discard_level = 0;
+ }
- if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE )
- {
- LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL;
- size_okay = false;
- }
-
- if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
- {
- // A non power-of-two image was uploaded (through a non standard client)
- LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL;
- size_okay = false;
- }
-
- if( !size_okay )
- {
- // An inappropriately-sized image was uploaded (through a non standard client)
- // We treat these images as missing assets which causes them to
- // be renderd as 'missing image' and to stop requesting data
- LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL;
- setIsMissingAsset();
- destroyRawImage();
- return FALSE;
- }
+ U32 raw_width = mRawImage->getWidth() << discard_level;
+ U32 raw_height = mRawImage->getHeight() << discard_level;
+
+ if (raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE)
+ {
+ LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL;
+ size_okay = false;
+ }
+
+ if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
+ {
+ // A non power-of-two image was uploaded (through a non standard client)
+ LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL;
+ size_okay = false;
+ }
+
+ if (!size_okay)
+ {
+ // An inappropriately-sized image was uploaded (through a non standard client)
+ // We treat these images as missing assets which causes them to
+ // be renderd as 'missing image' and to stop requesting data
+ LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL;
+ setIsMissingAsset();
+ destroyRawImage();
+ return FALSE;
+ }
if (mGLTexturep->getHasExplicitFormat())
{
@@ -1565,19 +1590,79 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
}
}
- res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+ return res;
+}
- notifyAboutCreatingTexture();
+BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
+{
+ if (!mNeedsCreateTexture)
+ {
+ return FALSE;
+ }
- setActive();
+ BOOL res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+
+ return res;
+}
- if (!needsToSaveRawImage())
- {
- mNeedsAux = FALSE;
- destroyRawImage();
- }
+void LLViewerFetchedTexture::postCreateTexture()
+{
+ if (!mNeedsCreateTexture)
+ {
+ return;
+ }
- return res;
+ notifyAboutCreatingTexture();
+
+ setActive();
+
+ if (!needsToSaveRawImage())
+ {
+ mNeedsAux = FALSE;
+ destroyRawImage();
+ }
+
+ mNeedsCreateTexture = FALSE;
+}
+
+void LLViewerFetchedTexture::scheduleCreateTexture()
+{
+ ref();
+ mNeedsCreateTexture = TRUE;
+ if (preCreateTexture())
+ {
+ mNeedsCreateTexture = TRUE;
+#if LL_WINDOWS //flip to 0 to revert to single-threaded OpenGL texture uploads
+ if (!LLImageGLThread::sInstance->post([this]()
+ {
+ //actually create the texture on a background thread
+ createTexture();
+ {
+ LL_PROFILE_ZONE_NAMED("iglt - sync");
+ if (gGLManager.mHasSync)
+ {
+ auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ glClientWaitSync(sync, 0, 0);
+ glDeleteSync(sync);
+ }
+ else
+ {
+ glFinish();
+ }
+ }
+ LLImageGLThread::sInstance->postCallback([this]()
+ {
+ //finalize on main thread
+ postCreateTexture();
+ unref();
+ });
+ }))
+#endif
+ {
+ gTextureList.mCreateTextureList.insert(this);
+ unref();
+ }
+ }
}
// Call with 0,0 to turn this feature off.
@@ -1869,6 +1954,7 @@ void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
void LLViewerFetchedTexture::updateVirtualSize()
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mMaxVirtualSizeResetCounter)
{
addTextureStats(0.f, FALSE);//reset
@@ -1960,6 +2046,7 @@ bool LLViewerFetchedTexture::isActiveFetching()
bool LLViewerFetchedTexture::updateFetch()
{
+ LL_PROFILE_ZONE_SCOPED;
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2);
static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3);
@@ -2062,7 +2149,7 @@ bool LLViewerFetchedTexture::updateFetch()
}
else
{
- mIsRawImageValid = TRUE;
+ mIsRawImageValid = TRUE;
addToCreateTexture();
}
@@ -2890,6 +2977,7 @@ void LLViewerFetchedTexture::destroyRawImage()
//virtual
void LLViewerFetchedTexture::switchToCachedImage()
{
+ LL_PROFILE_ZONE_SCOPED;
if(mCachedRawImage.notNull())
{
mRawImage = mCachedRawImage;
@@ -2901,12 +2989,12 @@ void LLViewerFetchedTexture::switchToCachedImage()
mComponents = mRawImage->getComponents();
mGLTexturep->setComponents(mComponents);
gTextureList.dirtyImage(this);
- }
+ }
mIsRawImageValid = TRUE;
mRawDiscardLevel = mCachedRawDiscardLevel;
- gTextureList.mCreateTextureList.insert(this);
- mNeedsCreateTexture = TRUE;
+
+ scheduleCreateTexture();
}
}
@@ -3180,6 +3268,7 @@ bool LLViewerLODTexture::isUpdateFrozen()
//virtual
void LLViewerLODTexture::processTextureStats()
{
+ LL_PROFILE_ZONE_SCOPED;
updateVirtualSize();
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 69568cc825..a5a1fb2c16 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -321,9 +321,13 @@ public:
void addToCreateTexture();
-
- // ONLY call from LLViewerTextureList
+ //call to determine if createTexture is necessary
+ BOOL preCreateTexture(S32 usename = 0);
+ // ONLY call from LLViewerTextureList or ImageGL background thread
BOOL createTexture(S32 usename = 0);
+ void postCreateTexture();
+ void scheduleCreateTexture();
+
void destroyTexture() ;
virtual void processTextureStats() ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 12495078e9..db740b69e9 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -114,6 +114,7 @@ void LLViewerTextureList::init()
void LLViewerTextureList::doPreloadImages()
{
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL;
llassert_always(mInitialized) ;
@@ -205,6 +206,7 @@ static std::string get_texture_list_name()
void LLViewerTextureList::doPrefetchImages()
{
+ LL_PROFILE_ZONE_SCOPED;
if (LLAppViewer::instance()->getPurgeCache())
{
// cache was purged, no point
@@ -258,6 +260,7 @@ LLViewerTextureList::~LLViewerTextureList()
void LLViewerTextureList::shutdown()
{
+ LL_PROFILE_ZONE_SCOPED;
// clear out preloads
mImagePreloads.clear();
@@ -333,6 +336,7 @@ void LLViewerTextureList::shutdown()
void LLViewerTextureList::dump()
{
+ LL_PROFILE_ZONE_SCOPED;
LL_INFOS() << "LLViewerTextureList::dump()" << LL_ENDL;
for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it)
{
@@ -377,6 +381,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
LLGLenum primary_format,
const LLUUID& force_id)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInitialized)
{
return NULL ;
@@ -404,6 +409,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
LLGLenum primary_format,
const LLUUID& force_id)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInitialized)
{
return NULL ;
@@ -492,6 +498,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
LLGLenum primary_format,
LLHost request_from_host)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInitialized)
{
return NULL ;
@@ -554,6 +561,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
LLGLenum primary_format,
LLHost request_from_host)
{
+ LL_PROFILE_ZONE_SCOPED;
static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled", true);
LLPointer<LLViewerFetchedTexture> imagep ;
@@ -609,6 +617,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector<LLViewerFetchedTexture*> &output)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTextureKey search_key(image_id, TEX_LIST_STANDARD);
uuid_map_t::iterator iter = mUUIDMap.lower_bound(search_key);
while (iter != mUUIDMap.end() && iter->first.textureId == image_id)
@@ -634,6 +643,7 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id, E
void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
{
+ LL_PROFILE_ZONE_SCOPED;
assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
@@ -653,6 +663,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
{
+ LL_PROFILE_ZONE_SCOPED;
assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
@@ -701,6 +712,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListType tex_type)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!new_image)
{
return;
@@ -724,6 +736,7 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListTy
void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image)
{
+ LL_PROFILE_ZONE_SCOPED;
if( image)
{
if (image->hasCallbacks())
@@ -845,6 +858,7 @@ void LLViewerTextureList::updateImages(F32 max_time)
void LLViewerTextureList::clearFetchingRequests()
{
+ LL_PROFILE_ZONE_SCOPED;
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
{
return;
@@ -862,6 +876,7 @@ void LLViewerTextureList::clearFetchingRequests()
void LLViewerTextureList::updateImagesDecodePriorities()
{
+ LL_PROFILE_ZONE_SCOPED;
// Update the decode priority for N images each frame
{
F32 lazy_flush_timeout = 30.f; // stop decoding
@@ -977,6 +992,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()
void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!tex->setDebugFetching(debug_level))
{
return;
@@ -1025,6 +1041,7 @@ void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debu
F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
{
+ LL_PROFILE_ZONE_SCOPED;
if (gGLManager.mIsDisabled) return 0.0f;
//
@@ -1041,6 +1058,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
enditer = iter;
LLViewerFetchedTexture *imagep = *curiter;
imagep->createTexture();
+ imagep->postCreateTexture();
if (create_timer.getElapsedTimeF32() > max_time)
{
break;
@@ -1052,6 +1070,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
{
+ LL_PROFILE_ZONE_SCOPED;
if (gGLManager.mIsDisabled) return 0.0f;
if(mFastCacheList.empty())
{
@@ -1082,6 +1101,7 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!imagep)
{
return ;
@@ -1101,6 +1121,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTimer image_op_timer;
// Update fetch for N images each frame
@@ -1176,6 +1197,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
void LLViewerTextureList::updateImagesUpdateStats()
{
+ LL_PROFILE_ZONE_SCOPED;
if (mForceResetTextureStats)
{
for (image_priority_list_t::iterator iter = mImageList.begin();
@@ -1190,6 +1212,7 @@ void LLViewerTextureList::updateImagesUpdateStats()
void LLViewerTextureList::decodeAllImages(F32 max_time)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTimer timer;
//loading from fast cache
@@ -1259,6 +1282,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
const std::string& out_filename,
const U8 codec)
{
+ LL_PROFILE_ZONE_SCOPED;
// Load the image
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
if (image.isNull())
@@ -1312,6 +1336,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
// note: modifies the argument raw_image!!!!
LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image)
{
+ LL_PROFILE_ZONE_SCOPED;
raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
@@ -1345,6 +1370,7 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
// Returns min setting for TextureMemory (in MB)
S32Megabytes LLViewerTextureList::getMinVideoRamSetting()
{
+ LL_PROFILE_ZONE_SCOPED;
U32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
//min texture mem sets to 64M if total physical mem is more than 1.5GB
return (system_ram > U32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ;
@@ -1354,6 +1380,7 @@ S32Megabytes LLViewerTextureList::getMinVideoRamSetting()
// Returns max setting for TextureMemory (in MB)
S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier)
{
+ LL_PROFILE_ZONE_SCOPED;
S32Megabytes max_texmem;
if (gGLManager.mVRAM != 0)
{
@@ -1407,6 +1434,7 @@ const S32Megabytes VIDEO_CARD_FRAMEBUFFER_MEM(12);
const S32Megabytes MIN_MEM_FOR_NON_TEXTURE(512);
void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
{
+ LL_PROFILE_ZONE_SCOPED;
// Initialize the image pipeline VRAM settings
S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory"));
F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
@@ -1647,6 +1675,7 @@ void LLUIImageList::cleanUp()
LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id, S32 priority)
{
+ LL_PROFILE_ZONE_SCOPED;
// use id as image name
std::string image_name = image_id.asString();
@@ -1665,6 +1694,7 @@ LLUIImagePtr LLUIImageList::getUIImageByID(const LLUUID& image_id, S32 priority)
LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priority)
{
+ LL_PROFILE_ZONE_SCOPED;
// look for existing image
uuid_ui_image_map_t::iterator found_it = mUIImages.find(image_name);
if (found_it != mUIImages.end())
@@ -1682,6 +1712,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std
BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority,
LLUIImage::EScaleStyle scale_style)
{
+ LL_PROFILE_ZONE_SCOPED;
if (boost_priority == LLGLTexture::BOOST_NONE)
{
boost_priority = LLGLTexture::BOOST_UI;
@@ -1694,6 +1725,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id,
BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority,
LLUIImage::EScaleStyle scale_style)
{
+ LL_PROFILE_ZONE_SCOPED;
if (boost_priority == LLGLTexture::BOOST_NONE)
{
boost_priority = LLGLTexture::BOOST_UI;
@@ -1705,6 +1737,7 @@ LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id,
LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect,
LLUIImage::EScaleStyle scale_style)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!imagep) return NULL;
imagep->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -1742,6 +1775,7 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLUIImage::EScaleStyle scale_style)
{
+ LL_PROFILE_ZONE_SCOPED;
// look for existing image
uuid_ui_image_map_t::iterator found_it = mUIImages.find(name);
if (found_it != mUIImages.end())
@@ -1756,6 +1790,7 @@ LLUIImagePtr LLUIImageList::preloadUIImage(const std::string& name, const std::s
//static
void LLUIImageList::onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* user_data )
{
+ LL_PROFILE_ZONE_SCOPED;
if(!success || !user_data)
{
return;
@@ -1857,6 +1892,7 @@ struct UIImageDeclarations : public LLInitParam::Block<UIImageDeclarations>
bool LLUIImageList::initFromFile()
{
+ LL_PROFILE_ZONE_SCOPED;
// Look for textures.xml in all the right places. Pass
// constraint=LLDir::ALL_SKINS because we want to overlay textures.xml
// from all the skins directories.
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index c52a4e98d3..82ece85c1b 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2011,7 +2011,7 @@ 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(LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ;
+ LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ;
gTextureList.init();
LLViewerTextureManager::init() ;
gBumpImageList.init();