Add onPrePrepare to GrFillRRectOp
As the first real op to be updated this required the plumbing of the DstProxyView and the de-constification of the GrAppliedClip.
Bug: skia:9455
Change-Id: Ieaa16adfa1d114021b2ad60d0ef8ecbe31d9cc82
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255136
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/ops/GrFillRRectOp.cpp b/src/gpu/ops/GrFillRRectOp.cpp
index 27b8f54..c0ba65b 100644
--- a/src/gpu/ops/GrFillRRectOp.cpp
+++ b/src/gpu/ops/GrFillRRectOp.cpp
@@ -94,9 +94,9 @@
return pool->allocate<GrFillRRectOp>(aaType, rrect, flags, m, std::move(paint), devBounds);
}
-GrFillRRectOp::GrFillRRectOp(
- GrAAType aaType, const SkRRect& rrect, Flags flags,
- const SkMatrix& totalShapeMatrix, GrPaint&& paint, const SkRect& devBounds)
+GrFillRRectOp::GrFillRRectOp(GrAAType aaType, const SkRRect& rrect, Flags flags,
+ const SkMatrix& totalShapeMatrix, GrPaint&& paint,
+ const SkRect& devBounds)
: GrDrawOp(ClassID())
, fAAType(aaType)
, fOriginalColor(paint.getColor4f())
@@ -135,7 +135,6 @@
SkPMColor4f overrideColor;
const GrProcessorSet::Analysis& analysis = fProcessors.finalize(
-
fOriginalColor, GrProcessorAnalysisCoverage::kSingleChannel, clip,
&GrUserStencilSettings::kUnused, hasMixedSampledCoverage, caps, clampType,
&overrideColor);
@@ -179,13 +178,13 @@
return arena->make<Processor>(aaType, flags);
}
- const char* name() const override { return "GrFillRRectOp::Processor"; }
+ const char* name() const final { return "GrFillRRectOp::Processor"; }
- void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
+ void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const final {
b->add32(((uint32_t)fFlags << 16) | (uint32_t)fAAType);
}
- GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
+ GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const final;
private:
friend class ::SkArenaAlloc; // for access to ctor
@@ -450,6 +449,20 @@
GR_DECLARE_STATIC_UNIQUE_KEY(gMSAAIndexBufferKey);
+void GrFillRRectOp::onPrePrepare(GrRecordingContext* context,
+ const GrSurfaceProxyView* dstView,
+ GrAppliedClip* clip,
+ const GrXferProcessor::DstProxyView& dstProxyView) {
+ SkArenaAlloc* arena = context->priv().recordTimeAllocator();
+
+ // This is equivalent to a GrOpFlushState::detachAppliedClip
+ GrAppliedClip appliedClip = clip ? std::move(*clip) : GrAppliedClip();
+
+ // TODO: need to also give this to the recording context
+ fProgramInfo = this->createProgramInfo(context->priv().caps(), arena, dstView,
+ std::move(appliedClip), dstProxyView);
+}
+
void GrFillRRectOp::onPrepare(GrOpFlushState* flushState) {
if (void* instanceData = flushState->makeVertexSpace(fInstanceStride, fInstanceCount,
&fInstanceBuffer, &fBaseInstance)) {
@@ -738,49 +751,66 @@
return new CoverageImpl();
}
-void GrFillRRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
- if (!fInstanceBuffer || !fIndexBuffer || !fVertexBuffer) {
- return; // Setup failed.
- }
-
- Processor* proc = flushState->allocator()->make<Processor>(fAAType, fFlags);
- SkASSERT(proc->instanceStride() == (size_t)fInstanceStride);
+GrProgramInfo* GrFillRRectOp::createProgramInfo(const GrCaps* caps,
+ SkArenaAlloc* arena,
+ const GrSurfaceProxyView* dstView,
+ GrAppliedClip&& appliedClip,
+ const GrXferProcessor::DstProxyView& dstProxyView) {
+ GrGeometryProcessor* geomProc = Processor::Make(arena, fAAType, fFlags);
+ SkASSERT(geomProc->instanceStride() == (size_t)fInstanceStride);
GrPipeline::InitArgs initArgs;
if (GrAAType::kMSAA == fAAType) {
initArgs.fInputFlags = GrPipeline::InputFlags::kHWAntialias;
}
- initArgs.fCaps = &flushState->caps();
- initArgs.fDstProxyView = flushState->drawOpArgs().dstProxyView();
- initArgs.fOutputSwizzle = flushState->drawOpArgs().outputSwizzle();
- auto clip = flushState->detachAppliedClip();
+ initArgs.fCaps = caps;
+ initArgs.fDstProxyView = dstProxyView;
+ initArgs.fOutputSwizzle = dstView->swizzle();
+
GrPipeline::FixedDynamicState* fixedDynamicState = nullptr;
- if (clip.scissorState().enabled()) {
- fixedDynamicState = flushState->allocator()->make<GrPipeline::FixedDynamicState>(
- clip.scissorState().rect());
+ if (appliedClip.scissorState().enabled()) {
+ fixedDynamicState = arena->make<GrPipeline::FixedDynamicState>(
+ appliedClip.scissorState().rect());
}
- GrPipeline* pipeline = flushState->allocator()->make<GrPipeline>(initArgs,
- std::move(fProcessors),
- std::move(clip));
+ GrPipeline* pipeline = arena->make<GrPipeline>(initArgs,
+ std::move(fProcessors),
+ std::move(appliedClip));
- GrProgramInfo programInfo(flushState->proxy()->numSamples(),
- flushState->proxy()->numStencilSamples(),
- flushState->drawOpArgs().origin(),
- pipeline,
- proc,
- fixedDynamicState,
- nullptr, 0,
- GrPrimitiveType::kTriangles);
+ GrRenderTargetProxy* dstProxy = dstView->asRenderTargetProxy();
+ return arena->make<GrProgramInfo>(dstProxy->numSamples(),
+ dstProxy->numStencilSamples(),
+ dstView->origin(),
+ pipeline,
+ geomProc,
+ fixedDynamicState,
+ nullptr, 0,
+ GrPrimitiveType::kTriangles);
+}
+
+void GrFillRRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
+ if (!fInstanceBuffer || !fIndexBuffer || !fVertexBuffer) {
+ return; // Setup failed.
+ }
+
+ if (!fProgramInfo) {
+ const GrSurfaceProxyView* dstView = flushState->view();
+
+ fProgramInfo = this->createProgramInfo(&flushState->caps(),
+ flushState->allocator(),
+ dstView,
+ flushState->detachAppliedClip(),
+ flushState->dstProxyView());
+ }
GrMesh* mesh = flushState->allocator()->make<GrMesh>(GrPrimitiveType::kTriangles);
- mesh->setIndexedInstanced(
- std::move(fIndexBuffer), fIndexCount, std::move(fInstanceBuffer), fInstanceCount,
- fBaseInstance, GrPrimitiveRestart::kNo);
+ mesh->setIndexedInstanced(std::move(fIndexBuffer), fIndexCount,
+ std::move(fInstanceBuffer), fInstanceCount,
+ fBaseInstance, GrPrimitiveRestart::kNo);
mesh->setVertexData(std::move(fVertexBuffer));
- flushState->opsRenderPass()->draw(programInfo, mesh, 1, this->bounds());
- fIndexCount = 0;
+
+ flushState->opsRenderPass()->draw(*fProgramInfo, mesh, 1, this->bounds());
}
// Will the given corner look good if we use HW derivatives?
diff --git a/src/gpu/ops/GrFillRRectOp.h b/src/gpu/ops/GrFillRRectOp.h
index c3e7599..c6ad1e2 100644
--- a/src/gpu/ops/GrFillRRectOp.h
+++ b/src/gpu/ops/GrFillRRectOp.h
@@ -8,6 +8,7 @@
#ifndef GrFillRRectOp_DEFINED
#define GrFillRRectOp_DEFINED
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/ops/GrDrawOp.h"
class GrRecordingContext;
@@ -20,21 +21,29 @@
GrRecordingContext*, GrAAType, const SkMatrix& viewMatrix, const SkRRect&,
const GrCaps&, GrPaint&&);
- const char* name() const override { return "GrFillRRectOp"; }
- FixedFunctionFlags fixedFunctionFlags() const override {
- return (GrAAType::kMSAA == fAAType)
- ? FixedFunctionFlags::kUsesHWAA
- : FixedFunctionFlags::kNone;
+ const char* name() const final { return "GrFillRRectOp"; }
+
+ FixedFunctionFlags fixedFunctionFlags() const final {
+ return (GrAAType::kMSAA == fAAType) ? FixedFunctionFlags::kUsesHWAA
+ : FixedFunctionFlags::kNone;
}
GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
- bool hasMixedSampledCoverage, GrClampType) override;
- CombineResult onCombineIfPossible(GrOp*, const GrCaps&) override;
+ bool hasMixedSampledCoverage, GrClampType) final;
+ CombineResult onCombineIfPossible(GrOp*, const GrCaps&) final;
void visitProxies(const VisitProxyFunc& fn) const override {
- fProcessors.visitProxies(fn);
+ if (fProgramInfo) {
+ fProgramInfo->visitProxies(fn);
+ } else {
+ fProcessors.visitProxies(fn);
+ }
}
- void onPrepare(GrOpFlushState*) override;
- void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
+ void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView*, GrAppliedClip*,
+ const GrXferProcessor::DstProxyView&) final;
+
+ void onPrepare(GrOpFlushState*) final;
+
+ void onExecute(GrOpFlushState*, const SkRect& chainBounds) final;
private:
enum class Flags {
@@ -68,6 +77,13 @@
void writeInstanceData() {} // Halt condition.
+ // Create a GrProgramInfo object in the provided arena
+ GrProgramInfo* createProgramInfo(const GrCaps*,
+ SkArenaAlloc*,
+ const GrSurfaceProxyView* dstView,
+ GrAppliedClip&&,
+ const GrXferProcessor::DstProxyView&);
+
const GrAAType fAAType;
const SkPMColor4f fOriginalColor;
const SkRect fLocalRect;
@@ -81,9 +97,13 @@
sk_sp<const GrBuffer> fInstanceBuffer;
sk_sp<const GrBuffer> fVertexBuffer;
sk_sp<const GrBuffer> fIndexBuffer;
- int fBaseInstance;
+ int fBaseInstance = 0;
int fIndexCount = 0;
+ // If this op is prePrepared the created programInfo will be stored here from use in
+ // onExecute. In the prePrepared case it will have been stored in the record-time arena.
+ GrProgramInfo* fProgramInfo = nullptr;
+
friend class GrOpMemoryPool;
};
diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h
index cf259c7..7ba78db 100644
--- a/src/gpu/ops/GrMeshDrawOp.h
+++ b/src/gpu/ops/GrMeshDrawOp.h
@@ -89,15 +89,17 @@
private:
void onPrePrepare(GrRecordingContext* context,
const GrSurfaceProxyView* dstView,
- const GrAppliedClip* clip) final {
- this->onPrePrepareDraws(context, dstView, clip);
+ GrAppliedClip* clip,
+ const GrXferProcessor::DstProxyView& dstProxyView) final {
+ this->onPrePrepareDraws(context, dstView, clip, dstProxyView);
}
void onPrepare(GrOpFlushState* state) final;
// Only the GrTextureOp currently overrides this virtual
virtual void onPrePrepareDraws(GrRecordingContext*,
const GrSurfaceProxyView*,
- const GrAppliedClip*) {}
+ GrAppliedClip*,
+ const GrXferProcessor::DstProxyView&) {}
virtual void onPrepareDraws(Target*) = 0;
typedef GrDrawOp INHERITED;
@@ -186,7 +188,7 @@
virtual GrRenderTargetProxy* proxy() const = 0;
- virtual const GrAppliedClip* appliedClip() = 0;
+ virtual const GrAppliedClip* appliedClip() const = 0;
virtual GrAppliedClip detachAppliedClip() = 0;
virtual const GrXferProcessor::DstProxyView& dstProxyView() const = 0;
diff --git a/src/gpu/ops/GrOp.h b/src/gpu/ops/GrOp.h
index 7dfa7bc..4d58666 100644
--- a/src/gpu/ops/GrOp.h
+++ b/src/gpu/ops/GrOp.h
@@ -159,8 +159,9 @@
* onPrePrepare must be prepared to handle both cases (when onPrePrepare has been called
* ahead of time and when it has not been called).
*/
- void prePrepare(GrRecordingContext* context, GrSurfaceProxyView* dstView, GrAppliedClip* clip) {
- this->onPrePrepare(context, dstView, clip);
+ void prePrepare(GrRecordingContext* context, GrSurfaceProxyView* dstView, GrAppliedClip* clip,
+ const GrXferProcessor::DstProxyView& dstProxyView) {
+ this->onPrePrepare(context, dstView, clip, dstProxyView);
}
/**
@@ -291,9 +292,11 @@
return CombineResult::kCannotCombine;
}
- // Only GrMeshDrawOp currently overrides this virtual
- virtual void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView*,
- const GrAppliedClip*) {}
+ // TODO: the parameters to onPrePrepare mirror GrOpFlushState::OpArgs - fuse the two?
+ virtual void onPrePrepare(GrRecordingContext*,
+ const GrSurfaceProxyView*,
+ GrAppliedClip*,
+ const GrXferProcessor::DstProxyView&) {}
virtual void onPrepare(GrOpFlushState*) = 0;
// If this op is chained then chainBounds is the union of the bounds of all ops in the chain.
// Otherwise, this op's bounds.
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index d61d968..23f140b 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -516,7 +516,8 @@
void onPrePrepareDraws(GrRecordingContext* context,
const GrSurfaceProxyView* dstView,
- const GrAppliedClip* clip) override {
+ GrAppliedClip* clip,
+ const GrXferProcessor::DstProxyView& dstProxyView) override {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
SkDEBUGCODE(this->validate();)