Revert "Revert "Add a new non-AA rect op that does not inherit from GrLegacyMeshDrawOp.""
This reverts commit 0f35332796
.
Bug: skia:
Change-Id: I8def56fa55bfc70de4386bf0b7a7867f6e91c173
Reviewed-on: https://skia-review.googlesource.com/15251
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
cc413b0cf1
commit
6d4b65e9da
@ -261,6 +261,8 @@ 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",
|
||||
@ -278,6 +280,7 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/ops/GrSemaphoreOp.h",
|
||||
"$_src/gpu/ops/GrShadowRRectOp.cpp",
|
||||
"$_src/gpu/ops/GrShadowRRectOp.h",
|
||||
"$_src/gpu/ops/GrSimpleMeshDrawOpHelper.h",
|
||||
"$_src/gpu/ops/GrSmallPathRenderer.cpp",
|
||||
"$_src/gpu/ops/GrSmallPathRenderer.h",
|
||||
"$_src/gpu/ops/GrStencilAndCoverPathRenderer.cpp",
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "GrBufferAllocPool.h"
|
||||
#include "GrGpu.h"
|
||||
#include "SkArenaAlloc.h"
|
||||
#include "ops/GrMeshDrawOp.h"
|
||||
|
||||
class GrGpuCommandBuffer;
|
||||
@ -94,6 +95,7 @@ public:
|
||||
void reset() {
|
||||
fVertexPool.reset();
|
||||
fIndexPool.reset();
|
||||
fPipelines.reset();
|
||||
}
|
||||
|
||||
/** Additional data required on a per-op basis when executing GrDrawOps. */
|
||||
@ -110,16 +112,22 @@ public:
|
||||
return *fOpArgs;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
GrPipeline* allocPipeline(Args... args) {
|
||||
return fPipelines.make<GrPipeline>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
GrGpu* fGpu;
|
||||
GrResourceProvider* fResourceProvider;
|
||||
GrGpuCommandBuffer* fCommandBuffer;
|
||||
GrVertexBufferAllocPool fVertexPool;
|
||||
GrIndexBufferAllocPool fIndexPool;
|
||||
SkSTArray<4, GrDrawOp::DeferredUploadFn> fAsapUploads;
|
||||
GrDrawOpUploadToken fLastIssuedToken;
|
||||
GrDrawOpUploadToken fLastFlushedToken;
|
||||
DrawOpArgs* fOpArgs;
|
||||
GrGpu* fGpu;
|
||||
GrResourceProvider* fResourceProvider;
|
||||
GrGpuCommandBuffer* fCommandBuffer;
|
||||
GrVertexBufferAllocPool fVertexPool;
|
||||
GrIndexBufferAllocPool fIndexPool;
|
||||
SkSTArray<4, GrDrawOp::DeferredUploadFn> fAsapUploads;
|
||||
GrDrawOpUploadToken fLastIssuedToken;
|
||||
GrDrawOpUploadToken fLastFlushedToken;
|
||||
DrawOpArgs* fOpArgs;
|
||||
SkArenaAlloc fPipelines{sizeof(GrPipeline) * 100};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -182,6 +190,7 @@ public:
|
||||
protected:
|
||||
GrDrawOp* op() { return fOp; }
|
||||
GrOpFlushState* state() { return fState; }
|
||||
const GrOpFlushState* state() const { return fState; }
|
||||
|
||||
private:
|
||||
GrOpFlushState* fState;
|
||||
@ -211,6 +220,19 @@ public:
|
||||
this->state()->putBackVertexSpace(vertices * vertexStride);
|
||||
}
|
||||
|
||||
GrRenderTarget* renderTarget() const { return this->state()->drawOpArgs().fRenderTarget; }
|
||||
|
||||
const GrAppliedClip* clip() const { return this->state()->drawOpArgs().fAppliedClip; }
|
||||
|
||||
const GrXferProcessor::DstTexture& dstTexture() const {
|
||||
return this->state()->drawOpArgs().fDstTexture;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
GrPipeline* allocPipeline(Args... args) {
|
||||
return this->state()->allocPipeline(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
GrMeshDrawOp* meshDrawOp() { return static_cast<GrMeshDrawOp*>(this->op()); }
|
||||
typedef GrDrawOp::Target INHERITED;
|
||||
|
@ -12,11 +12,11 @@
|
||||
#include "effects/GrSimpleTextureEffect.h"
|
||||
|
||||
void GrPaint::setPorterDuffXPFactory(SkBlendMode mode) {
|
||||
fXPFactory = GrPorterDuffXPFactory::Get(mode);
|
||||
this->setXPFactory(GrPorterDuffXPFactory::Get(mode));
|
||||
}
|
||||
|
||||
void GrPaint::setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) {
|
||||
fXPFactory = GrCoverageSetOpXPFactory::Get(regionOp, invertCoverage);
|
||||
this->setXPFactory(GrCoverageSetOpXPFactory::Get(regionOp, invertCoverage));
|
||||
}
|
||||
|
||||
void GrPaint::addColorTextureProcessor(GrResourceProvider* resourceProvider,
|
||||
|
@ -79,11 +79,14 @@ public:
|
||||
* as such (with linear blending), and sRGB inputs to be filtered and decoded correctly.
|
||||
*/
|
||||
void setGammaCorrect(bool gammaCorrect) {
|
||||
setDisableOutputConversionToSRGB(!gammaCorrect);
|
||||
setAllowSRGBInputs(gammaCorrect);
|
||||
this->setDisableOutputConversionToSRGB(!gammaCorrect);
|
||||
this->setAllowSRGBInputs(gammaCorrect);
|
||||
}
|
||||
|
||||
void setXPFactory(const GrXPFactory* xpFactory) { fXPFactory = xpFactory; }
|
||||
void setXPFactory(const GrXPFactory* xpFactory) {
|
||||
fXPFactory = xpFactory;
|
||||
fTrivial &= !SkToBool(xpFactory);
|
||||
}
|
||||
|
||||
void setPorterDuffXPFactory(SkBlendMode mode);
|
||||
|
||||
@ -96,6 +99,7 @@ public:
|
||||
SkASSERT(fp);
|
||||
fUsesDistanceVectorField |= fp->usesDistanceVectorField();
|
||||
fColorFragmentProcessors.push_back(std::move(fp));
|
||||
fTrivial = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,6 +109,7 @@ public:
|
||||
SkASSERT(fp);
|
||||
fUsesDistanceVectorField |= fp->usesDistanceVectorField();
|
||||
fCoverageFragmentProcessors.push_back(std::move(fp));
|
||||
fTrivial = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,6 +148,12 @@ public:
|
||||
*/
|
||||
bool isConstantBlendedColor(GrColor* constantColor) const;
|
||||
|
||||
/**
|
||||
* A trivial paint is one that uses src-over and has no fragment processors.
|
||||
* It may have variable sRGB settings.
|
||||
**/
|
||||
bool isTrivial() const { return fTrivial; }
|
||||
|
||||
private:
|
||||
template <bool> class MoveOrImpl;
|
||||
|
||||
@ -172,6 +183,7 @@ private:
|
||||
bool fDisableOutputConversionToSRGB = false;
|
||||
bool fAllowSRGBInputs = false;
|
||||
bool fUsesDistanceVectorField = false;
|
||||
bool fTrivial = true;
|
||||
GrColor4f fColor = GrColor4f::OpaqueWhite();
|
||||
};
|
||||
|
||||
|
@ -90,6 +90,8 @@ public:
|
||||
**/
|
||||
GrPipeline(GrRenderTarget*, SkBlendMode);
|
||||
|
||||
GrPipeline(const InitArgs& args) { this->init(args); }
|
||||
|
||||
/** (Re)initializes a pipeline. After initialization the pipeline can be used. */
|
||||
void init(const InitArgs&);
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "GrXferProcessor.h"
|
||||
#include "effects/GrPorterDuffXferProcessor.h"
|
||||
|
||||
const GrProcessorSet GrProcessorSet::gEmpty{GrProcessorSet::Empty::kEmpty};
|
||||
|
||||
GrProcessorSet::GrProcessorSet(GrPaint&& paint) : fXP(paint.getXPFactory()) {
|
||||
fFlags = 0;
|
||||
if (paint.numColorFragmentProcessors() <= kMaxColorProcessors) {
|
||||
|
@ -18,6 +18,10 @@ class GrXferProcessor;
|
||||
class GrXPFactory;
|
||||
|
||||
class GrProcessorSet : private SkNoncopyable {
|
||||
private:
|
||||
// Arbitrary constructor arg for empty set and analysis
|
||||
enum class Empty { kEmpty };
|
||||
|
||||
public:
|
||||
GrProcessorSet(GrPaint&& paint);
|
||||
|
||||
@ -80,6 +84,14 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr Analysis(Empty)
|
||||
: fUsesLocalCoords(false)
|
||||
, fCompatibleWithCoverageAsAlpha(true)
|
||||
, fRequiresDstTexture(false)
|
||||
, fCanCombineOverlappedStencilAndCover(true)
|
||||
, fRequiresBarrierBetweenOverlappingDraws(false)
|
||||
, fIsInitialized(true)
|
||||
, fInputColorType(kOriginal_InputColorType) {}
|
||||
enum InputColorType : uint32_t {
|
||||
kOriginal_InputColorType,
|
||||
kOverridden_InputColorType,
|
||||
@ -122,7 +134,13 @@ public:
|
||||
|
||||
bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); }
|
||||
|
||||
static const GrProcessorSet& EmptySet() { return gEmpty; }
|
||||
static constexpr const Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); }
|
||||
|
||||
private:
|
||||
GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
|
||||
static const GrProcessorSet gEmpty;
|
||||
|
||||
// This absurdly large limit allows Analysis and this to pack fields together.
|
||||
static constexpr int kMaxColorProcessors = UINT8_MAX;
|
||||
|
||||
@ -130,6 +148,7 @@ private:
|
||||
|
||||
union XP {
|
||||
XP(const GrXPFactory* factory) : fFactory(factory) {}
|
||||
XP(const GrXferProcessor* processor) : fProcessor(processor) {}
|
||||
const GrXPFactory* fFactory;
|
||||
const GrXferProcessor* fProcessor;
|
||||
};
|
||||
@ -141,7 +160,7 @@ private:
|
||||
|
||||
SkAutoSTArray<4, const GrFragmentProcessor*> fFragmentProcessors;
|
||||
XP fXP;
|
||||
uint8_t fColorFragmentProcessorCnt;
|
||||
uint8_t fColorFragmentProcessorCnt = 0;
|
||||
uint8_t fFragmentProcessorOffset = 0;
|
||||
uint8_t fFlags;
|
||||
};
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "GrRenderTargetContext.h"
|
||||
#include "../private/GrAuditTrail.h"
|
||||
#include "GrAppliedClip.h"
|
||||
#include "GrColor.h"
|
||||
#include "GrContextPriv.h"
|
||||
@ -27,10 +28,11 @@
|
||||
#include "ops/GrClearOp.h"
|
||||
#include "ops/GrClearStencilClipOp.h"
|
||||
#include "ops/GrDiscardOp.h"
|
||||
#include "ops/GrDrawOp.h"
|
||||
#include "ops/GrDrawAtlasOp.h"
|
||||
#include "ops/GrDrawOp.h"
|
||||
#include "ops/GrDrawVerticesOp.h"
|
||||
#include "ops/GrLatticeOp.h"
|
||||
#include "ops/GrNewNonAAFillRectOp.h"
|
||||
#include "ops/GrOp.h"
|
||||
#include "ops/GrOvalOpFactory.h"
|
||||
#include "ops/GrRectOpFactory.h"
|
||||
@ -39,7 +41,6 @@
|
||||
#include "ops/GrStencilPathOp.h"
|
||||
#include "text/GrAtlasTextContext.h"
|
||||
#include "text/GrStencilAndCoverTextContext.h"
|
||||
#include "../private/GrAuditTrail.h"
|
||||
|
||||
#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this->drawingManager()->getContext())
|
||||
#define ASSERT_SINGLE_OWNER \
|
||||
@ -1275,7 +1276,13 @@ void GrRenderTargetContext::drawNonAAFilledRect(const GrClip& clip,
|
||||
const GrUserStencilSettings* ss,
|
||||
GrAAType hwOrNoneAAType) {
|
||||
SkASSERT(GrAAType::kCoverage != hwOrNoneAAType);
|
||||
SkASSERT(hwOrNoneAAType == GrAAType::kNone || this->isStencilBufferMultisampled());
|
||||
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);
|
||||
|
@ -67,8 +67,6 @@ void* GrMeshDrawOp::QuadHelper::init(Target* target, size_t vertexStride, int qu
|
||||
}
|
||||
|
||||
void GrMeshDrawOp::onExecute(GrOpFlushState* state) {
|
||||
SkASSERT(!state->drawOpArgs().fAppliedClip);
|
||||
SkASSERT(!state->drawOpArgs().fDstTexture.texture());
|
||||
int currUploadIdx = 0;
|
||||
int currMeshIdx = 0;
|
||||
|
||||
|
198
src/gpu/ops/GrNewNonAAFillRectOp.cpp
Normal file
198
src/gpu/ops/GrNewNonAAFillRectOp.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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)) {
|
||||
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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
31
src/gpu/ops/GrNewNonAAFillRectOp.h
Normal file
31
src/gpu/ops/GrNewNonAAFillRectOp.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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
|
194
src/gpu/ops/GrSimpleMeshDrawOpHelper.h
Normal file
194
src/gpu/ops/GrSimpleMeshDrawOpHelper.h
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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 GrSimpleMeshDrawOpHelper_DEFINED
|
||||
#define GrSimpleMeshDrawOpHelper_DEFINED
|
||||
|
||||
#include "GrAppliedClip.h"
|
||||
#include "GrOpFlushState.h"
|
||||
#include "GrPipeline.h"
|
||||
#include "GrProcessorSet.h"
|
||||
#include "GrUserStencilSettings.h"
|
||||
|
||||
/**
|
||||
* This class can be used to help implement simple mesh draw ops. It reduces the amount of
|
||||
* boilerplate code to type and also provides a mechanism for optionally allocating space for a
|
||||
* GrProcessorSet based on a GrPaint. It is intended to be used by ops that construct a single
|
||||
* GrPipeline for a uniform primitive color and a GrPaint.
|
||||
*/
|
||||
class GrSimpleMeshDrawOpHelper {
|
||||
public:
|
||||
struct MakeArgs;
|
||||
|
||||
/**
|
||||
* This can be used by a Op class to perform allocation and initialization such that a
|
||||
* GrProcessorSet (if required) is allocated at the same time as the Op instance. It requires
|
||||
* that Op implements a constructor of the form:
|
||||
* Op(MakeArgs, GrColor, OpArgs...)
|
||||
* which is public or made accessible via 'friend'.
|
||||
*/
|
||||
template <typename Op, typename... OpArgs>
|
||||
static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs);
|
||||
|
||||
GrSimpleMeshDrawOpHelper(const MakeArgs& args, GrAAType aaType,
|
||||
GrUserStencilSettings* stencilSettings = nullptr)
|
||||
: fProcessors(args.fProcessorSet)
|
||||
, fPipelineFlags(args.fSRGBFlags)
|
||||
, fAAType((int)aaType) {
|
||||
SkASSERT(!stencilSettings);
|
||||
if (GrAATypeIsHW(aaType)) {
|
||||
fPipelineFlags |= GrPipeline::kHWAntialias_Flag;
|
||||
}
|
||||
}
|
||||
|
||||
~GrSimpleMeshDrawOpHelper() {
|
||||
if (fProcessors) {
|
||||
fProcessors->~GrProcessorSet();
|
||||
}
|
||||
}
|
||||
|
||||
GrSimpleMeshDrawOpHelper() = delete;
|
||||
GrSimpleMeshDrawOpHelper(const GrSimpleMeshDrawOpHelper&) = delete;
|
||||
GrSimpleMeshDrawOpHelper& operator=(const GrSimpleMeshDrawOpHelper&) = delete;
|
||||
|
||||
GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const {
|
||||
return GrAATypeIsHW((this->aaType())) ? GrDrawOp::FixedFunctionFlags::kUsesHWAA
|
||||
: GrDrawOp::FixedFunctionFlags::kNone;
|
||||
}
|
||||
|
||||
bool isCompatible(const GrSimpleMeshDrawOpHelper& that) const {
|
||||
if (SkToBool(fProcessors) != SkToBool(that.fProcessors)) {
|
||||
return false;
|
||||
}
|
||||
if (SkToBool(fProcessors) && *fProcessors != *that.fProcessors) {
|
||||
return false;
|
||||
}
|
||||
return fPipelineFlags == that.fPipelineFlags && fAAType == that.fAAType;
|
||||
}
|
||||
|
||||
bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip,
|
||||
GrProcessorAnalysisCoverage geometryCoverage, GrColor* color) {
|
||||
if (fProcessors) {
|
||||
GrProcessorAnalysisCoverage coverage = geometryCoverage;
|
||||
if (GrProcessorAnalysisCoverage::kNone == coverage) {
|
||||
coverage = clip->clipCoverageFragmentProcessor()
|
||||
? GrProcessorAnalysisCoverage::kSingleChannel
|
||||
: GrProcessorAnalysisCoverage::kNone;
|
||||
}
|
||||
bool isMixedSamples = this->aaType() == GrAAType::kMixedSamples;
|
||||
GrProcessorSet::Analysis analysis =
|
||||
fProcessors->finalize(*color, coverage, clip, isMixedSamples, caps, color);
|
||||
return analysis.requiresDstTexture();
|
||||
} else {
|
||||
return GrProcessorSet::EmptySetAnalysis().requiresDstTexture();
|
||||
}
|
||||
}
|
||||
|
||||
GrPipeline* makePipeline(GrMeshDrawOp::Target* target) const {
|
||||
return target->allocPipeline(this->pipelineInitArgs(target));
|
||||
}
|
||||
|
||||
struct MakeArgs {
|
||||
private:
|
||||
MakeArgs() = default;
|
||||
|
||||
GrProcessorSet* fProcessorSet;
|
||||
uint32_t fSRGBFlags;
|
||||
|
||||
friend class GrSimpleMeshDrawOpHelper;
|
||||
};
|
||||
|
||||
protected:
|
||||
GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }
|
||||
uint32_t pipelineFlags() const { return fPipelineFlags; }
|
||||
const GrProcessorSet& processors() const {
|
||||
return fProcessors ? *fProcessors : GrProcessorSet::EmptySet();
|
||||
}
|
||||
|
||||
GrPipeline::InitArgs pipelineInitArgs(GrMeshDrawOp::Target* target) const {
|
||||
GrPipeline::InitArgs args;
|
||||
args.fFlags = this->pipelineFlags();
|
||||
args.fProcessors = &this->processors();
|
||||
args.fRenderTarget = target->renderTarget();
|
||||
args.fAppliedClip = target->clip();
|
||||
args.fDstTexture = target->dstTexture();
|
||||
args.fCaps = &target->caps();
|
||||
return args;
|
||||
}
|
||||
|
||||
private:
|
||||
GrProcessorSet* fProcessors;
|
||||
unsigned fPipelineFlags : 8;
|
||||
unsigned fAAType : 2;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class extends GrSimpleMeshDrawOpHelper to support an optional GrUserStencilSettings. This
|
||||
* uses private inheritance because it non-virtually overrides methods in the base class and should
|
||||
* never be used with a GrSimpleMeshDrawOpHelper pointer or reference.
|
||||
*/
|
||||
class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper {
|
||||
public:
|
||||
using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs;
|
||||
|
||||
// using declarations can't be templated, so this is a pass through function instead.
|
||||
template <typename Op, typename... OpArgs>
|
||||
static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs) {
|
||||
return GrSimpleMeshDrawOpHelper::FactoryHelper<Op, OpArgs...>(
|
||||
std::move(paint), std::forward<OpArgs>(opArgs)...);
|
||||
}
|
||||
|
||||
GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs& args, GrAAType aaType,
|
||||
const GrUserStencilSettings* stencilSettings)
|
||||
: INHERITED(args, aaType)
|
||||
, fStencilSettings(stencilSettings ? stencilSettings
|
||||
: &GrUserStencilSettings::kUnused) {}
|
||||
|
||||
GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const {
|
||||
GrDrawOp::FixedFunctionFlags flags = INHERITED::fixedFunctionFlags();
|
||||
if (fStencilSettings != &GrUserStencilSettings::kUnused) {
|
||||
flags |= GrDrawOp::FixedFunctionFlags::kUsesStencil;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
using GrSimpleMeshDrawOpHelper::xpRequiresDstTexture;
|
||||
|
||||
bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that) const {
|
||||
return INHERITED::isCompatible(that) && fStencilSettings == that.fStencilSettings;
|
||||
}
|
||||
|
||||
GrPipeline* makePipeline(GrMeshDrawOp::Target* target) const {
|
||||
auto args = INHERITED::pipelineInitArgs(target);
|
||||
args.fUserStencil = fStencilSettings;
|
||||
return target->allocPipeline(args);
|
||||
}
|
||||
|
||||
private:
|
||||
const GrUserStencilSettings* fStencilSettings;
|
||||
typedef GrSimpleMeshDrawOpHelper INHERITED;
|
||||
};
|
||||
|
||||
template <typename Op, typename... OpArgs>
|
||||
std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrPaint&& paint,
|
||||
OpArgs... opArgs) {
|
||||
MakeArgs makeArgs;
|
||||
makeArgs.fSRGBFlags = GrPipeline::SRGBFlagsFromPaint(paint);
|
||||
GrColor color = paint.getColor();
|
||||
if (paint.isTrivial()) {
|
||||
makeArgs.fProcessorSet = nullptr;
|
||||
return std::unique_ptr<GrDrawOp>(new Op(makeArgs, color, std::forward<OpArgs>(opArgs)...));
|
||||
} else {
|
||||
char* mem = (char*)GrOp::operator new(sizeof(Op) + sizeof(GrProcessorSet));
|
||||
char* setMem = mem + sizeof(Op);
|
||||
makeArgs.fProcessorSet = new (setMem) GrProcessorSet(std::move(paint));
|
||||
return std::unique_ptr<GrDrawOp>(
|
||||
new (mem) Op(makeArgs, color, std::forward<OpArgs>(opArgs)...));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user