SL-18869 Followup -- leverage "small commands" and time slicing to get rid of frame stalls on main thread without the need for multithreaded GL
parent
7bd9d21e19
commit
8b39e0e1a6
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue