Added ReadPixels format-supported check to GL Caps

http://codereview.appspot.com/6336055/



git-svn-id: http://skia.googlecode.com/svn/trunk@4374 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index ec125b7..125e387 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -35,6 +35,7 @@
     fTexStorageSupport = false;
     fTextureRedSupport = false;
     fImagingSupport = false;
+    fTwoFormatLimit = false;
 }
 
 GrGLCaps::GrGLCaps(const GrGLCaps& caps) {
@@ -63,6 +64,7 @@
     fTexStorageSupport = caps.fTexStorageSupport;
     fTextureRedSupport = caps.fTextureRedSupport;
     fImagingSupport = caps.fImagingSupport;
+    fTwoFormatLimit = caps.fTwoFormatLimit;
 
     return *this;
 }
@@ -151,10 +153,44 @@
     fImagingSupport = kDesktop_GrGLBinding == binding &&
                       ctxInfo.hasExtension("GL_ARB_imaging");
 
+    // ES 2 only guarantees RGBA/uchar + one other format/type combo for
+    // ReadPixels. The other format has to checked at run-time since it
+    // can change based on which render target is bound
+    fTwoFormatLimit = kES2_GrGLBinding == binding;
+
     this->initFSAASupport(ctxInfo);
     this->initStencilFormats(ctxInfo);
 }
 
+bool GrGLCaps::readPixelsSupported(const GrGLInterface* intf,
+                                   GrGLenum format, 
+                                   GrGLenum type) const { 
+    if (GR_GL_RGBA == format && GR_GL_UNSIGNED_BYTE == type) {
+        // ES 2 guarantees this format is supported
+        true;
+    }
+
+    if (!fTwoFormatLimit) {
+        // not limited by ES 2's constraints
+        return true;
+    }
+
+    int otherFormat = GR_GL_RGBA;
+    int otherType = GR_GL_UNSIGNED_BYTE;
+
+    // The other supported format/type combo supported for ReadPixels
+    // can change based on which render target is bound
+    GR_GL_GetIntegerv(intf, 
+                      GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT,
+                      &otherFormat);
+
+    GR_GL_GetIntegerv(intf, 
+                      GR_GL_IMPLEMENTATION_COLOR_READ_TYPE,
+                      &otherType);
+
+    return otherFormat == format && otherType == type; 
+}
+
 namespace {
 int coverage_mode_compare(const GrGLCaps::MSAACoverageMode* left,
                           const GrGLCaps::MSAACoverageMode* right) {
@@ -378,5 +414,6 @@
              (fPackRowLengthSupport ? "YES": "NO"));
     GrPrintf("Pack Flip Y support: %s\n",
              (fPackFlipYSupport ? "YES": "NO"));
+    GrPrintf("Two Format Limit: %s\n", (fTwoFormatLimit ? "YES": "NO"));
 }
 
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index ec75a53..322e733 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -214,6 +214,11 @@
     /// Is GL_ARB_IMAGING supported
     bool imagingSupport() const { return fImagingSupport; }
 
+    // Does ReadPixels support the provided format/type combo?
+    bool readPixelsSupported(const GrGLInterface* intf,
+                             GrGLenum format, 
+                             GrGLenum type) const;
+
 private:
     /**
      * Maintains a bit per GrPixelConfig. It is used to avoid redundantly
@@ -285,6 +290,7 @@
     bool fTexStorageSupport : 1;
     bool fTextureRedSupport : 1;
     bool fImagingSupport  : 1;
+    bool fTwoFormatLimit : 1;
 };
 
 #endif