Add flag to disable gl error checking when allocating gpu objects
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 19 Jan 2012 16:16:52 +0000 (16:16 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 19 Jan 2012 16:16:52 +0000 (16:16 +0000)
Review URL: http://codereview.appspot.com/5558052/

git-svn-id: http://skia.googlecode.com/svn/trunk@3075 2bbb7eff-a529-9590-31e7-b0007b416f81

include/gpu/GrGLConfig.h
include/gpu/GrGLConfig_chrome.h
src/gpu/GrGpuGL.cpp

index c9aaec5ade31d6b7edb1f66e2a5312490dc47f41..167c8eb0728c8ca86258654dbdbd5a9e2afb1773 100644 (file)
  * 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)
     #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
index ee3c991489e44deb5939a4bc77ff8e43d58315c3..2bae14579e9d519b026652a9252323e69ce9a2d5 100644 (file)
@@ -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
index d0fb12fe1566e1faf46ce2f714da20817a78adb3..f1bc63dac4c4f2c49b48b4554f25d64cb908bd70 100644 (file)
@@ -24,6 +24,16 @@ static const int SPARE_TEX_UNIT = GrDrawState::kNumStages;
 
 #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 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
     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 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
         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 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
         // 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 @@ GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(uint32_t size, bool dynamic) {
     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 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) {
     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;