Make GrDrawAtlasOp a non-legacy GrMeshDrawOp

Change-Id: I4d517855dbe3ee6894d7d457e0fc4488f204300c
Reviewed-on: https://skia-review.googlesource.com/22542
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Brian Salomon 2017-07-12 11:51:27 -04:00 committed by Skia Commit-Bot
parent 41ed7f3379
commit 0088f94817
6 changed files with 132 additions and 94 deletions

View File

@ -875,10 +875,10 @@ void GrRenderTargetContext::drawAtlas(const GrClip& clip,
AutoCheckFlush acf(this->drawingManager());
std::unique_ptr<GrLegacyMeshDrawOp> op =
GrDrawAtlasOp::Make(paint.getColor(), viewMatrix, spriteCount, xform, texRect, colors);
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
GrAAType aaType = this->chooseAAType(GrAA::kNo, GrAllowMixedSamples::kNo);
std::unique_ptr<GrDrawOp> op = GrDrawAtlasOp::Make(std::move(paint), viewMatrix, aaType,
spriteCount, xform, texRect, colors);
this->addDrawOp(clip, std::move(op));
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -12,23 +12,6 @@
#include "SkRSXform.h"
#include "SkRandom.h"
void GrDrawAtlasOp::applyPipelineOptimizations(const PipelineOptimizations& optimizations) {
SkASSERT(fGeoData.count() == 1);
if (optimizations.getOverrideColorIfSet(&fGeoData[0].fColor) && fHasColors) {
size_t vertexStride =
sizeof(SkPoint) + sizeof(SkPoint) + (this->hasColors() ? sizeof(GrColor) : 0);
uint8_t* currVertex = fGeoData[0].fVerts.begin();
for (int i = 0; i < 4 * fQuadCount; ++i) {
*(reinterpret_cast<GrColor*>(currVertex + sizeof(SkPoint))) = fGeoData[0].fColor;
currVertex += vertexStride;
}
}
fColor = fGeoData[0].fColor;
// We'd like to assert this, but we can't because of GLPrograms test
// SkASSERT(init.readsLocalCoords());
}
static sk_sp<GrGeometryProcessor> make_gp(bool hasColors,
GrColor color,
const SkMatrix& viewMatrix) {
@ -42,37 +25,10 @@ static sk_sp<GrGeometryProcessor> make_gp(bool hasColors,
LocalCoords::kHasExplicit_Type, viewMatrix);
}
void GrDrawAtlasOp::onPrepareDraws(Target* target) const {
// Setup geometry processor
sk_sp<GrGeometryProcessor> gp(make_gp(this->hasColors(), this->color(), this->viewMatrix()));
int instanceCount = fGeoData.count();
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride ==
sizeof(SkPoint) + sizeof(SkPoint) + (this->hasColors() ? sizeof(GrColor) : 0));
QuadHelper helper;
int numQuads = this->quadCount();
void* verts = helper.init(target, vertexStride, numQuads);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return;
}
uint8_t* vertPtr = reinterpret_cast<uint8_t*>(verts);
for (int i = 0; i < instanceCount; i++) {
const Geometry& args = fGeoData[i];
size_t allocSize = args.fVerts.count();
memcpy(vertPtr, args.fVerts.begin(), allocSize);
vertPtr += allocSize;
}
helper.recordDraw(target, gp.get(), this->pipeline());
}
GrDrawAtlasOp::GrDrawAtlasOp(GrColor color, const SkMatrix& viewMatrix, int spriteCount,
GrDrawAtlasOp::GrDrawAtlasOp(const Helper::MakeArgs& helperArgs, GrColor color,
const SkMatrix& viewMatrix, GrAAType aaType, int spriteCount,
const SkRSXform* xforms, const SkRect* rects, const SkColor* colors)
: INHERITED(ClassID()) {
: INHERITED(ClassID()), fHelper(helperArgs, aaType) {
SkASSERT(xforms);
SkASSERT(rects);
@ -151,11 +107,48 @@ GrDrawAtlasOp::GrDrawAtlasOp(GrColor color, const SkMatrix& viewMatrix, int spri
this->setTransformedBounds(bounds, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
}
SkString GrDrawAtlasOp::dumpInfo() const {
SkString string;
for (const auto& geo : fGeoData) {
string.appendf("Color: 0x%08x, Quads: %d\n", geo.fColor, geo.fVerts.count() / 4);
}
string += fHelper.dumpInfo();
string += INHERITED::dumpInfo();
return string;
}
void GrDrawAtlasOp::onPrepareDraws(Target* target) const {
// Setup geometry processor
sk_sp<GrGeometryProcessor> gp(make_gp(this->hasColors(), this->color(), this->viewMatrix()));
int instanceCount = fGeoData.count();
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride ==
sizeof(SkPoint) + sizeof(SkPoint) + (this->hasColors() ? sizeof(GrColor) : 0));
QuadHelper helper;
int numQuads = this->quadCount();
void* verts = helper.init(target, vertexStride, numQuads);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return;
}
uint8_t* vertPtr = reinterpret_cast<uint8_t*>(verts);
for (int i = 0; i < instanceCount; i++) {
const Geometry& args = fGeoData[i];
size_t allocSize = args.fVerts.count();
memcpy(vertPtr, args.fVerts.begin(), allocSize);
vertPtr += allocSize;
}
helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
}
bool GrDrawAtlasOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
GrDrawAtlasOp* that = t->cast<GrDrawAtlasOp>();
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
that->bounds(), caps)) {
if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
return false;
}
@ -179,6 +172,26 @@ bool GrDrawAtlasOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
return true;
}
GrDrawOp::FixedFunctionFlags GrDrawAtlasOp::fixedFunctionFlags() const {
return fHelper.fixedFunctionFlags();
}
GrDrawOp::RequiresDstTexture GrDrawAtlasOp::finalize(const GrCaps& caps,
const GrAppliedClip* clip) {
GrProcessorAnalysisColor gpColor;
if (this->hasColors()) {
gpColor.setToUnknown();
} else {
gpColor.setToConstant(fColor);
}
auto result =
fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, &gpColor);
if (gpColor.isConstant(&fColor)) {
fHasColors = false;
}
return result;
}
#if GR_TEST_UTILS
static SkRSXform random_xform(SkRandom* random) {
@ -222,7 +235,7 @@ static void randomize_params(uint32_t count, SkRandom* random, SkTArray<SkRSXfor
}
}
GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(GrDrawAtlasOp) {
GR_DRAW_OP_TEST_DEFINE(GrDrawAtlasOp) {
uint32_t spriteCount = random->nextRangeU(1, 100);
SkTArray<SkRSXform> xforms(spriteCount);
@ -234,10 +247,13 @@ GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(GrDrawAtlasOp) {
randomize_params(spriteCount, random, &xforms, &texRects, &colors, hasColors);
SkMatrix viewMatrix = GrTest::TestMatrix(random);
GrAAType aaType = GrAAType::kNone;
if (GrFSAAType::kUnifiedMSAA == fsaaType && random->nextBool()) {
aaType = GrAAType::kMSAA;
}
GrColor color = GrRandomColor(random);
return GrDrawAtlasOp::Make(color, viewMatrix, spriteCount, xforms.begin(), texRects.begin(),
hasColors ? colors.begin() : nullptr);
return GrDrawAtlasOp::Make(std::move(paint), viewMatrix, aaType, spriteCount, xforms.begin(),
texRects.begin(), hasColors ? colors.begin() : nullptr);
}
#endif

View File

@ -11,48 +11,37 @@
#include "GrColor.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrMeshDrawOp.h"
#include "GrSimpleMeshDrawOpHelper.h"
class GrDrawAtlasOp final : public GrMeshDrawOp {
private:
using Helper = GrSimpleMeshDrawOpHelper;
class GrDrawAtlasOp final : public GrLegacyMeshDrawOp {
public:
DEFINE_OP_CLASS_ID
static std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, const SkMatrix& viewMatrix,
int spriteCount, const SkRSXform* xforms,
const SkRect* rects, const SkColor* colors) {
return std::unique_ptr<GrLegacyMeshDrawOp>(
new GrDrawAtlasOp(color, viewMatrix, spriteCount, xforms, rects, colors));
static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
GrAAType aaType, int spriteCount, const SkRSXform* xforms,
const SkRect* rects, const SkColor* colors) {
return Helper::FactoryHelper<GrDrawAtlasOp>(std::move(paint), viewMatrix, aaType,
spriteCount, xforms, rects, colors);
}
GrDrawAtlasOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix,
GrAAType, int spriteCount, const SkRSXform* xforms, const SkRect* rects,
const SkColor* colors);
const char* name() const override { return "DrawAtlasOp"; }
SkString dumpInfo() const override {
SkString string;
for (const auto& geo : fGeoData) {
string.appendf("Color: 0x%08x, Quads: %d\n", geo.fColor, geo.fVerts.count() / 4);
}
string.append(DumpPipelineInfo(*this->pipeline()));
string.append(INHERITED::dumpInfo());
return string;
}
SkString dumpInfo() const override;
FixedFunctionFlags fixedFunctionFlags() const override;
RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override;
private:
GrDrawAtlasOp(GrColor color, const SkMatrix& viewMatrix, int spriteCount,
const SkRSXform* xforms, const SkRect* rects, const SkColor* colors);
void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color,
GrProcessorAnalysisCoverage* coverage) const override {
if (this->hasColors()) {
color->setToUnknown();
} else {
color->setToConstant(fGeoData[0].fColor);
}
*coverage = GrProcessorAnalysisCoverage::kNone;
}
void onPrepareDraws(Target*) const override;
void applyPipelineOptimizations(const PipelineOptimizations&) override;
GrColor color() const { return fColor; }
const SkMatrix& viewMatrix() const { return fViewMatrix; }
bool hasColors() const { return fHasColors; }
@ -66,13 +55,13 @@ private:
};
SkSTArray<1, Geometry, true> fGeoData;
Helper fHelper;
SkMatrix fViewMatrix;
GrColor fColor;
int fQuadCount;
bool fHasColors;
typedef GrLegacyMeshDrawOp INHERITED;
typedef GrMeshDrawOp INHERITED;
};
#endif

