When GL_RGBA readPixels are slow do swizzle using a draw then readPixels with GL_BGRA

Review URL: http://codereview.appspot.com/5339051/


git-svn-id: http://skia.googlecode.com/svn/trunk@2631 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrConfig.h b/include/gpu/GrConfig.h
index 461dee7..bc71792 100644
--- a/include/gpu/GrConfig.h
+++ b/include/gpu/GrConfig.h
@@ -380,6 +380,7 @@
     #define GR_MAX_OFFSCREEN_AA_SIZE    256
 #endif
 
+
 ///////////////////////////////////////////////////////////////////////////////
 // tail section:
 //
diff --git a/include/gpu/GrGLConfig.h b/include/gpu/GrGLConfig.h
index 45b551c..f9a801d 100644
--- a/include/gpu/GrGLConfig.h
+++ b/include/gpu/GrGLConfig.h
@@ -77,6 +77,10 @@
  * It is not extern "C".
  * The GrGLInterface field fCallback specifies the function ptr and there is an
  * additional field fCallbackData of type intptr_t for client data.
+ *
+ * GR_GL_RGBA_8888_READBACK_SLOW: Set this to 1 if it is known that performing
+ * glReadPixels with format=GL_RGBA, type=GL_UNISIGNED_BYTE is significantly 
+ * slower than format=GL_BGRA, type=GL_UNISIGNED_BYTE.
  */
 
 #if !defined(GR_GL_LOG_CALLS)
@@ -111,6 +115,10 @@
     #define GR_GL_PER_GL_FUNC_CALLBACK          0
 #endif
 
+#if !defined(GR_GL_RGBA_8888_READBACK_SLOW)
+    #define GR_GL_RGBA_8888_READBACK_SLOW       0
+#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 d21e2f4..79324ab 100644
--- a/include/gpu/GrGLConfig_chrome.h
+++ b/include/gpu/GrGLConfig_chrome.h
@@ -14,6 +14,9 @@
 // ANGLE creates a temp VB for vertex attributes not specified per-vertex.
 #define GR_GL_NO_CONSTANT_ATTRIBUTES    GR_WIN32_BUILD
 
+// RGBA Readbacks are a slow path in ANGLE
+#define GR_GL_RGBA_8888_READBACK_SLOW   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
diff --git a/include/gpu/GrSamplerState.h b/include/gpu/GrSamplerState.h
index 324472c..9c217db 100644
--- a/include/gpu/GrSamplerState.h
+++ b/include/gpu/GrSamplerState.h
@@ -112,6 +112,7 @@
         fSampleMode = kNormal_SampleMode;
         fFilter = filter;
         fMatrix.setIdentity();
+        fSwapRAndB = false;
         fTextureDomain.setEmpty();
     }
 
@@ -125,6 +126,7 @@
         fSampleMode = kNormal_SampleMode;
         fFilter = filter;
         fMatrix = matrix;
+        fSwapRAndB = false;
         fTextureDomain.setEmpty();
     }
 
@@ -138,6 +140,7 @@
         fSampleMode = sample;
         fMatrix = matrix;
         fFilter = filter;
+        fSwapRAndB = false;
         fTextureDomain.setEmpty();
     }
 
@@ -151,6 +154,7 @@
     int getKernelWidth() const { return fKernelWidth; }
     const float* getKernel() const { return fKernel; }
     const float* getImageIncrement() const { return fImageIncrement; }
+    bool swapsRAndB() const { return fSwapRAndB; }
 
     bool isGradient() const {
         return  kRadial_SampleMode == fSampleMode ||
@@ -177,6 +181,12 @@
     void setTextureDomain(const GrRect& textureDomain) { fTextureDomain = textureDomain; }
 
     /**
+     * Swaps the R and B components when reading from the texture. Has no effect
+     * if the texture is alpha only.
+     */
+    void setRAndBSwap(bool swap) { fSwapRAndB = swap; }
+
+    /**
      *  Multiplies the current sampler matrix  a matrix
      *
      *  After this call M' = M*m where M is the old matrix, m is the parameter
@@ -201,6 +211,7 @@
         fFilter = kNearest_Filter;
         fMatrix.setIdentity();
         fTextureDomain.setEmpty();
+        fSwapRAndB = false;
     }
 
     GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
@@ -246,6 +257,7 @@
     SampleMode  fSampleMode;
     Filter      fFilter;
     GrMatrix    fMatrix;
+    bool        fSwapRAndB;
     GrRect      fTextureDomain;
 
     // these are undefined unless fSampleMode == kRadial2_SampleMode
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index 36ad9e0..1986a4e 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -319,6 +319,60 @@
 // has a different interpretation when skia is compiled BGRA.
 static const GrPixelConfig kRGBA_8888_GrPixelConfig = kSkia8888_PM_GrPixelConfig;
 
+// Returns true if the pixel config has 8bit r,g,b,a components in that byte
+// order
+static inline bool GrPixelConfigIsRGBA8888(GrPixelConfig config) {
+    switch (config) {
+        case kRGBA_8888_PM_GrPixelConfig:
+        case kRGBA_8888_UPM_GrPixelConfig:
+            return true;
+        default:
+            return false;
+    }
+}
+
+// Returns true if the pixel config has 8bit b,g,r,a components in that byte
+// order
+static inline bool GrPixelConfigIsBGRA8888(GrPixelConfig config) {
+    switch (config) {
+        case kBGRA_8888_PM_GrPixelConfig:
+        case kBGRA_8888_UPM_GrPixelConfig:
+            return true;
+        default:
+            return false;
+    }
+}
+
+// Returns true if the pixel config is 32 bits per pixel
+static inline bool GrPixelConfigIs32Bit(GrPixelConfig config) {
+    switch (config) {
+        case kRGBA_8888_PM_GrPixelConfig:
+        case kRGBA_8888_UPM_GrPixelConfig:
+        case kBGRA_8888_PM_GrPixelConfig:
+        case kBGRA_8888_UPM_GrPixelConfig:
+            return true;
+        default:
+            return false;
+    }
+}
+
+// Takes a config and returns the equivalent config with the R and B order
+// swapped if such a config exists. Otherwise, kUnknown_GrPixelConfig
+static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
+    switch (config) {
+        case kBGRA_8888_PM_GrPixelConfig:
+            return kRGBA_8888_PM_GrPixelConfig;
+        case kBGRA_8888_UPM_GrPixelConfig:
+            return kRGBA_8888_UPM_GrPixelConfig;
+        case kRGBA_8888_PM_GrPixelConfig:
+            return kBGRA_8888_PM_GrPixelConfig;
+        case kRGBA_8888_UPM_GrPixelConfig:
+            return kBGRA_8888_UPM_GrPixelConfig;
+        default:
+            return kUnknown_GrPixelConfig;
+    }
+}
+
 static inline size_t GrBytesPerPixel(GrPixelConfig config) {
     switch (config) {
         case kAlpha_8_GrPixelConfig: