Updated blur to use A8/R8 (instead of RGBA8) when available - this provides a perform...
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 10 Apr 2012 19:26:38 +0000 (19:26 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 10 Apr 2012 19:26:38 +0000 (19:26 +0000)
http://codereview.appspot.com/5988071/

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

include/gpu/GrContext.h
src/gpu/GrContext.cpp
src/gpu/GrGpu.cpp
src/gpu/GrGpu.h
src/gpu/SkGpuDevice.cpp
src/gpu/gl/GrGLCaps.cpp
src/gpu/gl/GrGpuGL.cpp
src/gpu/gl/GrGpuGL.h

index bed2d99..433c113 100644 (file)
@@ -274,6 +274,11 @@ public:
     const GrRenderTarget* getRenderTarget() const;
     GrRenderTarget* getRenderTarget();
 
+    /**
+     * Can the provided configuration act as a color render target?
+     */
+    bool isConfigRenderable(GrPixelConfig config) const;
+
     ///////////////////////////////////////////////////////////////////////////
     // Platform Surfaces
 
index f044909..3fb944b 100644 (file)
@@ -1989,6 +1989,10 @@ const GrRenderTarget* GrContext::getRenderTarget() const {
     return fDrawState->getRenderTarget();
 }
 
+bool GrContext::isConfigRenderable(GrPixelConfig config) const {
+    return fGpu->isConfigRenderable(config);
+}
+
 const GrMatrix& GrContext::getMatrix() const {
     return fDrawState->getViewMatrix();
 }
@@ -2112,16 +2116,22 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
                          static_cast<float>(scaleFactorY));
     this->setClip(srcRect);
 
+    GrAssert(kBGRA_8888_PM_GrPixelConfig == srcTexture->config() ||
+             kRGBA_8888_PM_GrPixelConfig == srcTexture->config() ||
+             kAlpha_8_GrPixelConfig == srcTexture->config());
+
     const GrTextureDesc desc = {
         kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit,
         SkScalarFloorToInt(srcRect.width()),
         SkScalarFloorToInt(srcRect.height()),
-        kRGBA_8888_PM_GrPixelConfig,
+        srcTexture->config(), 
         0 // samples 
     };
 
     temp1->set(this, desc);
-    if (temp2) temp2->set(this, desc);
+    if (temp2) {
+        temp2->set(this, desc);
+    }
 
     GrTexture* dstTexture = temp1->texture();
     GrPaint paint;
@@ -2160,7 +2170,9 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
         convolve(fGpu, srcTexture, srcRect, kernelX, kernelWidthX,
                  GrSamplerState::kX_FilterDirection);
         SkTSwap(srcTexture, dstTexture);
-        if (temp2 && dstTexture == origTexture) dstTexture = temp2->texture();
+        if (temp2 && dstTexture == origTexture) {
+            dstTexture = temp2->texture();
+        }
     }
 
     if (sigmaY > 0.0f) {
@@ -2180,7 +2192,9 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
         convolve(fGpu, srcTexture, srcRect, kernelY, kernelWidthY,
                  GrSamplerState::kY_FilterDirection);
         SkTSwap(srcTexture, dstTexture);
-        if (temp2 && dstTexture == origTexture) dstTexture = temp2->texture();
+        if (temp2 && dstTexture == origTexture) {
+            dstTexture = temp2->texture();
+        }
     }
 
     if (scaleFactorX > 1 || scaleFactorY > 1) {
index aeb104c..57e73c4 100644 (file)
@@ -57,6 +57,10 @@ GrGpu::GrGpu()
     poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
 #endif
     resetStats();
+
+    for (int i = 0; i < kGrPixelConfigCount; ++i) {
+        fConfigRenderSupport[i] = false;
+    };
 }
 
 GrGpu::~GrGpu() {
index 52282ed..4a986b1 100644 (file)
@@ -333,6 +333,14 @@ public:
         return fResetTimestamp;
     }
 
+    /**
+     * Can the provided configuration act as a color render target?
+     */
+    bool isConfigRenderable(GrPixelConfig config) const {
+        GrAssert(kGrPixelConfigCount > config); 
+        return fConfigRenderSupport[config];
+    }
+
 protected:
     enum PrivateDrawStateStateBits {
         kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
@@ -377,6 +385,10 @@ protected:
         return fGeomPoolStateStack.back(); 
     }
 
+    // Derived classes need access to this so they can fill it out in their
+    // constructors
+    bool    fConfigRenderSupport[kGrPixelConfigCount];
+
     // GrDrawTarget overrides
     virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
                                       int vertexCount,
index cf05284..bb088b2 100644 (file)
@@ -788,16 +788,20 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
     }
     GrPoint offset = GrPoint::Make(-srcRect.fLeft, -srcRect.fTop);
     srcRect.offset(offset);
