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
This commit is contained in:
robertphillips 2016-07-13 07:48:43 -07:00 committed by Commit bot
parent e3aea10428
commit 9199a9fef9
6 changed files with 109 additions and 99 deletions

View File

@ -228,6 +228,7 @@
'<(skia_src_path)/gpu/batches/GrBatch.cpp',
'<(skia_src_path)/gpu/batches/GrBatch.h',
'<(skia_src_path)/gpu/batches/GrClearBatch.h',
'<(skia_src_path)/gpu/batches/GrClearStencilClipBatch.h',
'<(skia_src_path)/gpu/batches/GrCopySurfaceBatch.cpp',
'<(skia_src_path)/gpu/batches/GrCopySurfaceBatch.h',
'<(skia_src_path)/gpu/batches/GrDashLinePathRenderer.cpp',

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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*);

View File

@ -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

View File

@ -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