View File

@ -64,7 +64,7 @@ bool GrSimpleMeshDrawOpHelper::isCompatible(const GrSimpleMeshDrawOpHelper& that
GrDrawOp::RequiresDstTexture GrSimpleMeshDrawOpHelper::xpRequiresDstTexture(
const GrCaps& caps, const GrAppliedClip* clip, GrProcessorAnalysisCoverage geometryCoverage,
GrColor* color) {
GrProcessorAnalysisColor* geometryColor) {
SkDEBUGCODE(fDidAnalysis = true);
GrProcessorSet::Analysis analysis;
if (fProcessors) {
@ -75,7 +75,12 @@ GrDrawOp::RequiresDstTexture GrSimpleMeshDrawOpHelper::xpRequiresDstTexture(
: GrProcessorAnalysisCoverage::kNone;
}
bool isMixedSamples = this->aaType() == GrAAType::kMixedSamples;
analysis = fProcessors->finalize(*color, coverage, clip, isMixedSamples, caps, color);
GrColor overrideColor;
analysis = fProcessors->finalize(*geometryColor, coverage, clip, isMixedSamples, caps,
&overrideColor);
if (analysis.inputColorIsOverridden()) {
*geometryColor = overrideColor;
}
} else {
analysis = GrProcessorSet::EmptySetAnalysis();
}
@ -86,6 +91,15 @@ GrDrawOp::RequiresDstTexture GrSimpleMeshDrawOpHelper::xpRequiresDstTexture(
: GrDrawOp::RequiresDstTexture::kNo;
}
GrDrawOp::RequiresDstTexture GrSimpleMeshDrawOpHelper::xpRequiresDstTexture(
const GrCaps& caps, const GrAppliedClip* clip, GrProcessorAnalysisCoverage geometryCoverage,
GrColor* geometryColor) {
GrProcessorAnalysisColor color = *geometryColor;
auto result = this->xpRequiresDstTexture(caps, clip, geometryCoverage, &color);
color.isConstant(geometryColor);
return result;
}
SkString GrSimpleMeshDrawOpHelper::dumpInfo() const {
SkString result = this->processors().dumpProcessors();
result.append("AA Type: ");

View File

@ -52,9 +52,28 @@ public:
bool isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps&, const SkRect& thisBounds,
const SkRect& thatBounds) const;
/**
* Finalizes the processor set and determines whether the destination must be provided
* to the fragment shader as a texture for blending.
*
* @param geometryCoverage Describes the coverage output of the op's geometry processor
* @param geometryColor An in/out param. As input this informs processor analysis about the
* color the op expects to output from its geometry processor. As output
* this may be set to a known color in which case the op must output this
* color from its geometry processor instead.
*/
GrDrawOp::RequiresDstTexture xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip,
GrProcessorAnalysisCoverage geometryCoverage,
GrProcessorAnalysisColor* geometryColor);
/**
* Version of above that can be used by ops that have a constant color geometry processor
* output. The op passes this color as 'geometryColor' and after return if 'geometryColor' has
* changed the op must override its geometry processor color output with the new color.
*/
GrDrawOp::RequiresDstTexture xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*,
GrProcessorAnalysisCoverage geometryCoverage,
GrColor* color);
GrColor* geometryColor);
bool usesLocalCoords() const {
SkASSERT(fDidAnalysis);

View File

@ -316,7 +316,6 @@ void GrDrawingManager::testingOnly_removeOnFlushCallbackObject(GrOnFlushCallback
LEGACY_MESH_DRAW_OP_TEST_EXTERN(AAFlatteningConvexPathOp);
LEGACY_MESH_DRAW_OP_TEST_EXTERN(AnalyticRectOp);
LEGACY_MESH_DRAW_OP_TEST_EXTERN(DefaultPathOp);
LEGACY_MESH_DRAW_OP_TEST_EXTERN(GrDrawAtlasOp);
LEGACY_MESH_DRAW_OP_TEST_EXTERN(TextBlobOp);
LEGACY_MESH_DRAW_OP_TEST_EXTERN(VerticesOp);
@ -328,6 +327,7 @@ DRAW_OP_TEST_EXTERN(CircleOp);
DRAW_OP_TEST_EXTERN(DashOp);
DRAW_OP_TEST_EXTERN(DIEllipseOp);
DRAW_OP_TEST_EXTERN(EllipseOp);
DRAW_OP_TEST_EXTERN(GrDrawAtlasOp);
DRAW_OP_TEST_EXTERN(NonAAFillRectOp);
DRAW_OP_TEST_EXTERN(NonAALatticeOp);
DRAW_OP_TEST_EXTERN(NonAAStrokeRectOp);
@ -344,7 +344,6 @@ void GrDrawRandomOp(SkRandom* random, GrRenderTargetContext* renderTargetContext
DRAW_OP_TEST_ENTRY(AAFlatteningConvexPathOp),
DRAW_OP_TEST_ENTRY(AnalyticRectOp),
DRAW_OP_TEST_ENTRY(DefaultPathOp),
DRAW_OP_TEST_ENTRY(GrDrawAtlasOp),
DRAW_OP_TEST_ENTRY(TextBlobOp),
DRAW_OP_TEST_ENTRY(VerticesOp)
};
@ -359,6 +358,7 @@ void GrDrawRandomOp(SkRandom* random, GrRenderTargetContext* renderTargetContext
DRAW_OP_TEST_ENTRY(DashOp),
DRAW_OP_TEST_ENTRY(DIEllipseOp),
DRAW_OP_TEST_ENTRY(EllipseOp),
DRAW_OP_TEST_ENTRY(GrDrawAtlasOp),
DRAW_OP_TEST_ENTRY(NonAAFillRectOp),
DRAW_OP_TEST_ENTRY(NonAALatticeOp),
DRAW_OP_TEST_ENTRY(NonAAStrokeRectOp),