Mv DRRect drawing code from GrDrawContext into SkGpuDevice

This is a TODO left over from https://codereview.chromium.org/1731413002/ (Hide GrDrawTarget from GrOvalRenderer). It is desireable since the GrDrawContext doesn't, in general, manipulate GrFragmentProcessors.

GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1733993003

Review URL: https://codereview.chromium.org/1733993003
This commit is contained in:
robertphillips 2016-02-25 09:28:08 -08:00 committed by Commit bot
parent 24dd687ac5
commit d77061067a
4 changed files with 73 additions and 131 deletions

View File

@ -140,23 +140,6 @@ public:
const SkRRect& rrect,
const GrStrokeInfo&);
/**
* Shortcut for drawing an SkPath consisting of nested rrects using a paint.
* Does not support stroking. The result is undefined if outer does not contain
* inner.
*
* @param paint describes how to color pixels.
* @param viewMatrix transformation matrix
* @param outer the outer roundrect
* @param inner the inner roundrect
*/
void drawDRRect(const GrClip&,
const GrPaint&,
const SkMatrix& viewMatrix,
const SkRRect& outer,
const SkRRect& inner);
/**
* Draws a path.
*

View File

@ -23,8 +23,6 @@
#include "batches/GrRectBatchFactory.h"
#include "batches/GrNinePatch.h" // TODO Factory
#include "effects/GrRRectEffect.h"
#include "text/GrAtlasTextContext.h"
#include "text/GrStencilAndCoverTextContext.h"
@ -517,113 +515,6 @@ void GrDrawContext::drawRRect(const GrClip& clip,
///////////////////////////////////////////////////////////////////////////////
static bool draw_drrect(GrDrawTarget* drawTarget,
const GrPipelineBuilder& pipelineBuilder,
GrColor color,
const SkMatrix& viewMatrix,
bool useAA,
const SkRRect& origOuter,
const SkRRect& origInner,
GrShaderCaps* shaderCaps) {
bool applyAA = useAA && !pipelineBuilder.getRenderTarget()->isUnifiedMultisampled();
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
if (!origInner.isEmpty()) {
SkTCopyOnFirstWrite<SkRRect> inner(origInner);
if (!viewMatrix.isIdentity()) {
if (!origInner.transform(viewMatrix, inner.writable())) {
return false;
}
}
GrPrimitiveEdgeType edgeType = applyAA ?
kInverseFillAA_GrProcessorEdgeType :
kInverseFillBW_GrProcessorEdgeType;
// TODO this needs to be a geometry processor
GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner);
if (nullptr == fp) {
return false;
}
arfps.set(&pipelineBuilder);
arfps.addCoverageFragmentProcessor(fp)->unref();
}
SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle);
SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(pipelineBuilder, color,
viewMatrix, useAA, origOuter,
fillRec, shaderCaps));
if (batch) {
drawTarget->drawBatch(pipelineBuilder, batch);
return true;
}
SkASSERT(!origOuter.isEmpty());
SkTCopyOnFirstWrite<SkRRect> outer(origOuter);
if (!viewMatrix.isIdentity()) {
if (!origOuter.transform(viewMatrix, outer.writable())) {
return false;
}
}
GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType :
kFillBW_GrProcessorEdgeType;
SkAutoTUnref<GrFragmentProcessor> effect(GrRRectEffect::Create(edgeType, *outer));
if (!effect) {
return false;
}
if (!arfps.isSet()) {
arfps.set(&pipelineBuilder);
}
SkMatrix invert;
if (!viewMatrix.invert(&invert)) {
return false;
}
arfps.addCoverageFragmentProcessor(effect);
SkRect bounds = outer->getBounds();
if (applyAA) {
bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
}
batch.reset(GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(), bounds,
nullptr, &invert));
drawTarget->drawBatch(pipelineBuilder, batch);
return true;
}
void GrDrawContext::drawDRRect(const GrClip& clip,
const GrPaint& paint,
const SkMatrix& viewMatrix,
const SkRRect& outer,
const SkRRect& inner) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawDRRect");
if (outer.isEmpty()) {
return;
}
AutoCheckFlush acf(fDrawingManager);
GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip);
GrColor color = paint.getColor();
if (!draw_drrect(this->getDrawTarget(), pipelineBuilder,
color, viewMatrix, paint.isAntiAlias(),
outer, inner, fContext->caps()->shaderCaps())) {
SkPath path;
path.setIsVolatile(true);
path.addRRect(inner);
path.addRRect(outer);
path.setFillType(SkPath::kEvenOdd_FillType);
GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle);
this->internalDrawPath(&pipelineBuilder, viewMatrix, color,
paint.isAntiAlias(), path, fillRec);
}
}
///////////////////////////////////////////////////////////////////////////////
void GrDrawContext::drawOval(const GrClip& clip,
const GrPaint& paint,
const SkMatrix& viewMatrix,

View File

@ -44,6 +44,7 @@
#include "batches/GrRectBatchFactory.h"
#include "effects/GrBicubicEffect.h"
#include "effects/GrDashingEffect.h"
#include "effects/GrRRectEffect.h"
#include "effects/GrSimpleTextureEffect.h"
#include "effects/GrTextureDomain.h"
#include "text/GrTextUtils.h"
@ -559,6 +560,66 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
fDrawContext->drawRRect(fClip, grPaint, *draw.fMatrix, rect, strokeInfo);
}
bool SkGpuDevice::drawFilledDRRect(const SkMatrix& viewMatrix, const SkRRect& origOuter,
const SkRRect& origInner, const SkPaint& paint) {
SkASSERT(!origInner.isEmpty());
SkASSERT(!origOuter.isEmpty());
bool applyAA = paint.isAntiAlias() && !fRenderTarget->isUnifiedMultisampled();
GrPrimitiveEdgeType innerEdgeType = applyAA ? kInverseFillAA_GrProcessorEdgeType :
kInverseFillBW_GrProcessorEdgeType;
GrPrimitiveEdgeType outerEdgeType = applyAA ? kFillAA_GrProcessorEdgeType :
kFillBW_GrProcessorEdgeType;
SkTCopyOnFirstWrite<SkRRect> inner(origInner), outer(origOuter);
SkMatrix inverseVM;
if (!viewMatrix.isIdentity()) {
if (!origInner.transform(viewMatrix, inner.writable())) {
return false;
}
if (!origOuter.transform(viewMatrix, outer.writable())) {
return false;
}
if (!viewMatrix.invert(&inverseVM)) {
return false;
}
} else {
inverseVM.reset();
}
GrPaint grPaint;
if (!SkPaintToGrPaint(this->context(), paint, viewMatrix, &grPaint)) {
return false;
}
grPaint.setAntiAlias(false);
// TODO these need to be a geometry processors
SkAutoTUnref<GrFragmentProcessor> innerEffect(GrRRectEffect::Create(innerEdgeType, *inner));
if (!innerEffect) {
return false;
}
SkAutoTUnref<GrFragmentProcessor> outerEffect(GrRRectEffect::Create(outerEdgeType, *outer));
if (!outerEffect) {
return false;
}
grPaint.addCoverageFragmentProcessor(innerEffect);
grPaint.addCoverageFragmentProcessor(outerEffect);
SkRect bounds = outer->getBounds();
if (applyAA) {
bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
}
fDrawContext->fillRectWithLocalMatrix(fClip, grPaint, SkMatrix::I(), bounds, inverseVM);
return true;
}
void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
const SkRRect& inner, const SkPaint& paint) {
ASSERT_SINGLE_OWNER
@ -566,16 +627,20 @@ void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
if (outer.isEmpty()) {
return;
}
if (inner.isEmpty()) {
return this->drawRRect(draw, outer, paint);
}
SkStrokeRec stroke(paint);
if (stroke.isFillStyle() && !paint.getMaskFilter() && !paint.getPathEffect()) {
GrPaint grPaint;
if (!SkPaintToGrPaint(this->context(), paint, *draw.fMatrix, &grPaint)) {
if (this->drawFilledDRRect(*draw.fMatrix, outer, inner, paint)) {
return;
}
fDrawContext->drawDRRect(fClip, grPaint, *draw.fMatrix, outer, inner);
return;
}
SkPath path;

View File

@ -251,6 +251,9 @@ private:
const GrClip&,
const SkPaint&);
bool drawFilledDRRect(const SkMatrix& viewMatrix, const SkRRect& outer,
const SkRRect& inner, const SkPaint& paint);
void drawProducerNine(const SkDraw&, GrTextureProducer*, const SkIRect& center,
const SkRect& dst, const SkPaint&);