Compute clipped draw bounds outside GrAppliedClip.
authorBrian Salomon <bsalomon@google.com>
Tue, 14 Mar 2017 17:42:58 +0000 (13:42 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Tue, 14 Mar 2017 18:51:49 +0000 (18:51 +0000)
We will be storing GrAppliedClips alongside ops. The op already stores the
clipped bounds. If GrAppliedClip has draw bounds then as ops combine the
GrAppliedClip's bounds should be merged to be consistent. However, we won't
actually ever use those bounds again so it would be wasteful to merge them.

Change-Id: I4ef3010dc04761e256120a2e0e074bc3c6ff6ca1
Reviewed-on: https://skia-review.googlesource.com/9642
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Chris Dalton <csmartdalton@google.com>
gm/windowrectangles.cpp
src/gpu/GrAppliedClip.h
src/gpu/GrClip.h
src/gpu/GrClipStackClip.cpp
src/gpu/GrClipStackClip.h
src/gpu/GrFixedClip.cpp
src/gpu/GrFixedClip.h
src/gpu/GrReducedClip.cpp
src/gpu/GrRenderTargetContext.cpp
tests/GpuSampleLocationsTest.cpp
tests/GrPorterDuffTest.cpp

index b24febd71c70f4f0bdd32cc7b366032d876dc1c9..202836f18a5a4fb804ec8bc33c9866c3a17d0ed4 100644 (file)
@@ -155,7 +155,8 @@ public:
                                                                SkIRect::MakeWH(w, h), {x, y});
     }
 private:
-    bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip* out) const override {
+    bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip* out,
+               SkRect* bounds) const override {
         out->addCoverageFP(fFP);
         return true;
     }
@@ -167,7 +168,8 @@ private:
  */
 class StencilOnlyClip final : public MaskOnlyClipBase {
 private:
-    bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip* out) const override {
+    bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip* out,
+               SkRect* bounds) const override {
         out->addStencilClip();
         return true;
     }
index 4786f6434fb9a7531678c4112585d63a0f1bea2f..57314ec7d4da6186e1132ca4025d627f5db382e5 100644 (file)
  */
 class GrAppliedClip : public SkNoncopyable {
 public:
-    GrAppliedClip(const SkRect& drawBounds)
-        : fHasStencilClip(false)
-        , fClippedDrawBounds(drawBounds) {
-    }
-
     const GrScissorState& scissorState() const { return fScissorState; }
     const GrWindowRectsState& windowRectsState() const { return fWindowRectsState; }
     GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP.get(); }
@@ -30,9 +25,11 @@ public:
 
     /**
      * Intersects the applied clip with the provided rect. Returns false if the draw became empty.
+     * 'clippedDrawBounds' will be intersected with 'irect'. This returns false if the clip becomes
+     * empty or the draw no longer intersects the clip. In either case the draw can be skipped.
      */
-    bool addScissor(const SkIRect& irect) {
-        return fScissorState.intersect(irect) && fClippedDrawBounds.intersect(SkRect::Make(irect));
+    bool addScissor(const SkIRect& irect, SkRect* clippedDrawBounds) {
+        return fScissorState.intersect(irect) && clippedDrawBounds->intersect(SkRect::Make(irect));
     }
 
     void addWindowRectangles(const GrWindowRectsState& windowState) {
@@ -55,18 +52,11 @@ public:
         fHasStencilClip = true;
     }
 
-    /**
-     * Returns the device bounds of the draw after clip has been applied. TODO: Ideally this would
-     * consider the combined effect of all clipping techniques in play (scissor, stencil, fp, etc.).
-     */
-    const SkRect& clippedDrawBounds() const { return fClippedDrawBounds; }
-
 private:
     GrScissorState             fScissorState;
     GrWindowRectsState         fWindowRectsState;
     sk_sp<GrFragmentProcessor> fClipCoverageFP;
-    bool                       fHasStencilClip;
-    SkRect                     fClippedDrawBounds;
+    bool                       fHasStencilClip = false;
     typedef SkNoncopyable INHERITED;
 };
 
index eb4eab2d0cfaf156ffa67ae1a3d18eaa8bada647..c44653baadd619a303b669d23caea006aedc428f 100644 (file)
@@ -28,8 +28,17 @@ public:
     }
     virtual void getConservativeBounds(int width, int height, SkIRect* devResult,
                                        bool* isIntersectionOfRects = nullptr) const = 0;
