Re-adding red texture support (by rolling back r3800)
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 30 Apr 2012 20:01:21 +0000 (20:01 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 30 Apr 2012 20:01:21 +0000 (20:01 +0000)
http://code.google.com/p/skia/source/detail?r=3622 - for original review
http://crbug.com/125596 ('M20 windows renderer stability maze') - for issue

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

gyp/tests.gyp
include/gpu/gl/GrGLDefines.h
src/gpu/gl/GrGLCaps.cpp
src/gpu/gl/GrGLCaps.h
src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgram.h
src/gpu/gl/GrGpuGL.cpp
src/gpu/gl/GrGpuGLShaders.cpp

index aea125a2266ee0e26c333ee10875583d8c37a4cb..58039ba6c77ce1c196600388981ab46aab73e05f 100644 (file)
@@ -59,6 +59,7 @@
         '../tests/QuickRejectTest.cpp',
         '../tests/Reader32Test.cpp',
         '../tests/ReadPixelsTest.cpp',
+        '../tests/ReadWriteAlphaTest.cpp',
         '../tests/RefDictTest.cpp',
         '../tests/RegionTest.cpp',
         '../tests/ScalarTest.cpp',
index af8c2a898bec5f30114de7659f8df72ee07120d2..0e03b556f1424dbb27a935727102ebbf2ad58813 100644 (file)
 #define GR_GL_PALETTE8_RGBA8                 0x8B96
 #define GR_GL_ALPHA8                         0x803C
 
+#define GR_GL_R8                             0x8229
+
 /* PixelType */
 /*      GL_UNSIGNED_BYTE */
 #define GR_GL_UNSIGNED_SHORT_4_4_4_4         0x8033
index d40cf604aceddcc40aabcb2255054662998adf5d..797abb4d80e9b5f246fa2d202eadf510f52beabe 100644 (file)
@@ -33,6 +33,7 @@ void GrGLCaps::reset() {
     fPackFlipYSupport = false;
     fTextureUsageSupport = false;
     fTexStorageSupport = false;
+    fTextureRedSupport = false;
 }
 
 GrGLCaps::GrGLCaps(const GrGLCaps& caps) {
@@ -58,6 +59,7 @@ GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) {
     fPackFlipYSupport = caps.fPackFlipYSupport;
     fTextureUsageSupport = caps.fTextureUsageSupport;
     fTexStorageSupport = caps.fTexStorageSupport;
+    fTextureRedSupport = caps.fTextureRedSupport;
 
     return *this;
 }
@@ -135,6 +137,14 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo) {
                          ctxInfo.hasExtension("GL_ARB_texture_storage") ||
                          ctxInfo.hasExtension("GL_EXT_texture_storage");
 
+    // ARB_texture_rg is part of OpenGL 3.0
+    if (kDesktop_GrGLBinding == binding) {
+        fTextureRedSupport = version >= GR_GL_VER(3,0) ||
+                             ctxInfo.hasExtension("GL_ARB_texture_rg");
+    } else {
+        fTextureRedSupport = ctxInfo.hasExtension("GL_EXT_texture_rg");
+    }
+
     this->initFSAASupport(ctxInfo);
     this->initStencilFormats(ctxInfo);
 }
index c5d1d05007164b44770b91a66935193cd58d4c2e..eb095765c688a59100fac52e3233802dfd249c57 100644 (file)
@@ -206,6 +206,9 @@ public:
     /// Is there support for glTexStorage
     bool texStorageSupport() const { return fTexStorageSupport; }
 
