Add ClockwiseTestOp::onPrePrepare
This is a trial balloon for the pulling forward of GrProgramInfo to DDL-record time
Bug: skia:9455
Change-Id: Icabf27fcf7169f12b0655ee23f98dafa7c770add
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/253099
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/gm/clockwise.cpp b/gm/clockwise.cpp
index 6fe1e99..f96e958 100644
--- a/gm/clockwise.cpp
+++ b/gm/clockwise.cpp
@@ -80,18 +80,25 @@
class ClockwiseTestProcessor : public GrGeometryProcessor {
public:
+ static sk_sp<GrGeometryProcessor> Make(bool readSkFragCoord) {
+ return sk_sp<GrGeometryProcessor>(new ClockwiseTestProcessor(readSkFragCoord));
+ }
+
+ const char* name() const final { return "ClockwiseTestProcessor"; }
+
+ void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const final {
+ b->add32(fReadSkFragCoord);
+ }
+
+ GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const final;
+
+private:
ClockwiseTestProcessor(bool readSkFragCoord)
: GrGeometryProcessor(kClockwiseTestProcessor_ClassID)
, fReadSkFragCoord(readSkFragCoord) {
this->setVertexAttributes(&gVertex, 1);
}
- const char* name() const override { return "ClockwiseTestProcessor"; }
- void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const final {
- b->add32(fReadSkFragCoord);
- }
- GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const final;
-private:
const bool fReadSkFragCoord;
friend class GLSLClockwiseTestProcessor;
@@ -147,6 +154,32 @@
bool hasMixedSampledCoverage, GrClampType) override {
return GrProcessorSet::EmptySetAnalysis();
}
+
+ void onPrePrepare(GrRecordingContext* context,
+ const GrSurfaceProxyView* dstView,
+ const GrAppliedClip*) final {
+ // We're going to create the GrProgramInfo (and the GrPipeline it relies on) in the
+ // DDL-record-time arena.
+ SkArenaAlloc* arena = context->priv().opPODAllocator();
+
+ // Not POD! It has some sk_sp's buried inside it!
+ GrPipeline* pipeline = arena->make<GrPipeline>(GrScissorTest::kDisabled, SkBlendMode::kPlus,
+ dstView->swizzle());
+
+ // This is allocated in the processor memory pool!?!
+ fGeomProc = ClockwiseTestProcessor::Make(fReadSkFragCoord);
+
+ // The programInfo is POD
+ GrRenderTargetProxy* dstProxy = dstView->asRenderTargetProxy();
+ fProgramInfo = arena->make<GrProgramInfo>(dstProxy->numSamples(),
+ dstProxy->numStencilSamples(),
+ dstView->origin(),
+ *pipeline,
+ *fGeomProc,
+ nullptr, nullptr, 0,
+ GrPrimitiveType::kTriangleStrip);
+ }
+
void onPrepare(GrOpFlushState* flushState) override {
SkPoint vertices[4] = {
{100, fY},
@@ -157,32 +190,55 @@
fVertexBuffer = flushState->resourceProvider()->createBuffer(
sizeof(vertices), GrGpuBufferType::kVertex, kStatic_GrAccessPattern, vertices);
}
+
void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
if (!fVertexBuffer) {
return;
}
- GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kPlus,
- flushState->drawOpArgs().outputSwizzle());
+
GrMesh mesh(GrPrimitiveType::kTriangleStrip);
mesh.setNonIndexedNonInstanced(4);
mesh.setVertexData(std::move(fVertexBuffer));
- ClockwiseTestProcessor primProc(fReadSkFragCoord);
+ if (fProgramInfo) {
+ flushState->opsRenderPass()->draw(*fProgramInfo, &mesh, 1,
+ SkRect::MakeXYWH(0, fY, 100, 100));
+ } else {
+ const GrSurfaceProxyView* dstView = flushState->view();
- GrProgramInfo programInfo(flushState->proxy()->numSamples(),
- flushState->proxy()->numStencilSamples(),
- flushState->drawOpArgs().origin(),
- pipeline,
- primProc,
- nullptr, nullptr, 0,
- GrPrimitiveType::kTriangleStrip);
+ GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kPlus,
+ dstView->swizzle());
- flushState->opsRenderPass()->draw(programInfo, &mesh, 1, SkRect::MakeXYWH(0, fY, 100, 100));
+ // This is allocated in the processor memory pool!?!
+ sk_sp<GrPrimitiveProcessor> gp = ClockwiseTestProcessor::Make(fReadSkFragCoord);
+
+ GrProgramInfo programInfo(dstView->asRenderTargetProxy()->numSamples(),
+ dstView->asRenderTargetProxy()->numStencilSamples(),
+ dstView->origin(),
+ pipeline,
+ *gp,
+ nullptr, nullptr, 0,
+ GrPrimitiveType::kTriangleStrip);
+
+ flushState->opsRenderPass()->draw(programInfo, &mesh, 1,
+ SkRect::MakeXYWH(0, fY, 100, 100));
+
+ }
+
}
- sk_sp<GrBuffer> fVertexBuffer;
- const bool fReadSkFragCoord;
- const float fY;
+ sk_sp<GrBuffer> fVertexBuffer;
+ const bool fReadSkFragCoord;
+ const float fY;
+
+ // This is allocated in the processor memory pool so we need to hold an sk_sp
+ sk_sp<GrPrimitiveProcessor> fGeomProc;
+
+ // The program info (and the GrPipeline it relies on), when allocated, are allocated in the
+ // ddl-record-time arena. It is the arena's job to free up their memory so we just have a
+ // bare program info pointer here. We don't even store the GrPipeline's pointer bc it is
+ // guaranteed to have the same lifetime as the program info.
+ GrProgramInfo* fProgramInfo = nullptr;
friend class ::GrOpMemoryPool; // for ctor
};
diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h
index d33f466..37ba109 100644
--- a/src/gpu/GrOpFlushState.h
+++ b/src/gpu/GrOpFlushState.h
@@ -72,6 +72,7 @@
GrSwizzle outputSwizzle() const { return fSurfaceView->swizzle(); }
GrOp* op() { return fOp; }
+ const GrSurfaceProxyView* view() const { return fSurfaceView; }
GrRenderTargetProxy* proxy() const { return fRenderTargetProxy; }
GrAppliedClip* appliedClip() { return fAppliedClip; }
const GrAppliedClip* appliedClip() const { return fAppliedClip; }
@@ -129,6 +130,7 @@
int* actualIndexCount) final;
void putBackIndices(int indexCount) final;
void putBackVertices(int vertices, size_t vertexStride) final;
+ const GrSurfaceProxyView* view() const { return this->drawOpArgs().view(); }
GrRenderTargetProxy* proxy() const final { return this->drawOpArgs().proxy(); }
const GrAppliedClip* appliedClip() final { return this->drawOpArgs().appliedClip(); }
GrAppliedClip detachAppliedClip() final;
diff --git a/src/gpu/GrOpsTask.cpp b/src/gpu/GrOpsTask.cpp
index 6181995..4a1146e 100644
--- a/src/gpu/GrOpsTask.cpp
+++ b/src/gpu/GrOpsTask.cpp
@@ -408,7 +408,7 @@
for (const auto& chain : fOpChains) {
if (chain.shouldExecute()) {
- chain.head()->prePrepare(context, chain.appliedClip());
+ chain.head()->prePrepare(context, &fTargetView, chain.appliedClip());
}
}
}
@@ -440,6 +440,12 @@
chain.dstProxyView());
flushState->setOpArgs(&opArgs);
+
+ // Temporary debugging helper: for debugging prePrepare w/o going through DDLs
+ // Delete once most of the GrOps have an onPrePrepare.
+ // chain.head()->prePrepare(flushState->gpu()->getContext(), &fTargetView,
+ // chain.appliedClip());
+
// GrOp::prePrepare may or may not have been called at this point
chain.head()->prepare(flushState);
flushState->setOpArgs(nullptr);
diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h
index d0d8436..75bb184 100644
--- a/src/gpu/ops/GrMeshDrawOp.h
+++ b/src/gpu/ops/GrMeshDrawOp.h
@@ -87,13 +87,17 @@
}
private:
- void onPrePrepare(GrRecordingContext* context, const GrAppliedClip* clip) final {
- this->onPrePrepareDraws(context, clip);
+ void onPrePrepare(GrRecordingContext* context,
+ const GrSurfaceProxyView* dstView,
+ const GrAppliedClip* clip) final {
+ this->onPrePrepareDraws(context, dstView, clip);
}
void onPrepare(GrOpFlushState* state) final;
// Only the GrTextureOp currently overrides this virtual
- virtual void onPrePrepareDraws(GrRecordingContext*, const GrAppliedClip*) {}
+ virtual void onPrePrepareDraws(GrRecordingContext*,
+ const GrSurfaceProxyView*,
+ const GrAppliedClip*) {}
virtual void onPrepareDraws(Target*) = 0;
typedef GrDrawOp INHERITED;
diff --git a/src/gpu/ops/GrOp.h b/src/gpu/ops/GrOp.h
index 9a250a3..7dfa7bc 100644
--- a/src/gpu/ops/GrOp.h
+++ b/src/gpu/ops/GrOp.h
@@ -159,8 +159,8 @@
* 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, GrAppliedClip* clip) {
- this->onPrePrepare(context, clip);
+ void prePrepare(GrRecordingContext* context, GrSurfaceProxyView* dstView, GrAppliedClip* clip) {
+ this->onPrePrepare(context, dstView, clip);
}
/**
@@ -292,7 +292,8 @@
}
// Only GrMeshDrawOp currently overrides this virtual
- virtual void onPrePrepare(GrRecordingContext*, const GrAppliedClip*) {}
+ virtual void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView*,
+ const GrAppliedClip*) {}
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 b9d3e6a..070221b 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -515,7 +515,9 @@
}
}
- void onPrePrepareDraws(GrRecordingContext* context, const GrAppliedClip* clip) override {
+ void onPrePrepareDraws(GrRecordingContext* context,
+ const GrSurfaceProxyView* dstView,
+ const GrAppliedClip* clip) override {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
SkDEBUGCODE(this->validate();)