+    /**
+     * This computes a GrAppliedClip from the clip which in turn can be used to build a GrPipeline.
+     * To determine the appropriate clipping implementation the GrClip subclass must know whether
+     * the draw will enable HW AA or uses the stencil buffer. On input 'bounds' is a conservative
+     * bounds of the draw that is to be clipped. After return 'bounds' has been intersected with a
+     * conservative bounds of the clip. A return value of false indicates that the draw can be
+     * skipped as it is fully clipped out.
+     */
     virtual bool apply(GrContext*, GrRenderTargetContext*, bool useHWAA,
-                       bool hasUserStencilSettings, GrAppliedClip* out) const = 0;
+                       bool hasUserStencilSettings, GrAppliedClip* result,
+                       SkRect* bounds) const = 0;
 
     virtual ~GrClip() {}
 
@@ -134,7 +143,8 @@ private:
             *isIntersectionOfRects = true;
         }
     }
-    bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip*) const final {
+    bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip*,
+               SkRect*) const final {
         return true;
     }
     bool isRRect(const SkRect&, SkRRect*, GrAA*) const override { return false; }
index d44373f9573b9ab920f80fadf20770453a2f07d2..e324770f62da3a6496fe59095779b0d38f6748cd 100644 (file)
@@ -247,14 +247,14 @@ static bool get_analytic_clip_processor(const ElementList& elements,
 // sort out what kind of clip mask needs to be created: alpha, stencil,
 // scissor, or entirely software
 bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTargetContext,
-                            bool useHWAA, bool hasUserStencilSettings, GrAppliedClip* out) const {
+                            bool useHWAA, bool hasUserStencilSettings, GrAppliedClip* out,
+                            SkRect* bounds) const {
     if (!fStack || fStack->isWideOpen()) {
         return true;
     }
 
-    SkRect devBounds = SkRect::MakeIWH(renderTargetContext->width(),
-                                       renderTargetContext->height());
-    if (!devBounds.intersect(out->clippedDrawBounds())) {
+    SkRect devBounds = SkRect::MakeIWH(renderTargetContext->width(), renderTargetContext->height());
+    if (!devBounds.intersect(*bounds)) {
         return false;
     }
 
@@ -262,7 +262,7 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar
                                     renderTargetContext->priv().maxWindowRectangles());
 
     if (reducedClip.hasIBounds() && !GrClip::IsInsideClip(reducedClip.ibounds(), devBounds)) {
-        out->addScissor(reducedClip.ibounds());
+        out->addScissor(reducedClip.ibounds(), bounds);
     }
 
     if (!reducedClip.windowRectangles().empty()) {
index a1365a771388c8ecf8f5eb49e459679f328ff048..8058c3b8a49015799f80be77993e36c897402401 100644 (file)
@@ -29,7 +29,7 @@ public:
     void getConservativeBounds(int width, int height, SkIRect* devResult,
                                bool* isIntersectionOfRects) const final;
     bool apply(GrContext*, GrRenderTargetContext*, bool useHWAA, bool hasUserStencilSettings,
-               GrAppliedClip* out) const final;
+               GrAppliedClip* out, SkRect* bounds) const final;
 
     bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA* aa) const override;
 
index d584ee119e5e06b39250b837c9aa58b09cdacdbd..e551f9b966ba0938379bc321abc571e44d4b4af0 100644 (file)
@@ -45,18 +45,18 @@ bool GrFixedClip::isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA* aa) const {
     return false;
 };
 