+    /// Is there support for GL_RED and GL_R8
+    bool textureRedSupport() const { return fTextureRedSupport; }
+
 private:
     /**
      * Maintains a bit per GrPixelConfig. It is used to avoid redundantly
@@ -273,6 +276,7 @@ private:
     bool fPackFlipYSupport : 1;
     bool fTextureUsageSupport : 1;
     bool fTexStorageSupport : 1;
+    bool fTextureRedSupport : 1;
 };
 
 #endif
index cb90ac6a72028e537bca603e888fe31b96a3fdc4..3e1f1d40c274ff3013a758312cc1bf77dcf015b7 100644 (file)
@@ -1942,11 +1942,17 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
     const char* swizzle = "";
     if (desc.fInConfigFlags & StageDesc::kSwapRAndB_InConfigFlag) {
         GrAssert(!(desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag));
+        GrAssert(!(desc.fInConfigFlags & StageDesc::kSmearRed_InConfigFlag));
         swizzle = ".bgra";
     } else if (desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag) {
         GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
+        GrAssert(!(desc.fInConfigFlags & StageDesc::kSmearRed_InConfigFlag));
         swizzle = ".aaaa";
-    } 
+    } else if (desc.fInConfigFlags & StageDesc::kSmearRed_InConfigFlag) {
+        GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
+        GrAssert(!(desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag));
+        swizzle = ".rrrr";
+    }
 
     GrStringBuilder modulate;
     if (NULL != fsInColor) {
@@ -1996,6 +2002,8 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
             GrAssert(GrIsPow2(kMulByAlphaMask & desc.fInConfigFlags));
             GrAssert(!(desc.fInConfigFlags & 
                        StageDesc::kSmearAlpha_InConfigFlag));
+            GrAssert(!(desc.fInConfigFlags & 
+                       StageDesc::kSmearRed_InConfigFlag));
             segments->fFSCode.appendf("\t%s = %s(%s, %s)%s;\n",
                                       fsOutColor, texFunc.c_str(), 
                                       samplerName, sampleCoords.c_str(),
index 91ee95cd936f8db7c58fd6a13c29dc1a25f4c4c4..73bfa949a6161becda4e0ffecc9813cf5711bde7 100644 (file)
@@ -122,7 +122,7 @@ public:
               described are performed after reading a texel.
              */
             enum InConfigFlags {
-                kNone_InConfigFlag                      = 0x0,
+                kNone_InConfigFlag                      = 0x00,
 
                 /**
                   Swap the R and B channels. This is incompatible with
@@ -130,15 +130,24 @@ public:
                   the shader using GL_ARB_texture_swizzle if possible rather
                   than setting this flag.
                  */
-                kSwapRAndB_InConfigFlag                 = 0x1,
+                kSwapRAndB_InConfigFlag                 = 0x01,
 
                 /**
                  Smear alpha across all four channels. This is incompatible with
-                 kSwapRAndB and kMulRGBByAlpha*. It is prefereable to perform
-                 the smear outside the shader using GL_ARB_texture_swizzle if
-                 possible rather than setting this flag.
+                 kSwapRAndB, kMulRGBByAlpha* and kSmearRed. It is prefereable 
+                 to perform the smear outside the shader using 
+                 GL_ARB_texture_swizzle if possible rather than setting this 
+                 flag.
                 */
-                kSmearAlpha_InConfigFlag                = 0x2,
+                kSmearAlpha_InConfigFlag                = 0x02,
+
+                /**
+                 Smear the red channel across all four channels. This flag is 
+                 incompatible with kSwapRAndB, kMulRGBByAlpha*and kSmearAlpha. 
+                 It is preferable to use GL_ARB_texture_swizzle instead of this 
+                 flag.
+                */
+                kSmearRed_InConfigFlag                  = 0x04,
 
                 /**
                  Multiply r,g,b by a after texture reads. This flag incompatible
@@ -149,8 +158,8 @@ public:
                  of 1/255.0 and the other rounds down. At most one of these
                  flags may be set.
                  */
-                kMulRGBByAlpha_RoundUp_InConfigFlag     =  0x4,
-                kMulRGBByAlpha_RoundDown_InConfigFlag   =  0x8,
+                kMulRGBByAlpha_RoundUp_InConfigFlag     =  0x08,
+                kMulRGBByAlpha_RoundDown_InConfigFlag   =  0x10,
 
                 kDummyInConfigFlag,
                 kInConfigBitMask = (kDummyInConfigFlag-1) |
index 5f8772e6e5f3bd1f1432e17cb54c603a16d5863e..3b5fffe7ef02a2eb82a5b1554c7f97c1568dacc8 100644 (file)
@@ -322,7 +322,8 @@ void GrGpuGL::fillInConfigRenderableTable() {
         }
     } else {
         // On ES we can only hope for R8
-        fConfigRenderSupport[kAlpha_8_GrPixelConfig] = false;
+        fConfigRenderSupport[kAlpha_8_GrPixelConfig] = 
+                                this->glCaps().textureRedSupport();
     }
 
     if (kDesktop_GrGLBinding != this->glBinding()) {
@@ -2043,12 +2044,20 @@ unsigned gr_to_gl_filter(GrSamplerState::Filter filter) {
     }
 }
 
