Start plumbing deferral of GPU resources in the image filters

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4688

Change-Id: I904d999ea87a55bee73765aa96a2f8aef7a0d61c
Reviewed-on: https://skia-review.googlesource.com/4688
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 630f782..cd35d65 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -17,10 +17,12 @@
 
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
-#include "GrRenderTargetContext.h"
 #include "GrFixedClip.h"
 #include "GrInvariantOutput.h"
+#include "GrRenderTargetContext.h"
 #include "GrTexture.h"
+#include "GrTextureProxy.h"
+
 #include "SkGr.h"
 #include "SkGrPriv.h"
 #include "effects/Gr1DKernelEffect.h"
@@ -151,7 +153,7 @@
     }
 
     static sk_sp<GrFragmentProcessor> Make(GrTexture* tex, Direction dir, int radius,
-                                           MorphologyType type, float bounds[2]) {
+                                           MorphologyType type, const float bounds[2]) {
         return sk_sp<GrFragmentProcessor>(new GrMorphologyEffect(tex, dir, radius, type, bounds));
     }
 
@@ -179,8 +181,7 @@
     void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
 
     GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
-    GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType,
-                       float bounds[2]);
+    GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType, const float bounds[2]);
 
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
@@ -310,10 +311,11 @@
 
     if (m.useRange()) {
         const float* range = m.range();
-        if (m.direction() && texture.origin() == kBottomLeft_GrSurfaceOrigin) {
-            pdman.set2f(fRangeUni, 1.0f - range[1], 1.0f - range[0]);
+        if (Gr1DKernelEffect::kY_Direction == m.direction() &&
+            texture.origin() == kBottomLeft_GrSurfaceOrigin) {
+            pdman.set2f(fRangeUni, 1.0f - (range[1]*pixelSize), 1.0f - (range[0]*pixelSize));
         } else {
-            pdman.set2f(fRangeUni, range[0], range[1]);
+            pdman.set2f(fRangeUni, range[0] * pixelSize, range[1] * pixelSize);
         }
     }
 }
@@ -334,7 +336,7 @@
                                        Direction direction,
                                        int radius,
                                        MorphologyType type,
-                                       float range[2])
+                                       const float range[2])
     : INHERITED(texture, direction, radius)
     , fType(type)
     , fUseRange(true) {
@@ -385,18 +387,19 @@
 }
 
 
