diff options
author | 2016-07-13 07:48:43 -0700 | |
---|---|---|
committer | 2016-07-13 07:48:43 -0700 | |
commit | 9199a9fef9896636f673372d2ac1c00af036bf85 (patch) | |
tree | be8246e54504ccc2151661fe113956d64a28efda /src/gpu | |
parent | e3aea10428d1597838fd563c92340beaf969a9b4 (diff) |
Move GrDrawTarget::clear logic into GrDrawContext
I found it a bit worrisome that GrDrawTarget was calling back into GrDrawContext. This also moves GrDrawTarget closer to being a simple-ish container of batches.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2145643003
Review-Url: https://codereview.chromium.org/2145643003
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrDrawContext.cpp | 36 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 42 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 12 | ||||
-rw-r--r-- | src/gpu/batches/GrClearBatch.h | 58 | ||||
-rw-r--r-- | src/gpu/batches/GrClearStencilClipBatch.h | 59 |
5 files changed, 108 insertions, 99 deletions
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index a86e01e72b..80b18ecf88 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -18,6 +18,7 @@ #include "SkSurfacePriv.h" #include "batches/GrBatch.h" +#include "batches/GrClearBatch.h" #include "batches/GrDrawAtlasBatch.h" #include "batches/GrDrawVerticesBatch.h" #include "batches/GrRectBatchFactory.h" @@ -195,7 +196,38 @@ void GrDrawContext::clear(const SkIRect* rect, GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::clear"); AutoCheckFlush acf(fDrawingManager); - this->getDrawTarget()->clear(rect, color, canIgnoreRect, this); + + const SkIRect rtRect = SkIRect::MakeWH(this->width(), this->height()); + SkIRect clippedRect; + if (!rect || + (canIgnoreRect && fContext->caps()->fullClearIsFree()) || + rect->contains(rtRect)) { + rect = &rtRect; + } else { + clippedRect = *rect; + if (!clippedRect.intersect(rtRect)) { + return; + } + rect = &clippedRect; + } + + if (fContext->caps()->useDrawInsteadOfClear()) { + // This works around a driver bug with clear by drawing a rect instead. + // The driver will ignore a clear if it is the only thing rendered to a + // target before the target is read. + if (rect == &rtRect) { + this->discard(); + } + + GrPaint paint; + paint.setColor4f(GrColor4f::FromGrColor(color)); + paint.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::kSrc_Mode)); + + this->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::Make(*rect)); + } else { + sk_sp<GrBatch> batch = GrClearBatch::Make(*rect, color, this->accessRenderTarget()); + this->getDrawTarget()->addBatch(std::move(batch)); + } } @@ -360,7 +392,7 @@ void GrDrawContext::drawRect(const GrClip& clip, // Will it blend? GrColor clearColor; if (paint.isConstantBlendedColor(&clearColor)) { - this->getDrawTarget()->clear(nullptr, clearColor, true, this); + this->clear(nullptr, clearColor, true); return; } } diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index bffe2f9740..252726c710 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -25,7 +25,7 @@ #include "SkStrokeRec.h" -#include "batches/GrClearBatch.h" +#include "batches/GrClearStencilClipBatch.h" #include "batches/GrCopySurfaceBatch.h" #include "batches/GrDiscardBatch.h" #include "batches/GrDrawBatch.h" @@ -443,44 +443,8 @@ void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder, batch->unref(); } -void GrDrawTarget::clear(const SkIRect* rect, - GrColor color, - bool canIgnoreRect, - GrDrawContext* drawContext) { - SkIRect rtRect = SkIRect::MakeWH(drawContext->width(), drawContext->height()); - SkIRect clippedRect; - if (!rect || - (canIgnoreRect && this->caps()->fullClearIsFree()) || - rect->contains(rtRect)) { - rect = &rtRect; - } else { - clippedRect = *rect; - if (!clippedRect.intersect(rtRect)) { - return; - } - rect = &clippedRect; - } - - if (this->caps()->useDrawInsteadOfClear()) { - // This works around a driver bug with clear by drawing a rect instead. - // The driver will ignore a clear if it is the only thing rendered to a - // target before the target is read. - if (rect == &rtRect) { - drawContext->discard(); - } - - SkRect scalarRect = SkRect::Make(*rect); - - GrPaint paint; - paint.setColor4f(GrColor4f::FromGrColor(color)); - paint.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::kSrc_Mode)); - - drawContext->drawRect(GrNoClip(), paint, SkMatrix::I(), scalarRect); - } else { - GrBatch* batch = new GrClearBatch(*rect, color, drawContext->accessRenderTarget()); - this->recordBatch(batch, batch->bounds()); - batch->unref(); - } +void GrDrawTarget::addBatch(sk_sp<GrBatch> batch) { + this->recordBatch(batch.get(), batch->bounds()); } void GrDrawTarget::discard(GrRenderTarget* renderTarget) { diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 7b268c2827..5f91baa33b 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -106,6 +106,8 @@ public: void drawBatch(const GrPipelineBuilder&, GrDrawContext*, const GrClip&, GrDrawBatch*); + void addBatch(sk_sp<GrBatch>); + /** * Draws path into the stencil buffer. The fill must be either even/odd or * winding (not inverse or hairline). It will respect the HW antialias flag @@ -116,16 +118,6 @@ public: const GrClip&, const SkMatrix& viewMatrix, const GrPath*, GrPathRendering::FillType); - /** - * Clear the passed in drawContext. Ignores the GrPipelineBuilder and clip. Clears the whole - * thing if rect is nullptr, otherwise just the rect. If canIgnoreRect is set then the entire - * drawContext can be optionally cleared. - */ - void clear(const SkIRect* rect, - GrColor color, - bool canIgnoreRect, - GrDrawContext*); - /** Discards the contents render target. */ void discard(GrRenderTarget*); diff --git a/src/gpu/batches/GrClearBatch.h b/src/gpu/batches/GrClearBatch.h index 9a653a3962..00a1c84de6 100644 --- a/src/gpu/batches/GrClearBatch.h +++ b/src/gpu/batches/GrClearBatch.h @@ -18,12 +18,8 @@ class GrClearBatch final : public GrBatch { public: DEFINE_BATCH_CLASS_ID - GrClearBatch(const SkIRect& rect, GrColor color, GrRenderTarget* rt) - : INHERITED(ClassID()) - , fRect(rect) - , fColor(color) - , fRenderTarget(rt) { - this->setBounds(SkRect::Make(rect), HasAABloat::kNo, IsZeroArea::kNo); + static sk_sp<GrBatch> Make(const SkIRect& rect, GrColor color, GrRenderTarget* rt) { + return sk_sp<GrBatch>(new GrClearBatch(rect, color, rt)); } const char* name() const override { return "Clear"; } @@ -41,6 +37,14 @@ public: } private: + GrClearBatch(const SkIRect& rect, GrColor color, GrRenderTarget* rt) + : INHERITED(ClassID()) + , fRect(rect) + , fColor(color) + , fRenderTarget(rt) { + this->setBounds(SkRect::Make(rect), HasAABloat::kNo, IsZeroArea::kNo); + } + bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { // This could be much more complicated. Currently we look at cases where the new clear // contains the old clear, or when the new clear is a subset of the old clear and is the @@ -71,46 +75,4 @@ private: typedef GrBatch INHERITED; }; -class GrClearStencilClipBatch final : public GrBatch { -public: - DEFINE_BATCH_CLASS_ID - - GrClearStencilClipBatch(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) - : INHERITED(ClassID()) - , fRect(rect) - , fInsideClip(insideClip) - , fRenderTarget(rt) { - this->setBounds(SkRect::Make(rect), HasAABloat::kNo, IsZeroArea::kNo); - } - - const char* name() const override { return "ClearStencilClip"; } - - uint32_t renderTargetUniqueID() const override { return fRenderTarget.get()->getUniqueID(); } - GrRenderTarget* renderTarget() const override { return fRenderTarget.get(); } - - SkString dumpInfo() const override { - SkString string; - string.printf("Rect [L: %d, T: %d, R: %d, B: %d], IC: %d, RT: 0x%p", - fRect.fLeft, fRect.fTop, fRect.fRight, fRect.fBottom, fInsideClip, - fRenderTarget.get()); - string.append(INHERITED::dumpInfo()); - return string; - } - -private: - bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { return false; } - - void onPrepare(GrBatchFlushState*) override {} - - void onDraw(GrBatchFlushState* state) override { - state->commandBuffer()->clearStencilClip(fRect, fInsideClip, fRenderTarget.get()); - } - - SkIRect fRect; - bool fInsideClip; - GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget; - - typedef GrBatch INHERITED; -}; - #endif diff --git a/src/gpu/batches/GrClearStencilClipBatch.h b/src/gpu/batches/GrClearStencilClipBatch.h new file mode 100644 index 0000000000..aa4d4afff0 --- /dev/null +++ b/src/gpu/batches/GrClearStencilClipBatch.h @@ -0,0 +1,59 @@ +/* + * 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 GrClearStencilClipBatch_DEFINED +#define GrClearStencilClipBatch_DEFINED + +#include "GrBatch.h" +#include "GrBatchFlushState.h" +#include "GrGpu.h" +#include "GrGpuCommandBuffer.h" +#include "GrRenderTarget.h" + +class GrClearStencilClipBatch final : public GrBatch { +public: + DEFINE_BATCH_CLASS_ID + + GrClearStencilClipBatch(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) + : INHERITED(ClassID()) + , fRect(rect) + , fInsideClip(insideClip) + , fRenderTarget(rt) { + this->setBounds(SkRect::Make(rect), HasAABloat::kNo, IsZeroArea::kNo); + } + + const char* name() const override { return "ClearStencilClip"; } + + uint32_t renderTargetUniqueID() const override { return fRenderTarget.get()->getUniqueID(); } + GrRenderTarget* renderTarget() const override { return fRenderTarget.get(); } + + SkString dumpInfo() const override { + SkString string; + string.printf("Rect [L: %d, T: %d, R: %d, B: %d], IC: %d, RT: %d", + fRect.fLeft, fRect.fTop, fRect.fRight, fRect.fBottom, fInsideClip, + fRenderTarget.get()->getUniqueID()); + string.append(INHERITED::dumpInfo()); + return string; + } + +private: + bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { return false; } + + void onPrepare(GrBatchFlushState*) override {} + + void onDraw(GrBatchFlushState* state) override { + state->commandBuffer()->clearStencilClip(fRect, fInsideClip, fRenderTarget.get()); + } + + SkIRect fRect; + bool fInsideClip; + GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget; + + typedef GrBatch INHERITED; +}; + +#endif |