Make filterMaskGPU use GrTextureProxy
authorRobert Phillips <robertphillips@google.com>
Wed, 14 Dec 2016 14:00:07 +0000 (09:00 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 14 Dec 2016 14:48:19 +0000 (14:48 +0000)
This is a staging CL to position the writePixels in sw_draw_with_mask_filter to be moved to GrSurfaceContext

Change-Id: I808372d30ad4aca4a56125ea75d071f7a3747146
Reviewed-on: https://skia-review.googlesource.com/5926
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>

include/core/SkMaskFilter.h
src/core/SkMaskFilter.cpp
src/effects/SkBlurMaskFilter.cpp
src/effects/SkShadowMaskFilter.cpp
src/gpu/GrBlurUtils.cpp

index 2d00477..198cf37 100644 (file)
@@ -23,6 +23,7 @@ class GrPaint;
 class GrFragmentProcessor;
 class GrRenderTarget;
 class GrTexture;
+class GrTextureProxy;
 class GrTextureProvider;
 class SkBitmap;
 class SkBlitter;
@@ -141,10 +142,10 @@ public:
      * Implementations are free to get the GrContext from the src texture in order to create
      * additional textures and perform multiple passes.
      */
-    virtual bool filterMaskGPU(GrTexture* src,
-                               const SkMatrix& ctm,
-                               const SkIRect& maskRect,
-                               GrTexture** result) const;
+    virtual sk_sp<GrTextureProxy> filterMaskGPU(GrContext*,
+                                                sk_sp<GrTextureProxy> srcProxy,
+                                                const SkMatrix& ctm,
+                                                const SkIRect& maskRect) const;
 #endif
 
     /**
index aff95f0..85ee38d 100644 (file)
@@ -17,6 +17,7 @@
 
 #if SK_SUPPORT_GPU
 #include "GrTexture.h"
+#include "GrTextureProxy.h"
 #include "SkGr.h"
 #endif
 
@@ -335,11 +336,11 @@ bool SkMaskFilter::directFilterRRectMaskGPU(GrContext*,
     return false;
 }
 
-bool SkMaskFilter::filterMaskGPU(GrTexture* src,
-                                 const SkMatrix& ctm,
-                                 const SkIRect& maskRect,
-                                 GrTexture** result) const {
-    return false;
+sk_sp<GrTextureProxy> SkMaskFilter::filterMaskGPU(GrContext*,
+                                                  sk_sp<GrTextureProxy> srcProxy,
+                                                  const SkMatrix& ctm,
+                                                  const SkIRect& maskRect) const {
+    return nullptr;
 }
 #endif
 
index 0b1d1db..84d9e18 100644 (file)
@@ -24,6 +24,7 @@
 #include "GrInvariantOutput.h"
 #include "GrShaderCaps.h"
 #include "GrStyle.h"
+#include "GrTextureProxy.h"
 #include "effects/GrSimpleTextureEffect.h"
 #include "glsl/GrGLSLFragmentProcessor.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
@@ -64,10 +65,10 @@ public:
                                   const SkStrokeRec& strokeRec,
                                   const SkRRect& rrect,
                                   const SkRRect& devRRect) const override;
-    bool filterMaskGPU(GrTexture* src,
-                       const SkMatrix& ctm,
-                       const SkIRect& maskRect,
-                       GrTexture** result) const override;
+    sk_sp<GrTextureProxy> filterMaskGPU(GrContext*,
+                                        sk_sp<GrTextureProxy> srcProxy,
+                                        const SkMatrix& ctm,
+                                        const SkIRect& maskRect) const override;
 #endif
 
     void computeFastBounds(const SkRect&, SkRect*) const override;
@@ -1490,18 +1491,22 @@ bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect,
     return true;
 }
 
-bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src,
-                                         const SkMatrix& ctm,
-                                         const SkIRect& maskRect,
-                                         GrTexture** result) const {
+sk_sp<GrTextureProxy> SkBlurMaskFilterImpl::filterMaskGPU(GrContext* context,
+                                                          sk_sp<GrTextureProxy> srcProxy,
+                                                          const SkMatrix& ctm,
+                                                          const SkIRect& maskRect) const {
     // 'maskRect' isn't snapped to the UL corner but the mask in 'src' is.
     const SkIRect clipRect = SkIRect::MakeWH(maskRect.width(), maskRect.height());
 
-    GrContext* context = src->getContext();
-
     SkScalar xformedSigma = this->computeXformedSigma(ctm);
     SkASSERT(xformedSigma > 0);
 
+    // TODO: defer this further (i.e., push the proxy into GaussianBlur)
+    GrTexture* src = srcProxy->instantiate(context->textureProvider());
+    if (!src) {
+        return nullptr;
+    }
+
     // If we're doing a normal blur, we can clobber the pathTexture in the
     // gaussianBlur.  Otherwise, we need to save it for later compositing.
     bool isNormalBlur = (kNormal_SkBlurStyle == fBlurStyle);
@@ -1511,7 +1516,7 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src,
                                                                                   xformedSigma,
                                                                                   xformedSigma));
     if (!renderTargetContext) {
-        return false;
+        return nullptr;
     }
 
     if (!isNormalBlur) {
@@ -1539,8 +1544,7 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src,
                                       SkRect::Make(clipRect));
     }
 
-    *result = renderTargetContext->asTexture().release();
-    return SkToBool(*result);
+    return sk_ref_sp(renderTargetContext->asDeferredTexture());
 }
 
 #endif // SK_SUPPORT_GPU
index 5c54072..85770ca 100755 (executable)
@@ -17,6 +17,7 @@
 #include "GrInvariantOutput.h"
 #include "GrStyle.h"
 #include "GrTexture.h"
+#include "GrTextureProxy.h"
 #include "glsl/GrGLSLFragmentProcessor.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
 #include "glsl/GrGLSLProgramDataManager.h"
@@ -54,10 +55,10 @@ public:
                                   const SkStrokeRec& strokeRec,
                                   const SkRRect& rrect,
                                   const SkRRect& devRRect) const override;
-    bool filterMaskGPU(GrTexture* src,
-                       const SkMatrix& ctm,
-                       const SkIRect& maskRect,
-                       GrTexture** result) const override;
+    sk_sp<GrTextureProxy> filterMaskGPU(GrContext*,
+                                        sk_sp<GrTextureProxy> srcProxy,
+                                        const SkMatrix& ctm,
+                                        const SkIRect& maskRect) const override;
 #endif
 
     void computeFastBounds(const SkRect&, SkRect*) const override;
@@ -344,12 +345,12 @@ bool SkShadowMaskFilterImpl::directFilterRRectMaskGPU(GrContext*,
     return true;
 }
 
-bool SkShadowMaskFilterImpl::filterMaskGPU(GrTexture* src,
-                                           const SkMatrix& ctm,
-                                           const SkIRect& maskRect,
-                                           GrTexture** result) const {
-    // TODO
-    return false;
+sk_sp<GrTextureProxy> SkShadowMaskFilterImpl::filterMaskGPU(GrContext*,
+                                                            sk_sp<GrTextureProxy> srcProxy,
+                                                            const SkMatrix& ctm,
+                                                            const SkIRect& maskRect) const {
+    // This filter it generative and doesn't operate on pre-existing masks
+    return nullptr;
 }
 
 #endif
index 7688605..2a3c0a8 100644 (file)
@@ -30,16 +30,25 @@ static bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& r
 // is already burnt into the mask this boils down to a rect draw.
 // Return true if the mask was successfully drawn.
 static bool draw_mask(GrRenderTargetContext* renderTargetContext,
+                      GrTextureProvider* textureProvider,
                       const GrClip& clip,
                       const SkMatrix& viewMatrix,
                       const SkIRect& maskRect,
                       GrPaint* grp,
-                      GrTexture* mask) {
+                      sk_sp<GrTextureProxy> mask) {
+
+    // TODO: defer this instantiation
+    GrTexture* maskTex = mask->instantiate(textureProvider);
+    if (!maskTex) {
+        return false;
+    }
+
     SkMatrix matrix;
     matrix.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop));
-    matrix.postIDiv(mask->width(), mask->height());
+    // TODO: this divide relies on the instantiated texture's size!
+    matrix.postIDiv(maskTex->width(), maskTex->height());
     matrix.preConcat(viewMatrix);
-    grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(mask, nullptr, matrix));
+    grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(maskTex, nullptr, matrix));
 
     SkMatrix inverse;
     if (!viewMatrix.invert(&inverse)) {
@@ -50,8 +59,8 @@ static bool draw_mask(GrRenderTargetContext* renderTargetContext,
     return true;
 }
 
-static bool sw_draw_with_mask_filter(GrRenderTargetContext* renderTargetContext,
-                                     GrTextureProvider* textureProvider,
+static bool sw_draw_with_mask_filter(GrContext* context,
+                                     GrRenderTargetContext* renderTargetContext,
                                      const GrClip& clipData,
                                      const SkMatrix& viewMatrix,
                                      const SkPath& devPath,
@@ -83,14 +92,25 @@ static bool sw_draw_with_mask_filter(GrRenderTargetContext* renderTargetContext,
     desc.fHeight = dstM.fBounds.height();
     desc.fConfig = kAlpha_8_GrPixelConfig;
 
-    sk_sp<GrTexture> texture(textureProvider->createApproxTexture(desc));
+    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeDeferred(*context->caps(), desc,
+                                                             SkBackingFit::kApprox,
+                                                             SkBudgeted::kYes));
+    if (!proxy || !proxy->asTextureProxy()) {
+        return false;
+    }
+
+    // This is a bit goofy but, until writePixels is moved to GrSurfaceContext, we're stuck
+    // instantiating here to do the writePixels
+    GrTexture* texture = proxy->asTextureProxy()->instantiate(context->textureProvider());
     if (!texture) {
         return false;
     }
+
     texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
-                               dstM.fImage, dstM.fRowBytes);
+                         dstM.fImage, dstM.fRowBytes);
 
-    return draw_mask(renderTargetContext, clipData, viewMatrix, dstM.fBounds, grp, texture.get());
+    return draw_mask(renderTargetContext, context->textureProvider(),
+                     clipData, viewMatrix, dstM.fBounds, grp, sk_ref_sp(proxy->asTextureProxy()));
 }
 
 // Create a mask of 'devPath' and place the result in 'mask'.
@@ -214,17 +234,13 @@ static void draw_path_with_mask_filter(GrContext* context,
                                                         aa,
                                                         renderTargetContext->numColorSamples()));
         if (maskProxy) {
-            GrTexture* filtered;
-
-            GrTexture* mask = maskProxy->instantiate(context->textureProvider());
-            if (!mask) {
-                return;
-            }
-
-            if (maskFilter->filterMaskGPU(mask, viewMatrix, finalIRect, &filtered)) {
-                // filterMaskGPU gives us ownership of a ref to the result
-                sk_sp<GrTexture> atu(filtered);
-                if (draw_mask(renderTargetContext, clip, viewMatrix, finalIRect, paint, filtered)) {
+            sk_sp<GrTextureProxy> filtered = maskFilter->filterMaskGPU(context,
+                                                                       std::move(maskProxy),
+                                                                       viewMatrix,
+                                                                       finalIRect);
+            if (filtered) {
+                if (draw_mask(renderTargetContext, context->textureProvider(),
+                              clip, viewMatrix, finalIRect, paint, std::move(filtered))) {
                     // This path is completely drawn
                     return;
                 }
@@ -232,8 +248,7 @@ static void draw_path_with_mask_filter(GrContext* context,
         }
     }
 
-    sw_draw_with_mask_filter(renderTargetContext, context->textureProvider(),
-                             clip, viewMatrix, *path,
+    sw_draw_with_mask_filter(context, renderTargetContext, clip, viewMatrix, *path,
                              maskFilter, clipBounds, paint, fillOrHairline);
 }