-static void apply_morphology_rect(GrRenderTargetContext* renderTargetContext,
+static void apply_morphology_rect(GrTextureProvider* provider,
+                                  GrRenderTargetContext* renderTargetContext,
                                   const GrClip& clip,
-                                  GrTexture* texture,
+                                  GrTextureProxy* textureProxy,
                                   const SkIRect& srcRect,
                                   const SkIRect& dstRect,
                                   int radius,
                                   GrMorphologyEffect::MorphologyType morphType,
-                                  float bounds[2],
+                                  const float bounds[2],
                                   Gr1DKernelEffect::Direction direction) {
     GrPaint paint;
     paint.setGammaCorrect(renderTargetContext->isGammaCorrect());
-    paint.addColorFragmentProcessor(GrMorphologyEffect::Make(texture,
+    paint.addColorFragmentProcessor(GrMorphologyEffect::Make(textureProxy->instantiate(provider),
                                                              direction,
                                                              radius,
                                                              morphType,
@@ -406,9 +409,10 @@
                                         SkRect::Make(srcRect));
 }
 
-static void apply_morphology_rect_no_bounds(GrRenderTargetContext* renderTargetContext,
+static void apply_morphology_rect_no_bounds(GrTextureProvider* provider,
+                                            GrRenderTargetContext* renderTargetContext,
                                             const GrClip& clip,
-                                            GrTexture* texture,
+                                            GrTextureProxy* textureProxy,
                                             const SkIRect& srcRect,
                                             const SkIRect& dstRect,
                                             int radius,
@@ -416,16 +420,18 @@
                                             Gr1DKernelEffect::Direction direction) {
     GrPaint paint;
     paint.setGammaCorrect(renderTargetContext->isGammaCorrect());
-    paint.addColorFragmentProcessor(GrMorphologyEffect::Make(texture, direction, radius,
+    paint.addColorFragmentProcessor(GrMorphologyEffect::Make(textureProxy->instantiate(provider),
+                                                             direction, radius,
                                                              morphType));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
     renderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect),
                                         SkRect::Make(srcRect));
 }
 
-static void apply_morphology_pass(GrRenderTargetContext* renderTargetContext,
+static void apply_morphology_pass(GrTextureProvider* provider,
+                                  GrRenderTargetContext* renderTargetContext,
                                   const GrClip& clip,
-                                  GrTexture* texture,
+                                  GrTextureProxy* textureProxy,
                                   const SkIRect& srcRect,
                                   const SkIRect& dstRect,
                                   int radius,
@@ -436,8 +442,8 @@
     SkIRect middleSrcRect = srcRect, middleDstRect = dstRect;
     SkIRect upperSrcRect = srcRect, upperDstRect = dstRect;
     if (direction == Gr1DKernelEffect::kX_Direction) {
-        bounds[0] = (SkIntToScalar(srcRect.left()) + 0.5f) / texture->width();
-        bounds[1] = (SkIntToScalar(srcRect.right()) - 0.5f) / texture->width();
+        bounds[0] = SkIntToScalar(srcRect.left()) + 0.5f;
+        bounds[1] = SkIntToScalar(srcRect.right()) - 0.5f;
         lowerSrcRect.fRight = srcRect.left() + radius;
         lowerDstRect.fRight = dstRect.left() + radius;
         upperSrcRect.fLeft = srcRect.right() - radius;
@@ -445,8 +451,8 @@
         middleSrcRect.inset(radius, 0);
         middleDstRect.inset(radius, 0);
     } else {
-        bounds[0] = (SkIntToScalar(srcRect.top()) + 0.5f) / texture->height();
-        bounds[1] = (SkIntToScalar(srcRect.bottom()) - 0.5f) / texture->height();
+        bounds[0] = SkIntToScalar(srcRect.top()) + 0.5f;
+        bounds[1] = SkIntToScalar(srcRect.bottom()) - 0.5f;
         lowerSrcRect.fBottom = srcRect.top() + radius;
         lowerDstRect.fBottom = dstRect.top() + radius;
         upperSrcRect.fTop = srcRect.bottom() - radius;
@@ -456,16 +462,16 @@
     }
     if (middleSrcRect.fLeft - middleSrcRect.fRight >= 0) {
         // radius covers srcRect; use bounds over entire draw
-        apply_morphology_rect(renderTargetContext, clip, texture, srcRect, dstRect, radius,
-                              morphType, bounds, direction);
+        apply_morphology_rect(provider, renderTargetContext, clip, textureProxy,
+                              srcRect, dstRect, radius, morphType, bounds, direction);
     } else {
         // Draw upper and lower margins with bounds; middle without.
-        apply_morphology_rect(renderTargetContext, clip, texture, lowerSrcRect, lowerDstRect,
-                              radius, morphType, bounds, direction);
-        apply_morphology_rect(renderTargetContext, clip, texture, upperSrcRect, upperDstRect,
-                              radius, morphType, bounds, direction);
-        apply_morphology_rect_no_bounds(renderTargetContext, clip, texture, middleSrcRect,
-                                        middleDstRect, radius, morphType, direction);
+        apply_morphology_rect(provider, renderTargetContext, clip, textureProxy,
+                              lowerSrcRect, lowerDstRect, radius, morphType, bounds, direction);
+        apply_morphology_rect(provider, renderTargetContext, clip, textureProxy,
+                              upperSrcRect, upperDstRect, radius, morphType, bounds, direction);
+        apply_morphology_rect_no_bounds(provider, renderTargetContext, clip, textureProxy,
+                                        middleSrcRect, middleDstRect, radius, morphType, direction);
     }
 }
 
@@ -476,7 +482,7 @@
                                           GrMorphologyEffect::MorphologyType morphType,
                                           SkISize radius,
                                           const SkImageFilter::OutputProperties& outputProperties) {
-    sk_sp<GrTexture> srcTexture(input->asTextureRef(context));
+    sk_sp<GrTextureProxy> srcTexture(input->asTextureProxy(context));
     SkASSERT(srcTexture);
     sk_sp<SkColorSpace> colorSpace = sk_ref_sp(outputProperties.colorSpace());
     GrPixelConfig config = GrRenderableConfigForColorSpace(colorSpace.get());
@@ -490,13 +496,14 @@
     SkASSERT(radius.width() > 0 || radius.height() > 0);
 
     if (radius.fWidth > 0) {
-        sk_sp<GrRenderTargetContext> dstRenderTargetContext(context->makeRenderTargetContext(
+        sk_sp<GrRenderTargetContext> dstRTContext(context->makeDeferredRenderTargetContext(
             SkBackingFit::kApprox, rect.width(), rect.height(), config, colorSpace));
-        if (!dstRenderTargetContext) {
+        if (!dstRTContext) {
             return nullptr;
         }
 
-        apply_morphology_pass(dstRenderTargetContext.get(), clip, srcTexture.get(),
+        apply_morphology_pass(context->textureProvider(), 
+                              dstRTContext.get(), clip, srcTexture.get(),
                               srcRect, dstRect, radius.fWidth, morphType,
                               Gr1DKernelEffect::kX_Direction);
         SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom,
@@ -504,29 +511,31 @@
         GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphType
                                 ? SK_ColorWHITE
                                 : SK_ColorTRANSPARENT;
-        dstRenderTargetContext->clear(&clearRect, clearColor, false);
+        dstRTContext->clear(&clearRect, clearColor, false);
 
-        srcTexture = dstRenderTargetContext->asTexture();
+        srcTexture = sk_ref_sp(dstRTContext->asDeferredTexture());
         srcRect = dstRect;
     }
     if (radius.fHeight > 0) {
-        sk_sp<GrRenderTargetContext> dstRenderTargetContext(context->makeRenderTargetContext(
+        sk_sp<GrRenderTargetContext> dstRTContext(context->makeDeferredRenderTargetContext(
             SkBackingFit::kApprox, rect.width(), rect.height(), config, colorSpace));
-        if (!dstRenderTargetContext) {
+        if (!dstRTContext) {
             return nullptr;
         }
 
-        apply_morphology_pass(dstRenderTargetContext.get(), clip, srcTexture.get(),
+        apply_morphology_pass(context->textureProvider(),
+                              dstRTContext.get(), clip, srcTexture.get(),
                               srcRect, dstRect, radius.fHeight, morphType,
                               Gr1DKernelEffect::kY_Direction);
 
-        srcTexture = dstRenderTargetContext->asTexture();
+        srcTexture = sk_ref_sp(dstRTContext->asDeferredTexture());
     }
 
-    return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(rect.width(), rect.height()),
-                                       kNeedNewImageUniqueID_SpecialImage,
-                                       std::move(srcTexture), std::move(colorSpace),
-                                       &input->props());
+    return SkSpecialImage::MakeDeferredFromGpu(context,
+                                               SkIRect::MakeWH(rect.width(), rect.height()),
+                                               kNeedNewImageUniqueID_SpecialImage,
+                                               std::move(srcTexture), std::move(colorSpace),
+                                               &input->props());
 }
 #endif