-const GrGLenum* get_swizzle(GrPixelConfig config,
-                            const GrSamplerState& sampler) {
+// get_swizzle is only called from this .cpp so it is OK to inline it here
+inline const GrGLenum* get_swizzle(GrPixelConfig config,
+                                   const GrSamplerState& sampler,
+                                   const GrGLCaps& glCaps) {
     if (GrPixelConfigIsAlphaOnly(config)) {
-        static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
-                                                GR_GL_ALPHA, GR_GL_ALPHA };
-        return gAlphaSmear;
+        if (glCaps.textureRedSupport()) {
+            static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED,
+                                                  GR_GL_RED, GR_GL_RED };
+            return gRedSmear;
+        } else {
+            static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
+                                                    GR_GL_ALPHA, GR_GL_ALPHA };
+            return gAlphaSmear;
+        }
     } else if (sampler.swapsRAndB()) {
         static const GrGLenum gRedBlueSwap[] = { GR_GL_BLUE, GR_GL_GREEN,
                                                  GR_GL_RED,  GR_GL_ALPHA };
@@ -2128,7 +2137,7 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
             newTexParams.fWrapS = wraps[sampler.getWrapX()];
             newTexParams.fWrapT = wraps[sampler.getWrapY()];
             memcpy(newTexParams.fSwizzleRGBA,
-                   get_swizzle(nextTexture->config(), sampler),
+                   get_swizzle(nextTexture->config(), sampler, this->glCaps()),
                    sizeof(newTexParams.fSwizzleRGBA));
             if (setAll || newTexParams.fFilter != oldTexParams.fFilter) {
                 setTextureUnit(s);
@@ -2370,14 +2379,25 @@ bool GrGpuGL::configToGLFormats(GrPixelConfig config,
             }
             break;
         case kAlpha_8_GrPixelConfig:
-            *internalFormat = GR_GL_ALPHA;
-            *externalFormat = GR_GL_ALPHA;
-            if (getSizedInternalFormat) {
-                *internalFormat = GR_GL_ALPHA8;
+            if (this->glCaps().textureRedSupport()) {
+                *internalFormat = GR_GL_RED;
+                *externalFormat = GR_GL_RED;
+                if (getSizedInternalFormat) {
+                    *internalFormat = GR_GL_R8;
+                } else {
+                    *internalFormat = GR_GL_RED;
+                }
+                *externalType = GR_GL_UNSIGNED_BYTE;
             } else {
                 *internalFormat = GR_GL_ALPHA;
+                *externalFormat = GR_GL_ALPHA;
+                if (getSizedInternalFormat) {
+                    *internalFormat = GR_GL_ALPHA8;
+                } else {
+                    *internalFormat = GR_GL_ALPHA;
+                }
+                *externalType = GR_GL_UNSIGNED_BYTE;
             }
-            *externalType = GR_GL_UNSIGNED_BYTE;
             break;
         default:
             return false;
index 88c81ab3374a9bc2f7be63a3680cb8cf92241523..1fcfbbee2bdcb3687185524678194e6aa52306a6 100644 (file)
@@ -181,6 +181,7 @@ bool GrGpuGLShaders::programUnitTest() {
         StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag,
         StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag,
         StageDesc::kSmearAlpha_InConfigFlag,
+        StageDesc::kSmearRed_InConfigFlag,
     };
     GrGLProgram program;
     ProgramDesc& pdesc = program.fProgramDesc;
@@ -276,6 +277,7 @@ bool GrGpuGLShaders::programUnitTest() {
             static const uint32_t kMulByAlphaMask =
                 StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag |
                 StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag;
+
             switch (stage.fFetchMode) {
                 case StageDesc::kSingle_FetchMode:
                     stage.fKernelWidth = 0;
@@ -1170,9 +1172,17 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
             if (!this->glCaps().textureSwizzleSupport()) {
                 if (GrPixelConfigIsAlphaOnly(texture->config())) {
                     // if we don't have texture swizzle support then
-                    // the shader must do an alpha smear after reading
-                    // the texture
-                    stage.fInConfigFlags |= StageDesc::kSmearAlpha_InConfigFlag;
+                    // the shader must smear the single channel after
+                    // reading the texture
+                    if (this->glCaps().textureRedSupport()) {
+                        // we can use R8 textures so use kSmearRed
+                        stage.fInConfigFlags |= 
+                                        StageDesc::kSmearRed_InConfigFlag;
+                    } else {
+                        // we can use A8 textures so use kSmearAlpha
+                        stage.fInConfigFlags |= 
+                                        StageDesc::kSmearAlpha_InConfigFlag;
+                    }
                 } else if (sampler.swapsRAndB()) {
                     stage.fInConfigFlags |= StageDesc::kSwapRAndB_InConfigFlag;
                 }