Commits

davep committed 5e94268

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

Comments (0)

Files changed (2)

indra/newview/pipeline.cpp

 		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);
 	}
 }
 
 		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
 	}
 
-	bool ret = doAllocateScreenBuffer(resX, resY);
+	eFBOStatus ret = doAllocateScreenBuffer(resX, resY);
 
 	if (save_settings)
 	{
 		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
 	}
 	
-	return ret;
-}
-
-
-bool LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
+	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;
+}
+
+
+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
 
 	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 
 			samples /= 2;
 			if (allocateScreenBuffer(resX, resY, samples))
 			{ //success
-				return ret;
+				return FBO_SUCCESS_LOWRES;
 			}
 			releaseScreenBuffers();
 		}
 			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();
 		}

indra/newview/pipeline.h

 	//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