Caching the result of readPixelsSupported

The call was calling GR_GL_GetIntegerv 2 times for each readPixels
and thus was causing a loss of performance

(resubmit of issue 344793008)

Benchmark url: http://packages.gkny.fr/tst/index.html

BUG=skia:2681

Committed: https://skia.googlesource.com/skia/+/753a2964afe5661ce9b2a8ca77ca9d0aabd3173c

Committed: https://skia.googlesource.com/skia/+/8339371f1ec3c57a0741932fd96bff32c53d4e54

Review URL: https://codereview.chromium.org/364193004
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 887e2e9..eb56798 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -11,8 +11,9 @@
 
 #include "GrDrawTargetCaps.h"
 #include "GrGLStencilBuffer.h"
+#include "SkChecksum.h"
+#include "SkTHashCache.h"
 #include "SkTArray.h"
-#include "SkTDArray.h"
 
 class GrGLContextInfo;
 
@@ -252,7 +253,8 @@
     /// Does ReadPixels support the provided format/type combo?
     bool readPixelsSupported(const GrGLInterface* intf,
                              GrGLenum format,
-                             GrGLenum type) const;
+                             GrGLenum type,
+                             GrGLenum currFboFormat) const;
 
     bool isCoreProfile() const { return fIsCoreProfile; }
 
@@ -323,6 +325,10 @@
     void initConfigRenderableTable(const GrGLContextInfo&);
     void initConfigTexturableTable(const GrGLContextInfo&, const GrGLInterface*);
 
+    bool doReadPixelsSupported(const GrGLInterface* intf,
+                                   GrGLenum format,
+                                   GrGLenum type) const;
+
     // tracks configs that have been verified to pass the FBO completeness when
     // used as a color attachment
     VerifiedColorConfigs fVerifiedColorConfigs;
@@ -366,6 +372,46 @@
     const char* fFBFetchColorName;
     const char* fFBFetchExtensionString;
 
+    class ReadPixelsSupportedFormats {
+    public:
+        struct Key {
+            GrGLenum fFormat;
+            GrGLenum fType;
+            GrGLenum fFboFormat;
+
+            bool operator==(const Key& rhs) const {
+                return fFormat == rhs.fFormat
+                        && fType == rhs.fType
+                        && fFboFormat == rhs.fFboFormat;
+            }
+
+            uint32_t getHash() const {
+                return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), sizeof(*this));
+            }
+        };
+
+        ReadPixelsSupportedFormats(Key key, bool value) : fKey(key), fValue(value) {
+        }
+
+        static const Key& GetKey(const ReadPixelsSupportedFormats& element) {
+            return element.fKey;
+        }
+
+        static uint32_t Hash(const Key& key) {
+            return key.getHash();
+        }
+
+        bool value() const {
+            return fValue;
+        }
+    private:
+        Key fKey;
+        bool fValue;
+    };
+
+    mutable SkTHashCache<ReadPixelsSupportedFormats,
+                         ReadPixelsSupportedFormats::Key> fReadPixelsSupportedCache;
+
     typedef GrDrawTargetCaps INHERITED;
 };