MAINT-1958 More robust error handling -- handle the case where the FBO allocation failure occurs when enabling lighting and shadows.

meow-7.2.2
Dave Parks 2012-11-30 17:47:12 -06:00
parent 9a8cf6603f
commit 9c205ee9e2
2 changed files with 28 additions and 19 deletions

View File

@ -764,16 +764,7 @@ void LLPipeline::resizeScreenTexture()
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
if (!allocateScreenBuffer(resX,resY))
{ //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
//NOTE: if the session closes successfully after this call, deferred rendering will be
// disabled on future sessions
if (LLPipeline::sRenderDeferred)
{
gSavedSettings.setBOOL("RenderDeferred", FALSE);
LLPipeline::refreshCachedSettings();
}
}
allocateScreenBuffer(resX,resY);
}
}
@ -800,7 +791,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
}
bool ret = doAllocateScreenBuffer(resX, resY);
eFBOStatus ret = doAllocateScreenBuffer(resX, resY);
if (save_settings)
{
@ -809,11 +800,22 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
}
return ret;
if (ret == FBO_FAILURE)
{ //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
//NOTE: if the session closes successfully after this call, deferred rendering will be
// disabled on future sessions
if (LLPipeline::sRenderDeferred)
{
gSavedSettings.setBOOL("RenderDeferred", FALSE);
LLPipeline::refreshCachedSettings();
}
}
return ret == FBO_SUCCESS_FULLRES;
}
bool LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
{
//try to allocate screen buffers at requested resolution and samples
// - on failure, shrink number of samples and try again
@ -822,11 +824,11 @@ bool LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
U32 samples = RenderFSAASamples;
bool ret = true;
eFBOStatus ret = FBO_SUCCESS_FULLRES;
if (!allocateScreenBuffer(resX, resY, samples))
{
//failed to allocate at requested specification, return false
ret = false;
ret = FBO_FAILURE;
releaseScreenBuffers();
//reduce number of samples
@ -835,7 +837,7 @@ bool LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
samples /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{ //success
return ret;
return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
}
@ -848,14 +850,14 @@ bool LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
resY /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{
return ret;
return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
resX /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{
return ret;
return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
}

View File

@ -122,9 +122,16 @@ public:
//allocate the largest screen buffer possible up to resX, resY
//returns true if full size buffer allocated, false if some other size is allocated
bool allocateScreenBuffer(U32 resX, U32 resY);
typedef enum {
FBO_SUCCESS_FULLRES = 0,
FBO_SUCCESS_LOWRES,
FBO_FAILURE
} eFBOStatus;
private:
//implementation of above, wrapped for easy error handling
bool doAllocateScreenBuffer(U32 resX, U32 resY);
eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY);
public:
//attempt to allocate screen buffers at resX, resY