Move all non-AA fill rect ops off of GrLegacyMeshDrawOp.

This adds perspective to GrNewNonAAFillRectOp, renames it to GrNonAAFillRectOp, and deletes the previous version of that namespace.

Change-Id: I20f35bf019f9c9105e6ec83dda11328451138109
Reviewed-on: https://skia-review.googlesource.com/15634
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2017-05-08 10:43:33 -04:00 committed by Skia Commit-Bot
parent 0418a888d3
commit ac70f84e7f
22 changed files with 330 additions and 683 deletions

View File

@ -13,7 +13,7 @@
#include "SkRRect.h"
#include "effects/GrRRectEffect.h"
#include "ops/GrDrawOp.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
namespace skiagm {
@ -81,16 +81,16 @@ protected:
SkASSERT(fp);
if (fp) {
GrPaint grPaint;
grPaint.setColor4f(GrColor4f(0, 0, 0, 1.f));
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
grPaint.addCoverageFragmentProcessor(std::move(fp));
SkRect bounds = testBounds;
bounds.offset(SkIntToScalar(x), SkIntToScalar(y));
std::unique_ptr<GrLegacyMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
0xff000000, SkMatrix::I(), bounds, nullptr, nullptr));
renderTargetContext->priv().testingOnly_addLegacyMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));
renderTargetContext->priv().testingOnly_addDrawOp(
GrNonAAFillRectOp::Make(std::move(grPaint), SkMatrix::I(), bounds,
nullptr, nullptr, GrAAType::kNone));
}
canvas->restore();
x = x + fTestOffsetX;

View File