-bool GrFixedClip::apply(GrContext*, GrRenderTargetContext* rtc,
-                        bool, bool, GrAppliedClip* out) const {
+bool GrFixedClip::apply(GrContext*, GrRenderTargetContext* rtc, bool, bool, GrAppliedClip* out,
+                        SkRect* bounds) const {
     if (fScissorState.enabled()) {
         SkIRect tightScissor = SkIRect::MakeWH(rtc->width(), rtc->height());
         if (!tightScissor.intersect(fScissorState.rect())) {
             return false;
         }
-        if (IsOutsideClip(tightScissor, out->clippedDrawBounds())) {
+        if (IsOutsideClip(tightScissor, *bounds)) {
             return false;
         }
-        if (!IsInsideClip(fScissorState.rect(), out->clippedDrawBounds())) {
-            out->addScissor(tightScissor);
+        if (!IsInsideClip(fScissorState.rect(), *bounds)) {
+            out->addScissor(tightScissor, bounds);
         }
     }
 
index 0f517525a082070df591dd7e976b8d12ed69e898..744bb27a81acfca6339c6b81896ed738f00da0a2 100644 (file)
@@ -42,7 +42,8 @@ public:
     bool quickContains(const SkRect&) const override;
     void getConservativeBounds(int w, int h, SkIRect* devResult, bool* iior) const override;
     bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const override;
-    bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip* out) const override;
+    bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip*,
+               SkRect*) const override;
 
     static const GrFixedClip& Disabled();
 
index d322c6b6caafede8ac01aa6ec271bee4e1eb29a9..4b7e69bc02edc88ad9442971561cc242ea3b57c2 100644 (file)
@@ -674,8 +674,9 @@ private:
         return false;
     }
     bool apply(GrContext* context, GrRenderTargetContext* renderTargetContext, bool useHWAA,
-               bool hasUserStencilSettings, GrAppliedClip* out) const override {
-        if (!fFixedClip.apply(context, renderTargetContext, useHWAA, hasUserStencilSettings, out)) {
+               bool hasUserStencilSettings, GrAppliedClip* out, SkRect* bounds) const override {
+        if (!fFixedClip.apply(context, renderTargetContext, useHWAA, hasUserStencilSettings, out,
+                              bounds)) {
             return false;
         }
         out->addStencilClip();
index 7a6abe0e73a91194ed7b5b7b13a91bfc6a224d25..8c231429fefa6bdfcf6cebf542691cbc71489f29 100644 (file)
@@ -712,9 +712,9 @@ void GrRenderTargetContextPriv::stencilPath(const GrClip& clip,
     SkRect bounds = SkRect::MakeIWH(fRenderTargetContext->width(), fRenderTargetContext->height());
 
     // Setup clip
-    GrAppliedClip appliedClip(bounds);
+    GrAppliedClip appliedClip;
     if (!clip.apply(fRenderTargetContext->fContext, fRenderTargetContext, useHWAA, true,
-                    &appliedClip)) {
+                    &appliedClip, &bounds)) {
         return;
     }
 
@@ -741,7 +741,7 @@ void GrRenderTargetContextPriv::stencilPath(const GrClip& clip,
                                                      appliedClip.scissorState(),
                                                      fRenderTargetContext->accessRenderTarget(),
                                                      path);
-    op->setClippedBounds(appliedClip.clippedDrawBounds());
+    op->setClippedBounds(bounds);
     fRenderTargetContext->getOpList()->recordOp(std::move(op), fRenderTargetContext);
 }
 
@@ -1692,9 +1692,9 @@ uint32_t GrRenderTargetContext::addDrawOp(const GrPipelineBuilder& pipelineBuild
     // Setup clip
     SkRect bounds;
     op_bounds(&bounds, op.get());
-    GrAppliedClip appliedClip(bounds);
+    GrAppliedClip appliedClip;
     if (!clip.apply(fContext, this, pipelineBuilder.isHWAntialias(),
-                    pipelineBuilder.hasUserStencilSettings(), &appliedClip)) {
+                    pipelineBuilder.hasUserStencilSettings(), &appliedClip, &bounds)) {
         return SK_InvalidUniqueID;
     }
 
@@ -1731,7 +1731,7 @@ uint32_t GrRenderTargetContext::addDrawOp(const GrPipelineBuilder& pipelineBuild
     }
     op->initPipeline(args);
     // TODO: We need to add pipeline dependencies on textures, etc before recording this op.
-    op->setClippedBounds(appliedClip.clippedDrawBounds());
+    op->setClippedBounds(bounds);
     return this->getOpList()->addOp(std::move(op), this);
 }
 
index e3764a5977609bda5aa9cc318b51971f99cb5165..8808b1d8cbfeaf47c33a0b62b538847c0fcff828 100644 (file)
@@ -96,7 +96,7 @@ static void construct_dummy_pipeline(GrRenderTargetContext* dc, GrPipeline* pipe
     GrScissorState dummyScissor;
     GrWindowRectsState dummyWindows;
 
-    GrAppliedClip dummyAppliedClip(SkRect::MakeLargest());
+    GrAppliedClip dummyAppliedClip;
     GrProcessorSet::FragmentProcessorAnalysis analysis;
     GrPipeline::InitArgs args;
     dummyBuilder.getPipelineInitArgs(&args);
index b09192e3bfa13fdb6277c279f1df4ef596ee3253..ddca03a497ecd74930dd5f11a9e12eb118e95877 100644 (file)
@@ -968,7 +968,7 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const
     } testLCDCoverageOp;
 
     GrProcessorSet::FragmentProcessorAnalysis analysis;
-    GrAppliedClip clip(SkRect::MakeLargest());
+    GrAppliedClip clip;
     testLCDCoverageOp.analyzeProcessors(&analysis, GrProcessorSet(GrPaint()), &clip, caps);
 
     SkASSERT(analysis.hasKnownOutputColor());