Partially defer GrSWMaskHelper
authorRobert Phillips <robertphillips@google.com>
Wed, 14 Dec 2016 17:19:05 +0000 (12:19 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 14 Dec 2016 19:04:02 +0000 (19:04 +0000)
This is intended to position the writePixels in GrSWMaskHelper::toTexture for moving to GrSurfaceContext

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

12 files changed:
gn/gpu.gni
include/gpu/GrRenderTargetContext.h
include/gpu/GrSurfaceContext.h
src/effects/SkShadowMaskFilter.cpp
src/gpu/GrClipStackClip.cpp
src/gpu/GrClipStackClip.h
src/gpu/GrContext.cpp
src/gpu/GrContextPriv.h
src/gpu/GrSWMaskHelper.cpp
src/gpu/GrSWMaskHelper.h
src/gpu/GrSoftwarePathRenderer.cpp
src/gpu/GrSurfaceContextPriv.h [new file with mode: 0644]

index 4df4461..b8306f3 100644 (file)
@@ -186,6 +186,7 @@ skia_gpu_sources = [
   "$_src/gpu/GrStencilSettings.h",
   "$_src/gpu/GrStyle.cpp",
   "$_src/gpu/GrStyle.h",
+  "$_src/gpu/GrSurfaceContextPriv.h",
   "$_src/gpu/GrTessellator.cpp",
   "$_src/gpu/GrTessellator.h",
   "$_src/gpu/GrTextureOpList.cpp",
index 620bb6f..864055b 100644 (file)
@@ -485,6 +485,8 @@ private:
     sk_sp<SkColorSpace>               fColorSpace;
     sk_sp<GrColorSpaceXform>          fColorXformFromSRGB;
     SkSurfaceProps                    fSurfaceProps;
+
+    typedef GrSurfaceContext INHERITED;
 };
 
 #endif
index 29a3f3d..f966086 100644 (file)
@@ -15,6 +15,7 @@ class GrContext;
 class GrRenderTargetProxy;
 class GrSingleOwner;
 class GrSurface;
+class GrSurfaceContextPriv;
 class GrSurfaceProxy;
 class GrTextureProxy;
 struct SkIPoint;
@@ -36,7 +37,13 @@ public:
 
     GrAuditTrail* auditTrail() { return fAuditTrail; }
 
+    // Provides access to functions that aren't part of the public API.
+    GrSurfaceContextPriv surfPriv();
+    const GrSurfaceContextPriv surfPriv() const;
+
 protected:
+    friend class GrSurfaceContextPriv;
+
     GrSurfaceContext(GrContext*, GrAuditTrail*, GrSingleOwner*);
 
     SkDEBUGCODE(GrSingleOwner* singleOwner() { return fSingleOwner; })
@@ -46,6 +53,9 @@ protected:
 
     // In debug builds we guard against improper thread handling
     SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
+
+private:
+    typedef SkRefCnt INHERITED;
 };
 
 #endif
index 85770ca..38f2591 100755 (executable)
@@ -349,7 +349,7 @@ 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
+    // This filter is generative and doesn't operate on pre-existing masks
     return nullptr;
 }
 
index fae01ce..a7bcce4 100644 (file)
@@ -16,6 +16,7 @@
 #include "GrRenderTargetPriv.h"
 #include "GrStencilAttachment.h"
 #include "GrSWMaskHelper.h"
+#include "GrTextureProxy.h"
 #include "effects/GrConvexPolyEffect.h"
 #include "effects/GrRRectEffect.h"
 #include "effects/GrTextureDomain.h"
@@ -340,7 +341,7 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar
         if (UseSWOnlyPath(context, hasUserStencilSettings, renderTargetContext, reducedClip)) {
             // The clip geometry is complex enough that it will be more efficient to create it
             // entirely in software
-            result = CreateSoftwareClipMask(context->textureProvider(), reducedClip);
+            result = CreateSoftwareClipMask(context, reducedClip);
         } else {
             result = CreateAlphaClipMask(context, reducedClip);
         }
@@ -425,11 +426,11 @@ sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context,
     return texture;
 }
 
-sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrTextureProvider* texProvider,
+sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrContext* context,
                                                          const GrReducedClip& reducedClip) {
     GrUniqueKey key;
     GetClipMaskKey(reducedClip.elementsGenID(), reducedClip.ibounds(), &key);
-    if (GrTexture* texture = texProvider->findAndRefTextureByUniqueKey(key)) {
+    if (GrTexture* texture = context->textureProvider()->findAndRefTextureByUniqueKey(key)) {
         return sk_sp<GrTexture>(texture);
     }
 
@@ -437,7 +438,7 @@ sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrTextureProvider* texP
     // the top left corner of the resulting rect to the top left of the texture.
     SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip.height());
 
-    GrSWMaskHelper helper(texProvider);
+    GrSWMaskHelper helper;
 
     // Set the matrix so that rendered clip elements are transformed to mask space from clip
     // space.
@@ -484,19 +485,14 @@ sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrTextureProvider* texP
         }
     }
 
-    // Allocate clip mask texture
-    GrSurfaceDesc desc;
-    desc.fWidth = reducedClip.width();
-    desc.fHeight = reducedClip.height();
-    desc.fConfig = kAlpha_8_GrPixelConfig;
+    sk_sp<GrTextureProxy> result(helper.toTexture(context, SkBackingFit::kApprox));
 
-    sk_sp<GrTexture> result(texProvider->createApproxTexture(desc));
-    if (!result) {
+    GrTexture* tex = result->instantiate(context->textureProvider());
+    if (!tex) {
         return nullptr;
     }
-    result->resourcePriv().setUniqueKey(key);
 
-    helper.toTexture(result.get());
+    tex->resourcePriv().setUniqueKey(key);
 
-    return result;
+    return sk_ref_sp(tex);
 }
index 42bd373..f5b8411 100644 (file)
@@ -54,7 +54,7 @@ private:
     static sk_sp<GrTexture> CreateAlphaClipMask(GrContext*, const GrReducedClip&);
 
     // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture.
-    static sk_sp<GrTexture> CreateSoftwareClipMask(GrTextureProvider*, const GrReducedClip&);
+    static sk_sp<GrTexture> CreateSoftwareClipMask(GrContext*, const GrReducedClip&);
 
    static bool UseSWOnlyPath(GrContext*,
                              bool hasUserStencilSettings,
index 7dd01de..6550342 100644 (file)
@@ -593,6 +593,23 @@ void GrContext::flushSurfaceIO(GrSurface* surface) {
     }
 }
 
+sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
+                                                                  SkBackingFit fit,
+                                                                  SkBudgeted isDstBudgeted) {
+
+    sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeDeferred(*fContext->caps(), dstDesc,
+                                                               fit, isDstBudgeted);
+
+    if (proxy->asRenderTargetProxy()) {
+        return this->drawingManager()->makeRenderTargetContext(std::move(proxy), nullptr, nullptr);
+    } else {
+        SkASSERT(proxy->asTextureProxy());
+        return this->drawingManager()->makeTextureContext(std::move(proxy));
+    }
+
+    return nullptr;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 int GrContext::getRecommendedSampleCount(GrPixelConfig config,
                                          SkScalar dpi) const {
@@ -639,7 +656,7 @@ sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurface
 }
 
 sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
-                                                                   const GrBackendTextureDesc& desc, 
+                                                                   const GrBackendTextureDesc& desc,
                                                                    sk_sp<SkColorSpace> colorSpace,
                                                                    const SkSurfaceProps* props,
                                                                    GrWrapOwnership ownership) {
index dcf0807..7d7cbb0 100644 (file)
@@ -26,6 +26,10 @@ public:
     // Create a surfaceContext that wraps an existing texture or renderTarget
     sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurface> tex);
 