-    const GrTextureDesc desc = {
+    GrTextureDesc desc = {
         kRenderTarget_GrTextureFlagBit,
         SkScalarCeilToInt(srcRect.width()),
         SkScalarCeilToInt(srcRect.height()),
         // We actually only need A8, but it often isn't supported as a
-        // render target
+        // render target so default to RGBA_8888
         kRGBA_8888_PM_GrPixelConfig,
         0 // samples
     };
 
+    if (context->isConfigRenderable(kAlpha_8_GrPixelConfig)) {
+        desc.fConfig = kAlpha_8_GrPixelConfig;
+    }
+
     GrAutoScratchTexture pathEntry(context, desc);
     GrTexture* pathTexture = pathEntry.texture();
     if (NULL == pathTexture) {
index 8b14a1b..5361967 100644 (file)
@@ -136,7 +136,7 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo) {
         fTextureRedSupport = version >= GR_GL_VER(3,0) ||
                              ctxInfo.hasExtension("GL_ARB_texture_rg");
     } else {
-        fTextureRedSupport = ctxInfo.hasExtension("GL_ARB_texture_rg");
+        fTextureRedSupport = ctxInfo.hasExtension("GL_EXT_texture_rg");
     }
 
     this->initFSAASupport(ctxInfo);
index 8481b74..dcde84e 100644 (file)
@@ -181,6 +181,8 @@ GrGpuGL::GrGpuGL(const GrGLContextInfo& ctxInfo) : fGLContextInfo(ctxInfo) {
 
     GrAssert(ctxInfo.isInitialized());
 
+    fillInConfigRenderableTable();
+
     fPrintedCaps = false;
 
     GrGLClearErr(fGLContextInfo.interface());
@@ -293,6 +295,71 @@ void GrGpuGL::initCaps() {
     fCaps.fFSAASupport = GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType();
 }
 
+void GrGpuGL::fillInConfigRenderableTable() {
+
+    // OpenGL < 3.0
+    //  no support for render targets unless the GL_ARB_framebuffer_object 
+    //  extension is supported (in which case we get ALPHA, RED, RG, RGB, 
+    //  RGBA (ALPHA8, RGBA4, RGBA8) for OpenGL > 1.1). Note that we 
+    //  probably don't get R8 in this case.
+
+    // OpenGL 3.0
+    //  base color renderable: ALPHA, RED, RG, RGB, and RGBA
+    //  sized derivatives: ALPHA8, R8, RGBA4, RGBA8
+
+    // >= OpenGL 3.1
+    //  base color renderable: RED, RG, RGB, and RGBA
+    //  sized derivatives: R8, RGBA4, RGBA8
+    //  if the GL_ARB_compatibility extension is supported then we get back
+    //  support for GL_ALPHA and ALPHA8
+
+    // GL_EXT_bgra adds BGRA render targets to any version
+
+    // ES 2.0
+    //  color renderable: RGBA4, RGB5_A1, RGB565
+    //  GL_EXT_texture_rg adds support for R8 as a color render target
+    //  GL_OES_rgb8_rgba8 and/or GL_ARM_rgba8 adds support for RGBA8
+    //  GL_EXT_texture_format_BGRA8888 and/or GL_APPLE_texture_format_BGRA8888
+    //          added BGRA support
+
+    if (kDesktop_GrGLBinding == this->glBinding()) {
+        // Post 3.0 we will get R8
+        // Prior to 3.0 we will get ALPHA8 (with GL_ARB_framebuffer_object)
+        if (this->glVersion() >= GR_GL_VER(3,0) ||
+            this->hasExtension("GL_ARB_framebuffer_object")) {
+            fConfigRenderSupport[kAlpha_8_GrPixelConfig] = true;
+        }
+    } else {
+        // On ES we can only hope for R8
+        fConfigRenderSupport[kAlpha_8_GrPixelConfig] = 
+                                this->glCaps().textureRedSupport();
+    }
+
+    if (kDesktop_GrGLBinding != this->glBinding()) {
+        // only available in ES
+        fConfigRenderSupport[kRGB_565_GrPixelConfig] = true;
+    }
+
+    // Pre 3.0, Ganesh relies on either GL_ARB_framebuffer_object or 
+    // GL_EXT_framebuffer_object for FBO support. Both of these
+    // allow RGBA4 render targets so this is always supported.
+    fConfigRenderSupport[kRGBA_4444_GrPixelConfig] = true;
+
+    if (this->glCaps().rgba8RenderbufferSupport()) {
+        fConfigRenderSupport[kRGBA_8888_PM_GrPixelConfig] = true;
+    }
+
+    if (this->glCaps().bgraFormatSupport()) {
+        fConfigRenderSupport[kBGRA_8888_PM_GrPixelConfig] = true;
+    }
+
+    // the un-premultiplied formats just inherit the premultiplied setting
+    fConfigRenderSupport[kRGBA_8888_UPM_GrPixelConfig] = 
+                fConfigRenderSupport[kRGBA_8888_PM_GrPixelConfig];
+    fConfigRenderSupport[kBGRA_8888_UPM_GrPixelConfig] = 
+                fConfigRenderSupport[kBGRA_8888_PM_GrPixelConfig];
+}
+
 bool GrGpuGL::canPreserveReadWriteUnpremulPixels() {
     if (kUnknown_CanPreserveUnpremulRoundtrip ==
         fCanPreserveUnpremulRoundtrip) {
index 398a2fc..928b50e 100644 (file)
@@ -233,6 +233,8 @@ private:
                                    GrGLuint texID,
                                    GrGLRenderTarget::Desc* desc);
 
+    void fillInConfigRenderableTable();
+
     friend class GrGLVertexBuffer;
     friend class GrGLIndexBuffer;
     friend class GrGLTexture;