SL-18869 Followup -- leverage "small commands" and time slicing to get rid of frame stalls on main thread without the need for multithreaded GL

master
Dave Parks 2023-01-19 11:33:11 -06:00
parent 7bd9d21e19
commit 8b39e0e1a6
3 changed files with 78 additions and 18 deletions

View File

@ -1404,9 +1404,53 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
stop_glerror();
{
LL_PROFILE_ZONE_NAMED("glTexImage2D");
LL_PROFILE_ZONE_NUM(width);
LL_PROFILE_ZONE_NUM(height);
free_cur_tex_image();
#if 0
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
#else
// break up calls to a manageable size for the GL command buffer
{
LL_PROFILE_ZONE_NAMED("glTexImage2D alloc");
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, nullptr);
}
U8* src = (U8*)(use_scratch ? scratch : pixels);
if (src)
{
LL_PROFILE_ZONE_NAMED("glTexImage2D copy");
U32 components = dataFormatComponents(pixformat);
U32 type_width = 0;
switch (pixtype)
{
case GL_UNSIGNED_BYTE:
case GL_BYTE:
type_width = 1;
break;
case GL_UNSIGNED_SHORT:
case GL_SHORT:
type_width = 2;
break;
case GL_UNSIGNED_INT:
case GL_INT:
case GL_FLOAT:
type_width = 4;
break;
default:
LL_ERRS() << "Unknown type: " << pixtype << LL_ENDL;
}
U32 line_width = width * components * type_width;
for (U32 y = 0; y < height; ++y)
{
glTexSubImage2D(target, miplevel, 0, y, width, 1, pixformat, pixtype, src);
src += line_width;
}
}
#endif
alloc_tex_image(width, height, pixformat);
}
stop_glerror();

View File

@ -1,4 +1,4 @@
version 44
version 45
// 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
@ -72,7 +72,7 @@ RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
RenderGLContextCoreProfile 1 1
RenderGLMultiThreaded 1 1
RenderGLMultiThreaded 1 0
//
@ -290,12 +290,10 @@ RenderReflectionProbeDetail 0 -1
list Intel
RenderAnisotropic 1 0
RenderFSAASamples 1 0
RenderGLMultiThreaded 1 0
RenderGLContextCoreProfile 1 0
list GL3
RenderFSAASamples 0 0
RenderReflectionsEnabled 0 0
RenderReflectionProbeDetail 0 0
RenderGLMultiThreaded 0 0

View File

@ -806,15 +806,20 @@ void LLViewerTextureList::updateImages(F32 max_time)
sample(FORMATTED_MEM, F64Bytes(LLImageFormatted::sGlobalFormattedMemory));
}
//loading from fast cache
max_time -= updateImagesLoadingFastCache(max_time);
F32 total_max_time = max_time;
// make sure each call below gets at least its "fair share" of time
F32 min_time = max_time * 0.33f;
F32 remaining_time = max_time;
max_time -= updateImagesFetchTextures(max_time);
max_time = llmax(max_time, total_max_time*.50f); // at least 50% of max_time
max_time -= updateImagesCreateTextures(max_time);
//loading from fast cache
remaining_time -= updateImagesLoadingFastCache(remaining_time);
remaining_time = llmax(remaining_time, min_time);
//dispatch to texture fetch threads
remaining_time -= updateImagesFetchTextures(remaining_time);
remaining_time = llmax(remaining_time, min_time);
//handle results from decode threads
updateImagesCreateTextures(remaining_time);
if (!mDirtyTextureList.empty())
{
@ -1037,6 +1042,11 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
LLViewerFetchedTexture *imagep = *curiter;
imagep->createTexture();
imagep->postCreateTexture();
if (create_timer.getElapsedTimeF32() > max_time)
{
break;
}
}
mCreateTextureList.erase(mCreateTextureList.begin(), enditer);
return create_timer.getElapsedTimeF32();
@ -1091,8 +1101,6 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLTimer image_op_timer;
typedef std::vector<LLPointer<LLViewerFetchedTexture> > entries_list_t;
entries_list_t entries;
@ -1125,6 +1133,10 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
}
}
LLTimer timer;
LLPointer<LLViewerTexture> last_imagep = nullptr;
for (auto& imagep : entries)
{
if (imagep->getNumRefs() > 1) // make sure this image hasn't been deleted before attempting to update (may happen as a side effect of some other image updating)
@ -1132,15 +1144,21 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
updateImageDecodePriority(imagep);
imagep->updateFetch();
}
last_imagep = imagep;
if (timer.getElapsedTimeF32() > max_time)
{
break;
}
}
if (entries.size() > 0)
if (last_imagep)
{
LLViewerFetchedTexture* imagep = *entries.rbegin();
mLastUpdateKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType());
mLastUpdateKey = LLTextureKey(last_imagep->getID(), (ETexListType)last_imagep->getTextureListType());
}
return image_op_timer.getElapsedTimeF32();
return timer.getElapsedTimeF32();
}
void LLViewerTextureList::updateImagesUpdateStats()