+    sk_sp<GrSurfaceContext> makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
+                                                       SkBackingFit dstFit,
+                                                       SkBudgeted isDstBudgeted);
+
     sk_sp<GrRenderTargetContext> makeBackendTextureRenderTargetContext(
                                                          const GrBackendTextureDesc& desc,
                                                          sk_sp<SkColorSpace> colorSpace,
index f90678a..0065390 100644 (file)
@@ -9,10 +9,13 @@
 
 #include "GrCaps.h"
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "batches/GrDrawOp.h"
 #include "GrRenderTargetContext.h"
 #include "GrPipelineBuilder.h"
 #include "GrShape.h"
+#include "GrSurfaceContext.h"
+#include "GrTextureProxy.h"
 
 #include "SkDistanceFieldGen.h"
 
@@ -94,33 +97,30 @@ bool GrSWMaskHelper::init(const SkIRect& resultBounds, const SkMatrix* matrix) {
     return true;
 }
 
-/**
- * Get a texture (from the texture cache) of the correct size & format.
- */
-GrTexture* GrSWMaskHelper::createTexture(SkBackingFit fit) {
+sk_sp<GrTextureProxy> GrSWMaskHelper::toTexture(GrContext* context, SkBackingFit fit) {
     GrSurfaceDesc desc;
     desc.fWidth = fPixels.width();
     desc.fHeight = fPixels.height();
     desc.fConfig = kAlpha_8_GrPixelConfig;
 
-    if (SkBackingFit::kApprox == fit) {
-        return fTexProvider->createApproxTexture(desc);
-    } else {
-        return fTexProvider->createTexture(desc, SkBudgeted::kYes);
+    sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
+                                                                                desc,
+                                                                                fit,
+                                                                                SkBudgeted::kYes);
+    if (!sContext || !sContext->asDeferredTexture()) {
+        return nullptr;
     }
-}
 
-/**
- * Move the result of the software mask generation back to the gpu
- */
-void GrSWMaskHelper::toTexture(GrTexture *texture) {
-    // Since we're uploading to it, and it's compressed, 'texture' shouldn't
-    // have a render target.
-    SkASSERT(!texture->asRenderTarget());
+    // TODO: can skip this step when writePixels is moved
+    GrTexture* tex = sContext->asDeferredTexture()->instantiate(context->textureProvider());
+    if (!tex) {
+        return nullptr;
+    }
 
-    texture->writePixels(0, 0, fPixels.width(), fPixels.height(), texture->config(),
-                         fPixels.addr(), fPixels.rowBytes());
+    tex->writePixels(0, 0, fPixels.width(), fPixels.height(), kAlpha_8_GrPixelConfig,
+                     fPixels.addr(), fPixels.rowBytes());
 
+    return sk_ref_sp(sContext->asDeferredTexture());
 }
 
 /**
@@ -136,13 +136,13 @@ void GrSWMaskHelper::toSDF(unsigned char* sdf) {
  * Software rasterizes shape to A8 mask and uploads the result to a scratch texture. Returns the
  * resulting texture on success; nullptr on failure.
  */
-GrTexture* GrSWMaskHelper::DrawShapeMaskToTexture(GrTextureProvider* texProvider,
-                                                  const GrShape& shape,
-                                                  const SkIRect& resultBounds,
-                                                  GrAA aa,
-                                                  SkBackingFit fit,
-                                                  const SkMatrix* matrix) {
-    GrSWMaskHelper helper(texProvider);
+sk_sp<GrTexture> GrSWMaskHelper::DrawShapeMaskToTexture(GrContext* context,
+                                                        const GrShape& shape,
+                                                        const SkIRect& resultBounds,
+                                                        GrAA aa,
+                                                        SkBackingFit fit,
+                                                        const SkMatrix* matrix) {
+    GrSWMaskHelper helper;
 
     if (!helper.init(resultBounds, matrix)) {
         return nullptr;
@@ -150,14 +150,12 @@ GrTexture* GrSWMaskHelper::DrawShapeMaskToTexture(GrTextureProvider* texProvider
 
     helper.drawShape(shape, SkRegion::kReplace_Op, aa, 0xFF);
 
-    GrTexture* texture(helper.createTexture(fit));
-    if (!texture) {
+    sk_sp<GrTextureProxy> tProxy = helper.toTexture(context, fit);
+    if (!tProxy) {
         return nullptr;
     }
 
-    helper.toTexture(texture);
-
-    return texture;
+    return sk_ref_sp(tProxy->instantiate(context->textureProvider()));
 }
 
 void GrSWMaskHelper::DrawToTargetWithShapeMask(GrTexture* texture,
index 55ed3ff..6ec1c82 100644 (file)
@@ -43,7 +43,7 @@ struct GrUserStencilSettings;
  */
 class GrSWMaskHelper : SkNoncopyable {
 public:
-    GrSWMaskHelper(GrTextureProvider* texProvider) : fTexProvider(texProvider) { }
+    GrSWMaskHelper() { }
 
     // set up the internal state in preparation for draws. Since many masks
     // may be accumulated in the helper during creation, "resultBounds"
@@ -57,8 +57,7 @@ public:
     // Draw a single path into the accumuation bitmap using the specified op
     void drawShape(const GrShape&, SkRegion::Op op, GrAA, uint8_t alpha);
 
-    // Move the mask generation results from the internal bitmap to the gpu.
-    void toTexture(GrTexture* texture);
+    sk_sp<GrTextureProxy> toTexture(GrContext*, SkBackingFit fit);
 
     // Convert mask generation results to a signed distance field
     void toSDF(unsigned char* sdf);
@@ -70,12 +69,12 @@ public:
 
     // Canonical usage utility that draws a single path and uploads it
     // to the GPU. The result is returned.
-    static GrTexture* DrawShapeMaskToTexture(GrTextureProvider*,
-                                             const GrShape&,
-                                             const SkIRect& resultBounds,
-                                             GrAA,
-                                             SkBackingFit,
-                                             const SkMatrix* matrix);
+    static sk_sp<GrTexture> DrawShapeMaskToTexture(GrContext*,
+                                                   const GrShape&,
+                                                   const SkIRect& resultBounds,
+                                                   GrAA,
+                                                   SkBackingFit,
+                                                   const SkMatrix* matrix);
 
     // This utility draws a path mask generated by DrawShapeMaskToTexture using a provided paint.
     // The rectangle is drawn in device space. The 'viewMatrix' will be used to ensure the correct
@@ -90,11 +89,6 @@ public:
                                           const SkIRect& deviceSpaceRectToDraw);
 
 private:
-    // Helper function to get a scratch texture suitable for capturing the
-    // result (i.e., right size & format)
-    GrTexture* createTexture(SkBackingFit);
-
-    GrTextureProvider*  fTexProvider;
     SkMatrix            fMatrix;
     SkAutoPixmapStorage fPixels;
     SkDraw              fDraw;
index d6db0df..12a753d 100644 (file)
@@ -11,6 +11,7 @@
 #include "GrPipelineBuilder.h"
 #include "GrGpuResourcePriv.h"
 #include "GrSWMaskHelper.h"
+#include "GrSurfaceContextPriv.h"
 #include "GrTextureProvider.h"
 #include "batches/GrRectBatchFactory.h"
 
@@ -203,9 +204,10 @@ bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
     if (!texture) {
         SkBackingFit fit = useCache ? SkBackingFit::kExact : SkBackingFit::kApprox;
         GrAA aa = GrAAType::kCoverage == args.fAAType ? GrAA::kYes : GrAA::kNo;
-        texture.reset(GrSWMaskHelper::DrawShapeMaskToTexture(fTexProvider, *args.fShape,
-                                                             *boundsForMask, aa,
-                                                             fit, args.fViewMatrix));
+        GrContext* context = args.fRenderTargetContext->surfPriv().getContext();
+        texture = GrSWMaskHelper::DrawShapeMaskToTexture(context, *args.fShape,
+                                                         *boundsForMask, aa,
+                                                         fit, args.fViewMatrix);
         if (!texture) {
             return false;
         }
diff --git a/src/gpu/GrSurfaceContextPriv.h b/src/gpu/GrSurfaceContextPriv.h
new file mode 100644 (file)
index 0000000..bd3d2de
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrSurfaceContextPriv_DEFINED
+#define GrSurfaceContextPriv_DEFINED
+
+#include "GrSurfaceContext.h"
+
+/** Class that adds methods to GrSurfaceContext that are only intended for use internal to
+    Skia. This class is purely a privileged window into GrSurfaceContext. It should never have
+    additional data members or virtual methods. */
+class GrSurfaceContextPriv {
+public:
+    GrContext* getContext() { return fSurfaceContext->fContext; }
+
+private:
+    explicit GrSurfaceContextPriv(GrSurfaceContext* surfaceContext) 
+        : fSurfaceContext(surfaceContext) {
+    }
+
+    GrSurfaceContextPriv(const GrSurfaceContextPriv&) {} // unimpl
+    GrSurfaceContextPriv& operator=(const GrSurfaceContextPriv&); // unimpl
+
+    // No taking addresses of this type.
+    const GrSurfaceContextPriv* operator&() const;
+    GrSurfaceContextPriv* operator&();
+
+    GrSurfaceContext* fSurfaceContext;
+
+    friend class GrSurfaceContext; // to construct/copy this type.
+};
+
+inline GrSurfaceContextPriv GrSurfaceContext::surfPriv() {
+    return GrSurfaceContextPriv(this);
+}
+
+inline const GrSurfaceContextPriv GrSurfaceContext::surfPriv() const {
+    return GrSurfaceContextPriv(const_cast<GrSurfaceContext*>(this));
+}
+
+#endif