Add flag to disable gl error checking when allocating gpu objects
Review URL: http://codereview.appspot.com/5558052/
git-svn-id: http://skia.googlecode.com/svn/trunk@3075 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrGLConfig.h b/include/gpu/GrGLConfig.h
index c9aaec5..167c8eb 100644
--- a/include/gpu/GrGLConfig.h
+++ b/include/gpu/GrGLConfig.h
@@ -86,6 +86,12 @@
* glReadPixels to read the entire framebuffer is faster than calling it with
* the same sized rectangle but with a framebuffer bound that is larger than
* the rectangle read.
+ *
+ * GR_GL_CHECK_ALLOC_WITH_GET_ERROR: If set to 1 this will then glTexImage,
+ * glBufferData, glRenderbufferStorage, etc will be checked for errors. This
+ * amounts to ensuring the error is GL_NO_ERROR, calling the allocating
+ * function, and then checking that the error is still GL_NO_ERROR. When the
+ * value is 0 we will assume no error was generated without checking.
*/
#if !defined(GR_GL_LOG_CALLS)
@@ -128,6 +134,10 @@
#define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL 0
#endif
+#if !defined(GR_GL_CHECK_ALLOC_WITH_GET_ERROR)
+ #define GR_GL_CHECK_ALLOC_WITH_GET_ERROR 1
+#endif
+
#if(GR_GL_NO_CONSTANT_ATTRIBUTES) && (GR_GL_ATTRIBUTE_MATRICES)
#error "Cannot combine GR_GL_NO_CONSTANT_ATTRIBUTES and GR_GL_ATTRIBUTE_MATRICES"
#endif
diff --git a/include/gpu/GrGLConfig_chrome.h b/include/gpu/GrGLConfig_chrome.h
index ee3c991..2bae145 100644
--- a/include/gpu/GrGLConfig_chrome.h
+++ b/include/gpu/GrGLConfig_chrome.h
@@ -9,22 +9,26 @@
#define GrGLConfig_chrome_DEFINED
// glGetError() forces a sync with gpu process on chrome
-#define GR_GL_CHECK_ERROR_START 0
+#define GR_GL_CHECK_ERROR_START 0
// ANGLE creates a temp VB for vertex attributes not specified per-vertex.
-#define GR_GL_NO_CONSTANT_ATTRIBUTES GR_WIN32_BUILD
+#define GR_GL_NO_CONSTANT_ATTRIBUTES GR_WIN32_BUILD
// For RGBA teximage/readpixels ANGLE will sw-convert to/from BGRA.
-#define GR_GL_RGBA_8888_PIXEL_OPS_SLOW GR_WIN32_BUILD
+#define GR_GL_RGBA_8888_PIXEL_OPS_SLOW GR_WIN32_BUILD
// ANGLE can go faster if the entire fbo is read rather than a subrect
-#define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL GR_WIN32_BUILD
+#define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL GR_WIN32_BUILD
// cmd buffer allocates memory and memsets it to zero when it sees glBufferData
// with NULL.
-#define GR_GL_USE_BUFFER_DATA_NULL_HINT 0
+#define GR_GL_USE_BUFFER_DATA_NULL_HINT 0
// chrome uses this to set the context on each GL call.
-#define GR_GL_PER_GL_FUNC_CALLBACK 1
+#define GR_GL_PER_GL_FUNC_CALLBACK 1
+
+// Check error is even more expensive in chrome (cmd buffer flush). The
+// compositor also doesn't check its allocations.
+#define GR_GL_CHECK_ALLOC_WITH_GET_ERROR 0
#endif
diff --git a/src/gpu/GrGpuGL.cpp b/src/gpu/GrGpuGL.cpp
index d0fb12fe..f1bc63d 100644
--- a/src/gpu/GrGpuGL.cpp
+++ b/src/gpu/GrGpuGL.cpp
@@ -24,6 +24,16 @@
#define SKIP_CACHE_CHECK true
+#if GR_GL_CHECK_ALLOC_WITH_GET_ERROR
+ #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface)
+ #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call)
+ #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface)
+#else
+ #define CLEAR_ERROR_BEFORE_ALLOC(iface)
+ #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call)
+ #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR
+#endif
+
static const GrGLenum gXfermodeCoeff2Blend[] = {
GR_GL_ZERO,
GR_GL_ONE,
@@ -863,40 +873,39 @@
if (isNewTexture &&
0 == left && 0 == top &&
desc.fWidth == width && desc.fHeight == height) {
- GrGLClearErr(this->glInterface());
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
if (useTexStorage) {
// We never resize or change formats of textures. We don't use
// mipmaps currently.
- GR_GL_CALL_NOERRCHECK(this->glInterface(),
- TexStorage2D(GR_GL_TEXTURE_2D,
- 1, // levels
- internalFormat,
- desc.fWidth, desc.fHeight));
+ GL_ALLOC_CALL(this->glInterface(),
+ TexStorage2D(GR_GL_TEXTURE_2D,
+ 1, // levels
+ internalFormat,
+ desc.fWidth, desc.fHeight));
} else {
if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
GrGLsizei imageSize = desc.fWidth * desc.fHeight +
kGrColorTableSize;
- GR_GL_CALL_NOERRCHECK(this->glInterface(),
- CompressedTexImage2D(GR_GL_TEXTURE_2D,
- 0, // level
- internalFormat,
- desc.fWidth,
- desc.fHeight,
- 0, // border
- imageSize,
- data));
+ GL_ALLOC_CALL(this->glInterface(),
+ CompressedTexImage2D(GR_GL_TEXTURE_2D,
+ 0, // level
+ internalFormat,
+ desc.fWidth, desc.fHeight,
+ 0, // border
+ imageSize,
+ data));
} else {
- GR_GL_CALL_NOERRCHECK(this->glInterface(),
- TexImage2D(GR_GL_TEXTURE_2D,
- 0, // level
- internalFormat,
- desc.fWidth, desc.fHeight,
- 0, // border
- externalFormat, externalType,
- data));
+ GL_ALLOC_CALL(this->glInterface(),
+ TexImage2D(GR_GL_TEXTURE_2D,
+ 0, // level
+ internalFormat,
+ desc.fWidth, desc.fHeight,
+ 0, // border
+ externalFormat, externalType,
+ data));
}
}
- GrGLenum error = GR_GL_GET_ERROR(this->glInterface());
+ GrGLenum error = CHECK_ALLOC_ERROR(this->glInterface());
if (error != GR_GL_NO_ERROR) {
succeeded = false;
} else {
@@ -977,13 +986,13 @@
GrAssert(desc->fSampleCnt > 1);
GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER,
desc->fMSColorRenderbufferID));
- GrGLClearErr(this->glInterface());
- GR_GL_CALL_NOERRCHECK(this->glInterface(),
- RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
- desc->fSampleCnt,
- msColorFormat,
- width, height));
- err = GR_GL_GET_ERROR(this->glInterface());
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
+ GL_ALLOC_CALL(this->glInterface(),
+ RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
+ desc->fSampleCnt,
+ msColorFormat,
+ width, height));
+ err = CHECK_ALLOC_ERROR(this->glInterface());
if (err != GR_GL_NO_ERROR) {
goto FAILED;
}
@@ -1196,25 +1205,23 @@
// first (painful) stencil creation.
int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt;
const GrGLStencilBuffer::Format& sFmt = fGLCaps.fStencilFormats[sIdx];
- GrGLClearErr(this->glInterface());
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
// we do this "if" so that we don't call the multisample
// version on a GL that doesn't have an MSAA extension.
if (samples > 1) {
- GR_GL_CALL_NOERRCHECK(this->glInterface(),
- RenderbufferStorageMultisample(
- GR_GL_RENDERBUFFER,
- samples,
- sFmt.fInternalFormat,
- width,
- height));
+ GL_ALLOC_CALL(this->glInterface(),
+ RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
+ samples,
+ sFmt.fInternalFormat,
+ width, height));
} else {
- GR_GL_CALL_NOERRCHECK(this->glInterface(),
- RenderbufferStorage(GR_GL_RENDERBUFFER,
- sFmt.fInternalFormat,
- width, height));
+ GL_ALLOC_CALL(this->glInterface(),
+ RenderbufferStorage(GR_GL_RENDERBUFFER,
+ sFmt.fInternalFormat,
+ width, height));
}
- GrGLenum err = GR_GL_GET_ERROR(this->glInterface());
+ GrGLenum err = CHECK_ALLOC_ERROR(this->glInterface());
if (err == GR_GL_NO_ERROR) {
// After sized formats we attempt an unsized format and take whatever
// sizes GL gives us. In that case we query for the size.
@@ -1302,12 +1309,15 @@
if (id) {
GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, id));
fHWGeometryState.fArrayPtrsDirty = true;
- GrGLClearErr(this->glInterface());
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
// make sure driver can allocate memory for this buffer
- GR_GL_CALL_NOERRCHECK(this->glInterface(),
- BufferData(GR_GL_ARRAY_BUFFER, size, NULL,
- dynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
- if (GR_GL_GET_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
+ GL_ALLOC_CALL(this->glInterface(),
+ BufferData(GR_GL_ARRAY_BUFFER,
+ size,
+ NULL, // data ptr
+ dynamic ? GR_GL_DYNAMIC_DRAW :
+ GR_GL_STATIC_DRAW));
+ if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
GL_CALL(DeleteBuffers(1, &id));
// deleting bound buffer does implicit bind to 0
fHWGeometryState.fVertexBuffer = NULL;
@@ -1326,12 +1336,15 @@
GL_CALL(GenBuffers(1, &id));
if (id) {
GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
- GrGLClearErr(this->glInterface());
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
// make sure driver can allocate memory for this buffer
- GR_GL_CALL_NOERRCHECK(this->glInterface(),
- BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, size, NULL,
- dynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
- if (GR_GL_GET_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
+ GL_ALLOC_CALL(this->glInterface(),
+ BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
+ size,
+ NULL, // data ptr
+ dynamic ? GR_GL_DYNAMIC_DRAW :
+ GR_GL_STATIC_DRAW));
+ if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
GL_CALL(DeleteBuffers(1, &id));
// deleting bound buffer does implicit bind to 0
fHWGeometryState.fIndexBuffer = NULL;