@ -18,7 +18,7 @@
#include "SkGradientShader.h"
#include "effects/GrConstColorProcessor.h"
#include "ops/GrDrawOp.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
namespace skiagm {
/**
@ -109,11 +109,9 @@ protected:
sk_sp<GrFragmentProcessor> fp(GrConstColorProcessor::Make(color, mode));
grPaint.addColorFragmentProcessor(std::move(fp));
std::unique_ptr<GrLegacyMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
grPaint.getColor(), viewMatrix, renderRect, nullptr, nullptr));
renderTargetContext->priv().testingOnly_addLegacyMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));
renderTargetContext->priv().testingOnly_addDrawOp(
GrNonAAFillRectOp::Make(std::move(grPaint), viewMatrix, renderRect,
nullptr, nullptr, GrAAType::kNone));
// Draw labels for the input to the processor and the processor to the right of
// the test rect. The input label appears above the processor label.

View File

@ -17,7 +17,7 @@
#include "GrRenderTargetContextPriv.h"
#include "GrTextureProxy.h"
#include "effects/GrSimpleTextureEffect.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
// Basic test of Ganesh's ETC1 support
class ETC1GM : public skiagm::GM {
@ -97,10 +97,8 @@ protected:
SkRect rect = SkRect::MakeXYWH(kPad, kPad, kTexWidth, kTexHeight);
std::unique_ptr<GrLegacyMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
GrColor_WHITE, SkMatrix::I(), rect, nullptr, nullptr));
renderTargetContext->priv().testingOnly_addLegacyMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));
renderTargetContext->priv().testingOnly_addDrawOp(GrNonAAFillRectOp::Make(
std::move(grPaint), SkMatrix::I(), rect, nullptr, nullptr, GrAAType::kNone));
}
private:

View File

@ -12,7 +12,7 @@
#include "GrRenderTargetContextPriv.h"
#include "effects/GrRRectEffect.h"
#include "ops/GrDrawOp.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
#endif
#include "SkRRect.h"
@ -111,14 +111,18 @@ protected:
GrPaint grPaint;
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
grPaint.addCoverageFragmentProcessor(std::move(fp));
grPaint.setColor4f(GrColor4f(0, 0, 0, 1.f));
SkRect bounds = rrect.getBounds();
bounds.outset(2.f, 2.f);
std::unique_ptr<GrLegacyMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
0xff000000, SkMatrix::I(), bounds, nullptr, nullptr));
renderTargetContext->priv().testingOnly_addLegacyMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));
renderTargetContext->priv().testingOnly_addDrawOp(
GrNonAAFillRectOp::Make(std::move(grPaint),
SkMatrix::I(),
bounds,
nullptr,
nullptr,
GrAAType::kNone));
} else {
drew = false;
}

View File

@ -18,7 +18,7 @@
#include "SkGradientShader.h"
#include "effects/GrTextureDomain.h"
#include "ops/GrDrawOp.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
namespace skiagm {
/**
@ -133,11 +133,9 @@ protected:
}
const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y);
grPaint.addColorFragmentProcessor(std::move(fp));
std::unique_ptr<GrLegacyMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
GrColor_WHITE, viewMatrix, renderRect, nullptr, nullptr));
renderTargetContext->priv().testingOnly_addLegacyMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));
renderTargetContext->priv().testingOnly_addDrawOp(
GrNonAAFillRectOp::Make(std::move(grPaint), viewMatrix, renderRect,
nullptr, nullptr, GrAAType::kNone));
x += renderRect.width() + kTestPad;
}
y += renderRect.height() + kTestPad;

View File

@ -19,7 +19,7 @@
#include "SkGradientShader.h"
#include "effects/GrYUVEffect.h"
#include "ops/GrDrawOp.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
#define YSIZE 8
#define USIZE 4
@ -132,10 +132,9 @@ protected:
grPaint.addColorFragmentProcessor(std::move(fp));
SkMatrix viewMatrix;
viewMatrix.setTranslate(x, y);
std::unique_ptr<GrLegacyMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
GrColor_WHITE, viewMatrix, renderRect, nullptr, nullptr));
renderTargetContext->priv().testingOnly_addLegacyMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));
renderTargetContext->priv().testingOnly_addDrawOp(
GrNonAAFillRectOp::Make(std::move(grPaint), viewMatrix, renderRect,
nullptr, nullptr, GrAAType::kNone));
}
x += renderRect.width() + kTestPad;
}
@ -257,10 +256,9 @@ protected:
SkMatrix viewMatrix;
viewMatrix.setTranslate(x, y);
grPaint.addColorFragmentProcessor(fp);
std::unique_ptr<GrLegacyMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
GrColor_WHITE, viewMatrix, renderRect, nullptr, nullptr));
renderTargetContext->priv().testingOnly_addLegacyMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));
renderTargetContext->priv().testingOnly_addDrawOp(
GrNonAAFillRectOp::Make(std::move(grPaint), viewMatrix, renderRect, nullptr,
nullptr, GrAAType::kNone));
}
}
}

View File

@ -263,9 +263,6 @@ skia_gpu_sources = [
"$_src/gpu/ops/GrMSAAPathRenderer.h",
"$_src/gpu/ops/GrNonAAFillRectOp.h",
"$_src/gpu/ops/GrNonAAFillRectOp.cpp",
"$_src/gpu/ops/GrNewNonAAFillRectOp.h",
"$_src/gpu/ops/GrNewNonAAFillRectOp.cpp",
"$_src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp",
"$_src/gpu/ops/GrNonAAStrokeRectOp.cpp",
"$_src/gpu/ops/GrNonAAStrokeRectOp.h",
"$_src/gpu/ops/GrLatticeOp.cpp",

View File

@ -32,7 +32,7 @@
#include "ops/GrDrawOp.h"
#include "ops/GrDrawVerticesOp.h"
#include "ops/GrLatticeOp.h"
#include "ops/GrNewNonAAFillRectOp.h"
#include "ops/GrNonAAFillRectOp.h"
#include "ops/GrOp.h"
#include "ops/GrOvalOpFactory.h"
#include "ops/GrRectOpFactory.h"
@ -1274,19 +1274,9 @@ void GrRenderTargetContext::drawNonAAFilledRect(const GrClip& clip,
GrAAType hwOrNoneAAType) {
SkASSERT(GrAAType::kCoverage != hwOrNoneAAType);
SkASSERT(GrAAType::kNone == hwOrNoneAAType || this->isStencilBufferMultisampled());
if (!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective())) {
std::unique_ptr<GrDrawOp> op = GrNewNonAAFillRectOp::Make(
std::move(paint), viewMatrix, rect, localRect, localMatrix, hwOrNoneAAType, ss);
this->addDrawOp(clip, std::move(op));
return;
}
std::unique_ptr<GrLegacyMeshDrawOp> op = GrRectOpFactory::MakeNonAAFill(
paint.getColor(), viewMatrix, rect, localRect, localMatrix);
GrPipelineBuilder pipelineBuilder(std::move(paint), hwOrNoneAAType);
if (ss) {
pipelineBuilder.setUserStencil(ss);
}
this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
std::unique_ptr<GrDrawOp> op = GrNonAAFillRectOp::Make(
std::move(paint), viewMatrix, rect, localRect, localMatrix, hwOrNoneAAType, ss);
this->addDrawOp(clip, std::move(op));
}
// Can 'path' be drawn as a pair of filled nested rectangles?

View File

@ -107,6 +107,8 @@ public:
const GrUserStencilSettings* = nullptr,
bool snapToCenters = false);
uint32_t testingOnly_addDrawOp(std::unique_ptr<GrDrawOp>);
bool refsWrappedObjects() const {
return fRenderTargetContext->fRenderTargetProxy->refsWrappedObjects();
}

View File

@ -19,7 +19,7 @@
#include "SkDistanceFieldGen.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
/*
* Convert a boolean operation into a transfer mode code
@ -173,12 +173,10 @@ void GrSWMaskHelper::DrawToTargetWithShapeMask(sk_sp<GrTextureProxy> proxy,
SkMatrix maskMatrix = SkMatrix::MakeTrans(SkIntToScalar(-textureOriginInDeviceSpace.fX),
SkIntToScalar(-textureOriginInDeviceSpace.fY));
maskMatrix.preConcat(viewMatrix);
std::unique_ptr<GrLegacyMeshDrawOp> op = GrRectOpFactory::MakeNonAAFill(
paint.getColor(), SkMatrix::I(), dstRect, nullptr, &invert);
paint.addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(
resourceProvider, std::move(proxy), nullptr, maskMatrix,
GrSamplerParams::kNone_FilterMode));
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
pipelineBuilder.setUserStencil(&userStencilSettings);
renderTargetContext->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
renderTargetContext->addDrawOp(
clip, GrNonAAFillRectOp::Make(std::move(paint), SkMatrix::I(), dstRect, nullptr,
&invert, GrAAType::kNone, &userStencilSettings));
}

View File

@ -12,7 +12,7 @@
#include "GrPipelineBuilder.h"
#include "GrResourceProvider.h"
#include "GrSWMaskHelper.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
////////////////////////////////////////////////////////////////////////////////
bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
@ -76,12 +76,9 @@ void GrSoftwarePathRenderer::DrawNonAARect(GrRenderTargetContext* renderTargetCo
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkMatrix& localMatrix) {
std::unique_ptr<GrLegacyMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
paint.getColor(), viewMatrix, rect, nullptr, &localMatrix));
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
pipelineBuilder.setUserStencil(&userStencilSettings);
renderTargetContext->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
renderTargetContext->addDrawOp(
clip, GrNonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, nullptr, &localMatrix,
GrAAType::kNone, &userStencilSettings));
}
void GrSoftwarePathRenderer::DrawAroundInvPath(GrRenderTargetContext* renderTargetContext,

View File

@ -22,7 +22,7 @@
#include "SkTraceEvent.h"
#include "ops/GrMeshDrawOp.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
GrDefaultPathRenderer::GrDefaultPathRenderer() {
}
@ -523,12 +523,10 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget
}
const SkMatrix& viewM = (reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() :
viewMatrix;
std::unique_ptr<GrLegacyMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
paint.getColor(), viewM, bounds, nullptr, &localMatrix));
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
pipelineBuilder.setUserStencil(passes[p]);
renderTargetContext->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip,
std::move(op));
renderTargetContext->addDrawOp(
clip,
GrNonAAFillRectOp::Make(std::move(paint), viewM, bounds, nullptr, &localMatrix,
aaType, passes[p]));
} else {
std::unique_ptr<GrLegacyMeshDrawOp> op =
DefaultPathOp::Make(paint.getColor(), path, srcSpaceTol, newCoverage,

View File

@ -26,7 +26,7 @@
#include "glsl/GrGLSLUtil.h"
#include "glsl/GrGLSLVertexShaderBuilder.h"
#include "ops/GrMeshDrawOp.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
static const float kTolerance = 0.5f;
@ -668,13 +668,10 @@ bool GrMSAAPathRenderer::internalDrawPath(GrRenderTargetContext* renderTargetCon
}
const SkMatrix& viewM =
(reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() : viewMatrix;
std::unique_ptr<GrLegacyMeshDrawOp> op(GrRectOpFactory::MakeNonAAFill(
paint.getColor(), viewM, bounds, nullptr, &localMatrix));
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
pipelineBuilder.setUserStencil(passes[1]);
renderTargetContext->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
renderTargetContext->addDrawOp(
clip,
GrNonAAFillRectOp::Make(std::move(paint), viewM, bounds, nullptr, &localMatrix,
aaType, passes[1]));
}
return true;
}

View File

@ -1,198 +0,0 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrNewNonAAFillRectOp.h"
#include "GrAppliedClip.h"
#include "GrColor.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrMeshDrawOp.h"
#include "GrOpFlushState.h"
#include "GrPrimitiveProcessor.h"
#include "GrQuad.h"
#include "GrResourceProvider.h"
#include "GrSimpleMeshDrawOpHelper.h"
#include "SkMatrixPriv.h"
static const int kVertsPerRect = 4;
static const int kIndicesPerRect = 6;
/** We always use per-vertex colors so that rects can be combined across color changes. Sometimes
we have explicit local coords and sometimes not. We *could* always provide explicit local
coords and just duplicate the positions when the caller hasn't provided a local coord rect,
but we haven't seen a use case which frequently switches between local rect and no local
rect draws.
The vertex attrib order is always pos, color, [local coords].
*/
static sk_sp<GrGeometryProcessor> make_gp() {
using namespace GrDefaultGeoProcFactory;
return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type,
LocalCoords::kHasExplicit_Type, SkMatrix::I());
}
static void tesselate(intptr_t vertices,
size_t vertexStride,
GrColor color,
const SkMatrix* viewMatrix,
const SkRect& rect,
const GrQuad* localQuad) {
SkPoint* positions = reinterpret_cast<SkPoint*>(vertices);
positions->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vertexStride);
if (viewMatrix) {
SkMatrixPriv::MapPointsWithStride(*viewMatrix, positions, vertexStride, kVertsPerRect);
}
// Setup local coords
// TODO we should only do this if local coords are being read
if (localQuad) {
static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
for (int i = 0; i < kVertsPerRect; i++) {
SkPoint* coords =
reinterpret_cast<SkPoint*>(vertices + kLocalOffset + i * vertexStride);
*coords = localQuad->point(i);
}
}
static const int kColorOffset = sizeof(SkPoint);
GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset);
for (int j = 0; j < 4; ++j) {
*vertColor = color;
vertColor = (GrColor*)((intptr_t)vertColor + vertexStride);
}
}
class NewNonAAFillRectOp final : public GrMeshDrawOp {
private:
using Helper = GrSimpleMeshDrawOpHelperWithStencil;
public:
DEFINE_OP_CLASS_ID
NewNonAAFillRectOp() = delete;
static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
const SkRect& rect, const SkRect* localRect,
const SkMatrix* localMatrix, GrAAType aaType,
const GrUserStencilSettings* stencilSettings) {
SkASSERT(GrAAType::kCoverage != aaType);
return Helper::FactoryHelper<NewNonAAFillRectOp>(std::move(paint), viewMatrix, rect,
localRect, localMatrix, aaType,
stencilSettings);
}
const char* name() const override { return "NonAAFillRectOp"; }
SkString dumpInfo() const override {
SkString str;
str.append(GrMeshDrawOp::dumpInfo());
str.appendf("# combined: %d\n", fRects.count());
for (int i = 0; i < fRects.count(); ++i) {
const RectInfo& info = fRects[i];
str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
info.fColor, info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight,
info.fRect.fBottom);
}
return str;
}
bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override {
GrColor* color = &fRects.front().fColor;
return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
}
FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
NewNonAAFillRectOp(const Helper::MakeArgs& args, GrColor color, const SkMatrix& viewMatrix,
const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix,
GrAAType aaType, const GrUserStencilSettings* stencilSettings)
: INHERITED(ClassID()), fHelper(args, aaType, stencilSettings) {
SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective()));
RectInfo& info = fRects.push_back();
info.fColor = color;
info.fViewMatrix = viewMatrix;
info.fRect = rect;
if (localRect && localMatrix) {
info.fLocalQuad.setFromMappedRect(*localRect, *localMatrix);
} else if (localRect) {
info.fLocalQuad.set(*localRect);
} else if (localMatrix) {
info.fLocalQuad.setFromMappedRect(rect, *localMatrix);
} else {
info.fLocalQuad.set(rect);
}
this->setTransformedBounds(fRects[0].fRect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
}
private:
void onPrepareDraws(Target* target) const override {
sk_sp<GrGeometryProcessor> gp = make_gp();
if (!gp) {
SkDebugf("Couldn't create GrGeometryProcessor\n");
return;
}
SkASSERT(gp->getVertexStride() ==
sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr));
size_t vertexStride = gp->getVertexStride();
int rectCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer());
PatternHelper helper;
void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
indexBuffer.get(), kVertsPerRect, kIndicesPerRect, rectCount);
if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
for (int i = 0; i < rectCount; i++) {
intptr_t verts =
reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
tesselate(verts, vertexStride, fRects[i].fColor, &fRects[i].fViewMatrix,
fRects[i].fRect, &fRects[i].fLocalQuad);
}
helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
NewNonAAFillRectOp* that = t->cast<NewNonAAFillRectOp>();
if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
return false;
}
fRects.push_back_n(that->fRects.count(), that->fRects.begin());
this->joinBounds(*that);
return true;
}
struct RectInfo {
GrColor fColor;
SkMatrix fViewMatrix;
SkRect fRect;
GrQuad fLocalQuad;
};
Helper fHelper;
SkSTArray<1, RectInfo, true> fRects;
typedef GrMeshDrawOp INHERITED;
};
namespace GrNewNonAAFillRectOp {
std::unique_ptr<GrDrawOp> Make(GrPaint&& paint,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix,
GrAAType aaType,
const GrUserStencilSettings* stencilSettings) {
return NewNonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, localRect, localMatrix,
aaType, stencilSettings);
}
}; // namespace GrNewNonAAFillRectOp
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -1,31 +0,0 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrNewNonAAFillRectOp_DEFINED
#define GrNewNonAAFillRectOp_DEFINED
#include <memory>
#include "GrColor.h"
class GrDrawOp;
class GrPaint;
class SkMatrix;
struct SkRect;
struct GrUserStencilSettings;
enum class GrAAType : unsigned;
namespace GrNewNonAAFillRectOp {
std::unique_ptr<GrDrawOp> Make(GrPaint&&,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix,
GrAAType,
const GrUserStencilSettings* = nullptr);
};
#endif

