aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ops/GrAAStrokeRectOp.cpp
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-06-14 09:49:26 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-14 20:26:51 +0000
commit1ec03f33cf493352174c748662d4a3cca29f78fd (patch)
tree352c8f7fe900ea4c71846f3bc45a7f5a26d6469e /src/gpu/ops/GrAAStrokeRectOp.cpp
parentd99148623b1daecc54eca1e2df607a49f86c6fae (diff)
Converts remaining rect ops from GrLegacyMeshDrawOp to GrMeshDrawOp subclasses.
Consolidates op factory functions to a rewritten GrRectOpFactory. Removes GrRenderTargetContext::drawNonAAFilledRect() in favor of creating and adding ops directly by the callers. Change-Id: I57e5fc739bf4e92b4a4710c739e6d22cce82a479 Reviewed-on: https://skia-review.googlesource.com/17711 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/ops/GrAAStrokeRectOp.cpp')
-rw-r--r--src/gpu/ops/GrAAStrokeRectOp.cpp147
1 files changed, 77 insertions, 70 deletions
diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp
index 7af6c3e58e..82b4ec13fa 100644
--- a/src/gpu/ops/GrAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrAAStrokeRectOp.cpp
@@ -5,12 +5,12 @@
* found in the LICENSE file.
*/
-#include "GrAAStrokeRectOp.h"
-
#include "GrDefaultGeoProcFactory.h"
#include "GrOpFlushState.h"
+#include "GrRectOpFactory.h"
#include "GrResourceKey.h"
#include "GrResourceProvider.h"
+#include "GrSimpleMeshDrawOpHelper.h"
#include "SkStrokeRec.h"
GR_DECLARE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey);
@@ -110,13 +110,26 @@ static sk_sp<GrGeometryProcessor> create_stroke_rect_gp(bool tweakAlphaForCovera
viewMatrix);
}
-class AAStrokeRectOp final : public GrLegacyMeshDrawOp {
+namespace {
+
+class AAStrokeRectOp final : public GrMeshDrawOp {
+private:
+ using Helper = GrSimpleMeshDrawOpHelper;
+
public:
DEFINE_OP_CLASS_ID
- AAStrokeRectOp(GrColor color, const SkMatrix& viewMatrix, const SkRect& devOutside,
- const SkRect& devInside)
- : INHERITED(ClassID()), fViewMatrix(viewMatrix) {
+ static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
+ const SkRect& devOutside, const SkRect& devInside) {
+ return Helper::FactoryHelper<AAStrokeRectOp>(std::move(paint), viewMatrix, devOutside,
+ devInside);
+ }
+
+ AAStrokeRectOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix,
+ const SkRect& devOutside, const SkRect& devInside)
+ : INHERITED(ClassID())
+ , fHelper(helperArgs, GrAAType::kCoverage)
+ , fViewMatrix(viewMatrix) {
SkASSERT(!devOutside.isEmpty());
SkASSERT(!devInside.isEmpty());
@@ -125,30 +138,35 @@ public:
fMiterStroke = true;
}
- static std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, const SkMatrix& viewMatrix,
- const SkRect& rect, const SkStrokeRec& stroke) {
+ static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
+ const SkRect& rect, const SkStrokeRec& stroke) {
bool isMiter;
if (!allowed_stroke(stroke, &isMiter)) {
return nullptr;
}
+ return Helper::FactoryHelper<AAStrokeRectOp>(std::move(paint), viewMatrix, rect, stroke,
+ isMiter);
+ }
- AAStrokeRectOp* op = new AAStrokeRectOp();
- op->fMiterStroke = isMiter;
- RectInfo& info = op->fRects.push_back();
+ AAStrokeRectOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix,
+ const SkRect& rect, const SkStrokeRec& stroke, bool isMiter)
+ : INHERITED(ClassID())
+ , fHelper(helperArgs, GrAAType::kCoverage)
+ , fViewMatrix(viewMatrix) {
+ fMiterStroke = isMiter;
+ RectInfo& info = fRects.push_back();
compute_rects(&info.fDevOutside, &info.fDevOutsideAssist, &info.fDevInside,
&info.fDegenerate, viewMatrix, rect, stroke.getWidth(), isMiter);
info.fColor = color;
if (isMiter) {
- op->setBounds(info.fDevOutside, HasAABloat::kYes, IsZeroArea::kNo);
+ this->setBounds(info.fDevOutside, HasAABloat::kYes, IsZeroArea::kNo);
} else {
// The outer polygon of the bevel stroke is an octagon specified by the points of a
// pair of overlapping rectangles where one is wide and the other is narrow.
SkRect bounds = info.fDevOutside;
bounds.joinPossiblyEmptyRect(info.fDevOutsideAssist);
- op->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo);
+ this->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo);
}
- op->fViewMatrix = viewMatrix;
- return std::unique_ptr<GrLegacyMeshDrawOp>(op);
}
const char* name() const override { return "AAStrokeRect"; }
@@ -166,20 +184,18 @@ public:
info.fDevOutsideAssist.fBottom, info.fDevInside.fLeft, info.fDevInside.fTop,
info.fDevInside.fRight, info.fDevInside.fBottom, info.fDegenerate);
}
- string.append(DumpPipelineInfo(*this->pipeline()));
string.append(INHERITED::dumpInfo());
return string;
}
-private:
- AAStrokeRectOp() : INHERITED(ClassID()) {}
+ FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
- void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color,
- GrProcessorAnalysisCoverage* coverage) const override {
- color->setToConstant(fRects[0].fColor);
- *coverage = GrProcessorAnalysisCoverage::kSingleChannel;
+ bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override {
+ return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kSingleChannel,
+ &fRects.back().fColor);
}
- void applyPipelineOptimizations(const PipelineOptimizations&) override;
+
+private:
void onPrepareDraws(Target*) const override;
static const int kMiterIndexCnt = 3 * 24;
@@ -192,8 +208,6 @@ private:
static const GrBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider, bool miterStroke);
- bool usesLocalCoords() const { return fUsesLocalCoords; }
- bool canTweakAlphaForCoverage() const { return fCanTweakAlphaForCoverage; }
const SkMatrix& viewMatrix() const { return fViewMatrix; }
bool miterStroke() const { return fMiterStroke; }
@@ -221,29 +235,20 @@ private:
bool fDegenerate;
};
+ Helper fHelper;
SkSTArray<1, RectInfo, true> fRects;
- bool fUsesLocalCoords;
- bool fCanTweakAlphaForCoverage;
SkMatrix fViewMatrix;
bool fMiterStroke;
- typedef GrLegacyMeshDrawOp INHERITED;
+ typedef GrMeshDrawOp INHERITED;
};
-void AAStrokeRectOp::applyPipelineOptimizations(const PipelineOptimizations& optimizations) {
- optimizations.getOverrideColorIfSet(&fRects[0].fColor);
-
- fUsesLocalCoords = optimizations.readsLocalCoords();
- fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
- fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
-}
+} // anonymous namespace
void AAStrokeRectOp::onPrepareDraws(Target* target) const {
- bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
-
- sk_sp<GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlphaForCoverage,
+ sk_sp<GrGeometryProcessor> gp(create_stroke_rect_gp(fHelper.compatibleWithAlphaAsCoverage(),
this->viewMatrix(),
- this->usesLocalCoords()));
+ fHelper.usesLocalCoords()));
if (!gp) {
SkDebugf("Couldn't create GrGeometryProcessor\n");
return;
@@ -251,7 +256,7 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) const {
size_t vertexStride = gp->getVertexStride();
- SkASSERT(canTweakAlphaForCoverage
+ SkASSERT(fHelper.compatibleWithAlphaAsCoverage()
? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)
: vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
int innerVertexNum = 4;
@@ -284,9 +289,9 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) const {
info.fDevInside,
fMiterStroke,
info.fDegenerate,
- canTweakAlphaForCoverage);
+ fHelper.compatibleWithAlphaAsCoverage());
}
- helper.recordDraw(target, gp.get(), this->pipeline());
+ helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
}
const GrBuffer* AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvider,
@@ -386,8 +391,7 @@ const GrBuffer* AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvi
bool AAStrokeRectOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
AAStrokeRectOp* that = t->cast<AAStrokeRectOp>();
- if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
- that->bounds(), caps)) {
+ if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
return false;
}
@@ -397,18 +401,11 @@ bool AAStrokeRectOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
}
// We apply the viewmatrix to the rect points on the cpu. However, if the pipeline uses
- // local coords then we won't be able to combine. We could actually upload the viewmatrix
- // using vertex attributes in these cases, but haven't investigated that
- if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
+ // local coords then we won't be able to combine. TODO: Upload local coords as an attribute.
+ if (fHelper.usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
return false;
}
- // In the event of two ops, one who can tweak, one who cannot, we just fall back to not
- // tweaking.
- if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage()) {
- fCanTweakAlphaForCoverage = false;
- }
-
fRects.push_back_n(that->fRects.count(), that->fRects.begin());
this->joinBounds(*that);
return true;
@@ -569,31 +566,43 @@ void AAStrokeRectOp::generateAAStrokeRectGeometry(void* vertices,
}
}
-namespace GrAAStrokeRectOp {
+namespace GrRectOpFactory {
-std::unique_ptr<GrLegacyMeshDrawOp> MakeFillBetweenRects(GrColor color,
- const SkMatrix& viewMatrix,
- const SkRect& devOutside,
- const SkRect& devInside) {
- return std::unique_ptr<GrLegacyMeshDrawOp>(
- new AAStrokeRectOp(color, viewMatrix, devOutside, devInside));
-}
+std::unique_ptr<GrDrawOp> MakeAAFillNestedRects(GrPaint&& paint,
+ const SkMatrix& viewMatrix,
+ const SkRect rects[2]) {
+ SkASSERT(viewMatrix.rectStaysRect());
+ SkASSERT(!rects[0].isEmpty() && !rects[1].isEmpty());
-std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color,
- const SkMatrix& viewMatrix,
- const SkRect& rect,
- const SkStrokeRec& stroke) {
- return AAStrokeRectOp::Make(color, viewMatrix, rect, stroke);
+ SkRect devOutside, devInside;
+ viewMatrix.mapRect(&devOutside, rects[0]);
+ viewMatrix.mapRect(&devInside, rects[1]);
+ if (devInside.isEmpty()) {
+ if (devOutside.isEmpty()) {
+ return nullptr;
+ }
+ return MakeAAFillWithDevRect(std::move(paint), viewMatrix, rects[0], devOutside);
+ }
+
+ return AAStrokeRectOp::Make(std::move(paint), viewMatrix, devOutside, devInside);
}
+
+std::unique_ptr<GrDrawOp> MakeAAStroke(GrPaint&& paint,
+ const SkMatrix& viewMatrix,
+ const SkRect& rect,
+ const SkStrokeRec& stroke) {
+ return AAStrokeRectOp::Make(std::move(paint), viewMatrix, rect, stroke);
}
+} // namespace GrRectOpFactory
+
///////////////////////////////////////////////////////////////////////////////////////////////////
#if GR_TEST_UTILS
#include "GrDrawOpTest.h"
-GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) {
+GR_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) {
bool miterStroke = random->nextBool();
// Create either a empty rect or a non-empty rect.
@@ -602,14 +611,12 @@ GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) {
SkScalar minDim = SkMinScalar(rect.width(), rect.height());
SkScalar strokeWidth = random->nextUScalar1() * minDim;
- GrColor color = GrRandomColor(random);
-
SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
rec.setStrokeStyle(strokeWidth);
rec.setStrokeParams(SkPaint::kButt_Cap,
miterStroke ? SkPaint::kMiter_Join : SkPaint::kBevel_Join, 1.f);
SkMatrix matrix = GrTest::TestMatrixRectStaysRect(random);
- return GrAAStrokeRectOp::Make(color, matrix, rect, rec);
+ return GrRectOpFactory::MakeAAStroke(std::move(paint), matrix, rect, rec);
}
#endif