Add SampleLocationsTestOp::onPrePrepare
Bug: skia:9455
Change-Id: I2fb9bbba7c2315e300f363b34168f59eafdda8ce
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255084
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/gm/samplelocations.cpp b/gm/samplelocations.cpp
index 79c7612..15274e3 100644
--- a/gm/samplelocations.cpp
+++ b/gm/samplelocations.cpp
@@ -97,21 +97,32 @@
class SampleLocationsTestProcessor : public GrGeometryProcessor {
public:
+ static GrGeometryProcessor* Make(SkArenaAlloc* arena, GradType gradType) {
+ return arena->make<SampleLocationsTestProcessor>(gradType);
+ }
+
+ const char* name() const override { return "SampleLocationsTestProcessor"; }
+
+ void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const final {
+ b->add32((uint32_t)fGradType);
+ }
+
+ GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const final;
+
+private:
+ friend class ::SkArenaAlloc; // for access to ctor
+
SampleLocationsTestProcessor(GradType gradType)
: GrGeometryProcessor(kSampleLocationsTestProcessor_ClassID)
, fGradType(gradType) {
this->setWillUseCustomFeature(CustomFeatures::kSampleLocations);
}
- const char* name() const override { return "SampleLocationsTestProcessor"; }
- void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const final {
- b->add32((uint32_t)fGradType);
- }
- GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const final;
-private:
const GradType fGradType;
class Impl;
+
+ typedef GrGeometryProcessor INHERITED;
};
class SampleLocationsTestProcessor::Impl : public GrGLSLGeometryProcessor {
@@ -196,6 +207,16 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// Draw Op.
+static constexpr GrUserStencilSettings gStencilWrite(
+ GrUserStencilSettings::StaticInit<
+ 0x0001,
+ GrUserStencilTest::kAlways,
+ 0xffff,
+ GrUserStencilOp::kReplace,
+ GrUserStencilOp::kKeep,
+ 0xffff>()
+);
+
class SampleLocationsTestOp : public GrDrawOp {
public:
DEFINE_OP_CLASS_ID
@@ -219,40 +240,83 @@
bool hasMixedSampledCoverage, GrClampType) override {
return GrProcessorSet::EmptySetAnalysis();
}
- void onPrepare(GrOpFlushState*) override {}
- void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
- static constexpr GrUserStencilSettings kStencilWrite(
- GrUserStencilSettings::StaticInit<
- 0x0001,
- GrUserStencilTest::kAlways,
- 0xffff,
- GrUserStencilOp::kReplace,
- GrUserStencilOp::kKeep,
- 0xffff>()
- );
- GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
- flushState->drawOpArgs().outputSwizzle(),
- GrPipeline::InputFlags::kHWAntialias, &kStencilWrite);
+ void onPrePrepare(GrRecordingContext* context,
+ const GrSurfaceProxyView* dstView,
+ const GrAppliedClip*) final {
+ // We're going to create the GrProgramInfo (and the GrPipeline and geometry processor
+ // it relies on) in the DDL-record-time arena.
+ SkArenaAlloc* arena = context->priv().recordTimeAllocator();
- SampleLocationsTestProcessor primProc(fGradType);
- GrProgramInfo programInfo(flushState->proxy()->numSamples(),
- flushState->proxy()->numStencilSamples(),
- flushState->drawOpArgs().origin(),
- &pipeline,
- &primProc,
- nullptr, nullptr, 0,
- GrPrimitiveType::kTriangleStrip);
+ // Not POD! It has some sk_sp's buried inside it!
+ GrPipeline* pipeline = arena->make<GrPipeline>(GrScissorTest::kDisabled,
+ SkBlendMode::kSrcOver,
+ dstView->swizzle(),
+ GrPipeline::InputFlags::kHWAntialias,
+ &gStencilWrite);
+
+ GrGeometryProcessor* geomProc = SampleLocationsTestProcessor::Make(arena, fGradType);
+
+ // The programInfo is POD
+ GrRenderTargetProxy* dstProxy = dstView->asRenderTargetProxy();
+ fProgramInfo = arena->make<GrProgramInfo>(dstProxy->numSamples(),
+ dstProxy->numStencilSamples(),
+ dstView->origin(),
+ pipeline,
+ geomProc,
+ nullptr, nullptr, 0,
+ GrPrimitiveType::kTriangleStrip);
+ }
+
+ void onPrepare(GrOpFlushState*) final {}
+
+ void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) final {
GrMesh mesh(GrPrimitiveType::kTriangleStrip);
mesh.setInstanced(nullptr, 200*200, 0, 4);
- flushState->opsRenderPass()->draw(programInfo, &mesh, 1, SkRect::MakeIWH(200, 200));
+
+ if (fProgramInfo) {
+ flushState->opsRenderPass()->draw(*fProgramInfo, &mesh, 1,
+ SkRect::MakeIWH(200, 200));
+ } else {
+ const GrSurfaceProxyView* dstView = flushState->view();
+
+ GrPipeline pipeline(GrScissorTest::kDisabled,
+ SkBlendMode::kSrcOver,
+ dstView->swizzle(),
+ GrPipeline::InputFlags::kHWAntialias,
+ &gStencilWrite);
+
+ GrGeometryProcessor* gp = SampleLocationsTestProcessor::Make(flushState->allocator(),
+ fGradType);
+
+ GrRenderTargetProxy* dstProxy = dstView->asRenderTargetProxy();
+ GrProgramInfo programInfo(dstProxy->numSamples(),
+ dstProxy->numStencilSamples(),
+ dstView->origin(),
+ &pipeline,
+ gp,
+ nullptr, nullptr, 0,
+ GrPrimitiveType::kTriangleStrip);
+
+ flushState->opsRenderPass()->draw(programInfo, &mesh, 1,
+ SkRect::MakeIWH(200, 200));
+ }
}
const GradType fGradType;
+ // The program info (and both the GrPipeline and GrPrimitiveProcessor 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 programInfo pointer here. We don't even store the
+ // GrPipeline and GrPrimitiveProcessor pointers here bc they are guaranteed to have the
+ // same lifetime as the program info.
+ GrProgramInfo* fProgramInfo = nullptr;
+
friend class ::GrOpMemoryPool; // for ctor
+
+ typedef GrDrawOp INHERITED;
};
////////////////////////////////////////////////////////////////////////////////////////////////////