View File

@ -1,12 +1,12 @@
/*
* Copyright 2015 Google Inc.
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrNonAAFillRectOp.h"
#include "GrAppliedClip.h"
#include "GrColor.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrMeshDrawOp.h"
@ -14,11 +14,11 @@
#include "GrPrimitiveProcessor.h"
#include "GrQuad.h"
#include "GrResourceProvider.h"
#include "GrSimpleMeshDrawOpHelper.h"
#include "SkMatrixPriv.h"
static const int kVertsPerInstance = 4;
static const int kIndicesPerInstance = 6;
static const int kVertsPerRect = 4;
static const int kIndicesPerRect = 6;
/** We always use per-vertex colors so that rects can be combined across color changes. Sometimes
we have explicit local coords and sometimes not. We *could* always provide explicit local
@ -34,6 +34,35 @@ static sk_sp<GrGeometryProcessor> make_gp() {
LocalCoords::kHasExplicit_Type, SkMatrix::I());
}
static sk_sp<GrGeometryProcessor> make_perspective_gp(const SkMatrix& viewMatrix,
bool hasExplicitLocalCoords,
const SkMatrix* localMatrix) {
SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
using namespace GrDefaultGeoProcFactory;
// If we have perspective on the viewMatrix then we won't map on the CPU, nor will we map
// the local rect on the cpu (in case the localMatrix also has perspective).
// Otherwise, if we have a local rect, then we apply the localMatrix directly to the localRect
// to generate vertex local coords
if (viewMatrix.hasPerspective()) {
LocalCoords localCoords(hasExplicitLocalCoords ? LocalCoords::kHasExplicit_Type
: LocalCoords::kUsePosition_Type,
localMatrix);
return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
Coverage::kSolid_Type, localCoords, viewMatrix);
} else if (hasExplicitLocalCoords) {
LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix);
return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
Coverage::kSolid_Type, localCoords, SkMatrix::I());
} else {
LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix);
return GrDefaultGeoProcFactory::MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type,
Coverage::kSolid_Type, localCoords,
viewMatrix);
}
}
static void tesselate(intptr_t vertices,
size_t vertexStride,
GrColor color,
@ -45,14 +74,14 @@ static void tesselate(intptr_t vertices,
positions->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vertexStride);
if (viewMatrix) {
SkMatrixPriv::MapPointsWithStride(*viewMatrix, positions, vertexStride, kVertsPerInstance);
SkMatrixPriv::MapPointsWithStride(*viewMatrix, positions, vertexStride, kVertsPerRect);
}
// Setup local coords
// TODO we should only do this if local coords are being read
if (localQuad) {
static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
for (int i = 0; i < kVertsPerInstance; i++) {
for (int i = 0; i < kVertsPerRect; i++) {
SkPoint* coords =
reinterpret_cast<SkPoint*>(vertices + kLocalOffset + i * vertexStride);
*coords = localQuad->point(i);
@ -67,13 +96,28 @@ static void tesselate(intptr_t vertices,
}
}
class NonAAFillRectOp final : public GrLegacyMeshDrawOp {
public:
DEFINE_OP_CLASS_ID
namespace {
NonAAFillRectOp(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
const SkRect* localRect, const SkMatrix* localMatrix)
: INHERITED(ClassID()) {
class NonAAFillRectOp final : public GrMeshDrawOp {
private:
using Helper = GrSimpleMeshDrawOpHelperWithStencil;
public:
static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
const SkRect& rect, const SkRect* localRect,
const SkMatrix* localMatrix, GrAAType aaType,
const GrUserStencilSettings* stencilSettings) {
SkASSERT(GrAAType::kCoverage != aaType);
return Helper::FactoryHelper<NonAAFillRectOp>(std::move(paint), viewMatrix, rect, localRect,
localMatrix, aaType, stencilSettings);
}
NonAAFillRectOp() = delete;
NonAAFillRectOp(const Helper::MakeArgs& args, GrColor color, const SkMatrix& viewMatrix,
const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix,
GrAAType aaType, const GrUserStencilSettings* stencilSettings)
: INHERITED(ClassID()), fHelper(args, aaType, stencilSettings) {
SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective()));
RectInfo& info = fRects.push_back();
info.fColor = color;
@ -95,7 +139,7 @@ public:
SkString dumpInfo() const override {
SkString str;
str.append(INHERITED::dumpInfo());
str.append(GrMeshDrawOp::dumpInfo());
str.appendf("# combined: %d\n", fRects.count());
for (int i = 0; i < fRects.count(); ++i) {
const RectInfo& info = fRects[i];
@ -103,23 +147,19 @@ public:
info.fColor, info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight,
info.fRect.fBottom);
}
str.append(DumpPipelineInfo(*this->pipeline()));
return str;
}
bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override {
GrColor* color = &fRects.front().fColor;
return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
}
FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
DEFINE_OP_CLASS_ID
private:
NonAAFillRectOp() : INHERITED(ClassID()) {}
void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color,
GrProcessorAnalysisCoverage* coverage) const override {
color->setToConstant(fRects[0].fColor);
*coverage = GrProcessorAnalysisCoverage::kNone;
}
void applyPipelineOptimizations(const PipelineOptimizations& optimizations) override {
optimizations.getOverrideColorIfSet(&fRects[0].fColor);
}
void onPrepareDraws(Target* target) const override {
sk_sp<GrGeometryProcessor> gp = make_gp();
if (!gp) {
@ -130,34 +170,31 @@ private:
sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr));
size_t vertexStride = gp->getVertexStride();
int instanceCount = fRects.count();
int rectCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer());
PatternHelper helper;
void* vertices =
helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
kVertsPerInstance, kIndicesPerInstance, instanceCount);
void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
indexBuffer.get(), kVertsPerRect, kIndicesPerRect, rectCount);
if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
for (int i = 0; i < instanceCount; i++) {
for (int i = 0; i < rectCount; i++) {
intptr_t verts =
reinterpret_cast<intptr_t>(vertices) + i * kVertsPerInstance * vertexStride;
reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
tesselate(verts, vertexStride, fRects[i].fColor, &fRects[i].fViewMatrix,
fRects[i].fRect, &fRects[i].fLocalQuad);
}
helper.recordDraw(target, gp.get(), this->pipeline());
helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
NonAAFillRectOp* that = t->cast<NonAAFillRectOp>();
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
that->bounds(), caps)) {
if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
return false;
}
fRects.push_back_n(that->fRects.count(), that->fRects.begin());
this->joinBounds(*that);
return true;
@ -170,43 +207,173 @@ private:
GrQuad fLocalQuad;
};
Helper fHelper;
SkSTArray<1, RectInfo, true> fRects;
typedef GrLegacyMeshDrawOp INHERITED;
typedef GrMeshDrawOp INHERITED;
};
// We handle perspective in the local matrix or viewmatrix with special ops.
class NonAAFillRectPerspectiveOp final : public GrMeshDrawOp {
private:
using Helper = GrSimpleMeshDrawOpHelperWithStencil;
public:
static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
const SkRect& rect, const SkRect* localRect,
const SkMatrix* localMatrix, GrAAType aaType,
const GrUserStencilSettings* stencilSettings) {
SkASSERT(GrAAType::kCoverage != aaType);
return Helper::FactoryHelper<NonAAFillRectPerspectiveOp>(std::move(paint), viewMatrix, rect,
localRect, localMatrix, aaType,
stencilSettings);
}
NonAAFillRectPerspectiveOp() = delete;
NonAAFillRectPerspectiveOp(const Helper::MakeArgs& args, GrColor color,
const SkMatrix& viewMatrix, const SkRect& rect,
const SkRect* localRect, const SkMatrix* localMatrix,
GrAAType aaType, const GrUserStencilSettings* stencilSettings)
: INHERITED(ClassID())
, fHelper(args, aaType, stencilSettings)
, fViewMatrix(viewMatrix) {
SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
RectInfo& info = fRects.push_back();
info.fColor = color;
info.fRect = rect;
fHasLocalRect = SkToBool(localRect);
fHasLocalMatrix = SkToBool(localMatrix);
if (fHasLocalMatrix) {
fLocalMatrix = *localMatrix;
}
if (fHasLocalRect) {
info.fLocalRect = *localRect;
}
this->setTransformedBounds(rect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
}
const char* name() const override { return "NonAAFillRectPerspectiveOp"; }
SkString dumpInfo() const override {
SkString str;
str.appendf("# combined: %d\n", fRects.count());
for (int i = 0; i < fRects.count(); ++i) {
const RectInfo& geo = fRects[0];
str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
geo.fColor, geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight,
geo.fRect.fBottom);
}
str.append(INHERITED::dumpInfo());
return str;
}
bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override {
GrColor* color = &fRects.front().fColor;
return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, color);
}
FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
DEFINE_OP_CLASS_ID
private:
void onPrepareDraws(Target* target) const override {
sk_sp<GrGeometryProcessor> gp = make_perspective_gp(
fViewMatrix, fHasLocalRect, fHasLocalMatrix ? &fLocalMatrix : nullptr);
if (!gp) {
SkDebugf("Couldn't create GrGeometryProcessor\n");
return;
}
SkASSERT(fHasLocalRect
? gp->getVertexStride() ==
sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)
: gp->getVertexStride() ==
sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
size_t vertexStride = gp->getVertexStride();
int rectCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer());
PatternHelper helper;
void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
indexBuffer.get(), kVertsPerRect, kIndicesPerRect, rectCount);
if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
for (int i = 0; i < rectCount; i++) {
const RectInfo& info = fRects[i];
intptr_t verts =
reinterpret_cast<intptr_t>(vertices) + i * kVertsPerRect * vertexStride;
if (fHasLocalRect) {
GrQuad quad(info.fLocalRect);
tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, &quad);
} else {
tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, nullptr);
}
}
helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
NonAAFillRectPerspectiveOp* that = t->cast<NonAAFillRectPerspectiveOp>();
if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
return false;
}
// We could combine across perspective vm changes if we really wanted to.
if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) {
return false;
}
if (fHasLocalRect != that->fHasLocalRect) {
return false;
}
if (fHasLocalMatrix && !fLocalMatrix.cheapEqualTo(that->fLocalMatrix)) {
return false;
}
fRects.push_back_n(that->fRects.count(), that->fRects.begin());
this->joinBounds(*that);
return true;
}
struct RectInfo {
SkRect fRect;
GrColor fColor;
SkRect fLocalRect;
};
SkSTArray<1, RectInfo, true> fRects;
Helper fHelper;
bool fHasLocalMatrix;
bool fHasLocalRect;
SkMatrix fLocalMatrix;
SkMatrix fViewMatrix;
typedef GrMeshDrawOp INHERITED;
};
} // anonymous namespace
namespace GrNonAAFillRectOp {
std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) {
return std::unique_ptr<GrLegacyMeshDrawOp>(
new NonAAFillRectOp(color, viewMatrix, rect, localRect, localMatrix));
std::unique_ptr<GrDrawOp> Make(GrPaint&& paint,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix,
GrAAType aaType,
const GrUserStencilSettings* stencilSettings) {
if (!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective())) {
return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, localRect, localMatrix,
aaType, stencilSettings);
} else {
return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, localRect,
localMatrix, aaType, stencilSettings);
}
}
};
}; // namespace GrNonAAFillRectOp
///////////////////////////////////////////////////////////////////////////////////////////////////
#if GR_TEST_UTILS
#include "GrDrawOpTest.h"
DRAW_OP_TEST_DEFINE(NonAAFillRectOp) {
GrColor color = GrRandomColor(random);
SkRect rect = GrTest::TestRect(random);
SkRect localRect = GrTest::TestRect(random);
SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
SkMatrix localMatrix = GrTest::TestMatrix(random);
bool hasLocalRect = random->nextBool();
bool hasLocalMatrix = random->nextBool();
return GrNonAAFillRectOp::Make(color,
viewMatrix,
rect,
hasLocalRect ? &localRect : nullptr,
hasLocalMatrix ? &localMatrix : nullptr);
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 Google Inc.
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
@ -8,26 +8,24 @@
#ifndef GrNonAAFillRectOp_DEFINED
#define GrNonAAFillRectOp_DEFINED
#include <memory>
#include "GrColor.h"
#include "SkRefCnt.h"
class GrLegacyMeshDrawOp;
class GrDrawOp;
class GrPaint;
class SkMatrix;
struct SkRect;
struct GrUserStencilSettings;
enum class GrAAType : unsigned;
namespace GrNonAAFillRectOp {
std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix);
std::unique_ptr<GrLegacyMeshDrawOp> MakeWithPerspective(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix);
std::unique_ptr<GrDrawOp> Make(GrPaint&&,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix,
GrAAType,
const GrUserStencilSettings* = nullptr);
};
#endif

View File

@ -1,258 +0,0 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrNonAAFillRectOp.h"
#include "GrColor.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrMeshDrawOp.h"
#include "GrOpFlushState.h"
#include "GrPrimitiveProcessor.h"
#include "GrQuad.h"
#include "GrResourceProvider.h"
static const int kVertsPerInstance = 4;
static const int kIndicesPerInstance = 6;
/** We always use per-vertex colors so that rects can be combined across color changes. Sometimes
we have explicit local coords and sometimes not. We *could* always provide explicit local
coords and just duplicate the positions when the caller hasn't provided a local coord rect,
but we haven't seen a use case which frequently switches between local rect and no local
rect draws.
The vertex attrib order is always pos, color, [local coords].
*/
static sk_sp<GrGeometryProcessor> make_persp_gp(const SkMatrix& viewMatrix,
bool hasExplicitLocalCoords,
const SkMatrix* localMatrix) {
SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
using namespace GrDefaultGeoProcFactory;
// If we have perspective on the viewMatrix then we won't map on the CPU, nor will we map
// the local rect on the cpu (in case the localMatrix also has perspective).
// Otherwise, if we have a local rect, then we apply the localMatrix directly to the localRect
// to generate vertex local coords
if (viewMatrix.hasPerspective()) {
LocalCoords localCoords(hasExplicitLocalCoords ? LocalCoords::kHasExplicit_Type
: LocalCoords::kUsePosition_Type,
localMatrix);
return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
Coverage::kSolid_Type, localCoords, viewMatrix);
} else if (hasExplicitLocalCoords) {
LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix);
return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type,
Coverage::kSolid_Type, localCoords, SkMatrix::I());
} else {
LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix);
return GrDefaultGeoProcFactory::MakeForDeviceSpace(Color::kPremulGrColorAttribute_Type,
Coverage::kSolid_Type, localCoords,
viewMatrix);
}
}
static void tesselate(intptr_t vertices,
size_t vertexStride,
GrColor color,
const SkMatrix* viewMatrix,
const SkRect& rect,
const GrQuad* localQuad) {
SkPoint* positions = reinterpret_cast<SkPoint*>(vertices);
positions->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vertexStride);
if (viewMatrix) {
viewMatrix->mapPointsWithStride(positions, vertexStride, kVertsPerInstance);
}
// Setup local coords
// TODO we should only do this if local coords are being read
if (localQuad) {
static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
for (int i = 0; i < kVertsPerInstance; i++) {
SkPoint* coords =
reinterpret_cast<SkPoint*>(vertices + kLocalOffset + i * vertexStride);
*coords = localQuad->point(i);
}
}
static const int kColorOffset = sizeof(SkPoint);
GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset);
for (int j = 0; j < 4; ++j) {
*vertColor = color;
vertColor = (GrColor*)((intptr_t)vertColor + vertexStride);
}
}
// We handle perspective in the local matrix or viewmatrix with special ops.
class NonAAFillRectPerspectiveOp final : public GrLegacyMeshDrawOp {
public:
DEFINE_OP_CLASS_ID
NonAAFillRectPerspectiveOp(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
const SkRect* localRect, const SkMatrix* localMatrix)
: INHERITED(ClassID()), fViewMatrix(viewMatrix) {
SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
RectInfo& info = fRects.push_back();
info.fColor = color;
info.fRect = rect;
fHasLocalRect = SkToBool(localRect);
fHasLocalMatrix = SkToBool(localMatrix);
if (fHasLocalMatrix) {
fLocalMatrix = *localMatrix;
}
if (fHasLocalRect) {
info.fLocalRect = *localRect;
}
this->setTransformedBounds(rect, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
}
const char* name() const override { return "NonAAFillRectPerspectiveOp"; }
SkString dumpInfo() const override {
SkString str;
str.appendf("# combined: %d\n", fRects.count());
for (int i = 0; i < fRects.count(); ++i) {
const RectInfo& geo = fRects[0];
str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
geo.fColor, geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight,
geo.fRect.fBottom);
}
str.append(DumpPipelineInfo(*this->pipeline()));
str.append(INHERITED::dumpInfo());
return str;
}
private:
NonAAFillRectPerspectiveOp() : INHERITED(ClassID()) {}
void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color,
GrProcessorAnalysisCoverage* coverage) const override {
color->setToConstant(fRects[0].fColor);
*coverage = GrProcessorAnalysisCoverage::kNone;
}
void applyPipelineOptimizations(const PipelineOptimizations& optimizations) override {
optimizations.getOverrideColorIfSet(&fRects[0].fColor);
}
void onPrepareDraws(Target* target) const override {
sk_sp<GrGeometryProcessor> gp = make_persp_gp(fViewMatrix,
fHasLocalRect,
fHasLocalMatrix ? &fLocalMatrix : nullptr);
if (!gp) {
SkDebugf("Couldn't create GrGeometryProcessor\n");
return;
}
SkASSERT(fHasLocalRect
? gp->getVertexStride() ==
sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)
: gp->getVertexStride() ==
sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
size_t vertexStride = gp->getVertexStride();
int instanceCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer());
PatternHelper helper;
void* vertices =
helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
kVertsPerInstance, kIndicesPerInstance, instanceCount);
if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
for (int i = 0; i < instanceCount; i++) {
const RectInfo& info = fRects[i];
intptr_t verts =
reinterpret_cast<intptr_t>(vertices) + i * kVertsPerInstance * vertexStride;
if (fHasLocalRect) {
GrQuad quad(info.fLocalRect);
tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, &quad);
} else {
tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, nullptr);
}
}
helper.recordDraw(target, gp.get(), this->pipeline());
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
NonAAFillRectPerspectiveOp* that = t->cast<NonAAFillRectPerspectiveOp>();
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
that->bounds(), caps)) {
return false;
}
// We could combine across perspective vm changes if we really wanted to.
if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) {
return false;
}
if (fHasLocalRect != that->fHasLocalRect) {
return false;
}
if (fHasLocalMatrix && !fLocalMatrix.cheapEqualTo(that->fLocalMatrix)) {
return false;
}
fRects.push_back_n(that->fRects.count(), that->fRects.begin());
this->joinBounds(*that);
return true;
}
struct RectInfo {
SkRect fRect;
GrColor fColor;
SkRect fLocalRect;
};
SkSTArray<1, RectInfo, true> fRects;
bool fHasLocalMatrix;
bool fHasLocalRect;
SkMatrix fLocalMatrix;
SkMatrix fViewMatrix;
typedef GrLegacyMeshDrawOp INHERITED;
};
namespace GrNonAAFillRectOp {
std::unique_ptr<GrLegacyMeshDrawOp> MakeWithPerspective(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) {
return std::unique_ptr<GrLegacyMeshDrawOp>(
new NonAAFillRectPerspectiveOp(color, viewMatrix, rect, localRect, localMatrix));
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////
#if GR_TEST_UTILS
#include "GrDrawOpTest.h"
DRAW_OP_TEST_DEFINE(NonAAFillRectPerspectiveOp) {
GrColor color = GrRandomColor(random);
SkRect rect = GrTest::TestRect(random);
SkRect localRect = GrTest::TestRect(random);
SkMatrix viewMatrix = GrTest::TestMatrix(random);
bool hasLocalMatrix = random->nextBool();
SkMatrix localMatrix;
if (!viewMatrix.hasPerspective()) {
localMatrix = GrTest::TestMatrixPerspective(random);
hasLocalMatrix = true;
}
bool hasLocalRect = random->nextBool();
return GrNonAAFillRectOp::MakeWithPerspective(color, viewMatrix, rect,
hasLocalRect ? &localRect : nullptr,
hasLocalMatrix ? &localMatrix : nullptr);
}
#endif

View File

@ -13,7 +13,6 @@
#include "GrAnalyticRectOp.h"
#include "GrColor.h"
#include "GrMeshDrawOp.h"
#include "GrNonAAFillRectOp.h"
#include "GrNonAAStrokeRectOp.h"
#include "GrPaint.h"
#include "SkMatrix.h"
@ -27,19 +26,6 @@ class SkStrokeRec;
*/
namespace GrRectOpFactory {
inline std::unique_ptr<GrLegacyMeshDrawOp> MakeNonAAFill(GrColor color,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) {
if (viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective())) {
return GrNonAAFillRectOp::MakeWithPerspective(color, viewMatrix, rect, localRect,
localMatrix);
} else {
return GrNonAAFillRectOp::Make(color, viewMatrix, rect, localRect, localMatrix);
}
}
inline std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFill(const GrPaint& paint,
const SkMatrix& viewMatrix,
const SkRect& rect,

View File

@ -18,7 +18,7 @@
#include "GrResourceProvider.h"
#include "GrStencilPathOp.h"
#include "GrStyle.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrNonAAFillRectOp.h"
GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrResourceProvider* resourceProvider,
const GrCaps& caps) {
@ -112,9 +112,6 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
}
const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : viewMatrix;
std::unique_ptr<GrLegacyMeshDrawOp> coverOp(GrRectOpFactory::MakeNonAAFill(
args.fPaint.getColor(), viewM, bounds, nullptr, &invert));
// fake inverse with a stencil and cover
args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fAAType, viewMatrix,
path.get());
@ -138,11 +135,10 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
if (GrAAType::kMixedSamples == coverAAType) {
coverAAType = GrAAType::kNone;
}
GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), coverAAType);
pipelineBuilder.setUserStencil(&kInvertedCoverPass);
args.fRenderTargetContext->addLegacyMeshDrawOp(std::move(pipelineBuilder), *args.fClip,
std::move(coverOp));
args.fRenderTargetContext->addDrawOp(
*args.fClip,
GrNonAAFillRectOp::Make(std::move(args.fPaint), viewM, bounds, nullptr, &invert,
coverAAType, &kInvertedCoverPass));
}
} else {
std::unique_ptr<GrDrawOp> op =

View File

@ -9,6 +9,7 @@
#include "Test.h"
#if SK_SUPPORT_GPU
#include <random>
#include "GrClip.h"
#include "GrContext.h"
#include "GrGpuResource.h"
@ -20,7 +21,6 @@
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "ops/GrNonAAFillRectOp.h"
#include "ops/GrTestMeshDrawOp.h"
#include <random>
namespace {
class TestOp : public GrTestMeshDrawOp {
@ -266,11 +266,11 @@ void test_draw_op(GrRenderTargetContext* rtc, sk_sp<GrFragmentProcessor> fp,
nullptr, SkMatrix::I());
paint.addColorFragmentProcessor(std::move(fp));
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
GrPipelineBuilder pb(std::move(paint), GrAAType::kNone);
auto op =
GrNonAAFillRectOp::Make(GrColor_WHITE, SkMatrix::I(),
SkRect::MakeWH(rtc->width(), rtc->height()), nullptr, nullptr);
rtc->addLegacyMeshDrawOp(std::move(pb), GrNoClip(), std::move(op));
auto op = GrNonAAFillRectOp::Make(std::move(paint), SkMatrix::I(),
SkRect::MakeWH(rtc->width(), rtc->height()), nullptr, nullptr,
GrAAType::kNone);
rtc->addDrawOp(GrNoClip(), std::move(op));
}
#include "SkCommandLineFlags.h"

View File

@ -254,8 +254,9 @@ uint32_t GrRenderTargetContextPriv::testingOnly_addLegacyMeshDrawOp(
if (fRenderTargetContext->drawingManager()->wasAbandoned()) {
return SK_InvalidUniqueID;
}
SkDEBUGCODE(fRenderTargetContext->validate();) GR_AUDIT_TRAIL_AUTO_FRAME(
fRenderTargetContext->fAuditTrail, "GrRenderTargetContext::testingOnly_addMeshDrawOp");
SkDEBUGCODE(fRenderTargetContext->validate());
GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
"GrRenderTargetContext::testingOnly_addLegacyMeshDrawOp");
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
if (uss) {
@ -267,6 +268,17 @@ uint32_t GrRenderTargetContextPriv::testingOnly_addLegacyMeshDrawOp(
std::move(op));
}
uint32_t GrRenderTargetContextPriv::testingOnly_addDrawOp(std::unique_ptr<GrDrawOp> op) {
ASSERT_SINGLE_OWNER
if (fRenderTargetContext->drawingManager()->wasAbandoned()) {
return SK_InvalidUniqueID;
}
SkDEBUGCODE(fRenderTargetContext->validate());
GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
"GrRenderTargetContext::testingOnly_addDrawOp");
return fRenderTargetContext->addDrawOp(GrNoClip(), std::move(op));
}
#undef ASSERT_SINGLE_OWNER
///////////////////////////////////////////////////////////////////////////////