diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 5b05da7cbd..8dce76e15a 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -1647,6 +1647,8 @@ Result GPUDDLSink::ddlDraw(const Src& src, Result result = src.draw(recorder.beginRecording(SkIntToScalar(size.width()), SkIntToScalar(size.height()))); if (!result.isOk()) { + gpuTaskGroup->add([gpuTestCtx] { gpuTestCtx->makeNotCurrent(); }); + gpuTaskGroup->wait(); return result; } sk_sp inputPicture(recorder.finishRecordingAsPicture()); @@ -1657,6 +1659,8 @@ Result GPUDDLSink::ddlDraw(const Src& src, DDLPromiseImageHelper promiseImageHelper; sk_sp compressedPictureData = promiseImageHelper.deflateSKP(inputPicture.get()); if (!compressedPictureData) { + gpuTaskGroup->add([gpuTestCtx] { gpuTestCtx->makeNotCurrent(); }); + gpuTaskGroup->wait(); return Result::Fatal("GPUDDLSink: Couldn't deflate SkPicture"); } diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp index dc5439b68d..c7b29ed3a2 100644 --- a/gm/beziereffects.cpp +++ b/gm/beziereffects.cpp @@ -33,9 +33,11 @@ #include "src/gpu/GrGeometryProcessor.h" #include "src/gpu/GrMemoryPool.h" #include "src/gpu/GrOpFlushState.h" +#include "src/gpu/GrOpsRenderPass.h" #include "src/gpu/GrPaint.h" #include "src/gpu/GrProcessorAnalysis.h" #include "src/gpu/GrProcessorSet.h" +#include "src/gpu/GrProgramInfo.h" #include "src/gpu/GrRecordingContextPriv.h" #include "src/gpu/GrRenderTargetContext.h" #include "src/gpu/GrRenderTargetContextPriv.h" @@ -81,12 +83,60 @@ protected: this->setBounds(rect, HasAABloat::kYes, IsHairline::kNo); } - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - auto pipeline = GrSimpleMeshDrawOpHelper::CreatePipeline(flushState, - std::move(fProcessorSet), - GrPipeline::InputFlags::kNone); + virtual GrGeometryProcessor* makeGP(const GrCaps& caps, SkArenaAlloc* arena) = 0; - flushState->executeDrawsAndUploadsForMeshDrawOp(this, chainBounds, pipeline); + GrProgramInfo* createProgramInfo(const GrCaps* caps, + SkArenaAlloc* arena, + const GrSurfaceProxyView* outputView, + GrAppliedClip&& appliedClip, + const GrXferProcessor::DstProxyView& dstProxyView) { + auto gp = this->makeGP(*caps, arena); + if (!gp) { + return nullptr; + } + + GrPipeline::InputFlags flags = GrPipeline::InputFlags::kNone; + + return GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps, arena, outputView, + std::move(appliedClip), dstProxyView, + gp, std::move(fProcessorSet), flags); + } + + GrProgramInfo* createProgramInfo(GrOpFlushState* flushState) { + return this->createProgramInfo(&flushState->caps(), + flushState->allocator(), + flushState->view(), + flushState->detachAppliedClip(), + flushState->dstProxyView()); + } + + void onPrePrepareDraws(GrRecordingContext* context, + const GrSurfaceProxyView* outputView, + GrAppliedClip* clip, + const GrXferProcessor::DstProxyView& dstProxyView) final { + SkArenaAlloc* arena = context->priv().recordTimeAllocator(); + + // This is equivalent to a GrOpFlushState::detachAppliedClip + GrAppliedClip appliedClip = clip ? std::move(*clip) : GrAppliedClip(); + + fProgramInfo = this->createProgramInfo(context->priv().caps(), arena, outputView, + std::move(appliedClip), dstProxyView); + + context->priv().recordProgramInfo(fProgramInfo); + } + + void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) final { + if (!fProgramInfo) { + fProgramInfo = this->createProgramInfo(flushState); + } + + if (!fProgramInfo) { + return; + } + + static constexpr int kOneMesh = 1; + flushState->opsRenderPass()->bindPipeline(*fProgramInfo, chainBounds); + flushState->opsRenderPass()->drawMeshes(*fProgramInfo, fMesh, kOneMesh); } GrClipEdgeType edgeType() const { return fEdgeType; } @@ -94,11 +144,15 @@ protected: const SkRect& rect() const { return fRect; } const SkPMColor4f& color() const { return fColor; } +protected: + GrMesh* fMesh = nullptr; // filled in by the derived classes + private: - SkRect fRect; - SkPMColor4f fColor; - GrClipEdgeType fEdgeType; - GrProcessorSet fProcessorSet; + SkRect fRect; + SkPMColor4f fColor; + GrClipEdgeType fEdgeType; + GrProcessorSet fProcessorSet; + GrProgramInfo* fProgramInfo = nullptr; typedef GrMeshDrawOp INHERITED; }; @@ -110,7 +164,7 @@ class BezierConicTestOp : public BezierTestOp { public: DEFINE_OP_CLASS_ID - const char* name() const override { return "BezierConicTestOp"; } + const char* name() const final { return "BezierConicTestOp"; } static std::unique_ptr Make(GrRecordingContext* context, GrClipEdgeType et, @@ -134,29 +188,30 @@ private: float fKLM[4]; // The last value is ignored. The effect expects a vec4f. }; - void onPrepareDraws(Target* target) override { - GrGeometryProcessor* gp = GrConicEffect::Make(target->allocator(), this->color(), - SkMatrix::I(), this->edgeType(), - target->caps(), SkMatrix::I(), false); - if (!gp) { - return; + GrGeometryProcessor* makeGP(const GrCaps& caps, SkArenaAlloc* arena) final { + auto tmp = GrConicEffect::Make(arena, this->color(), SkMatrix::I(), this->edgeType(), + caps, SkMatrix::I(), false); + if (!tmp) { + return nullptr; } + SkASSERT(tmp->vertexStride() == sizeof(Vertex)); + return tmp; + } - SkASSERT(gp->vertexStride() == sizeof(Vertex)); + void onPrepareDraws(Target* target) final { QuadHelper helper(target, sizeof(Vertex), 1); Vertex* verts = reinterpret_cast(helper.vertices()); if (!verts) { return; } SkRect rect = this->rect(); - SkPointPriv::SetRectTriStrip(&verts[0].fPosition, rect.fLeft, rect.fTop, rect.fRight, - rect.fBottom, sizeof(Vertex)); + SkPointPriv::SetRectTriStrip(&verts[0].fPosition, rect, sizeof(Vertex)); for (int v = 0; v < 4; ++v) { SkPoint3 pt3 = {verts[v].fPosition.x(), verts[v].fPosition.y(), 1.f}; fKLM.mapHomogeneousPoints((SkPoint3* ) verts[v].fKLM, &pt3, 1); } - helper.recordDraw(target, gp); + fMesh = helper.mesh(); } SkMatrix fKLM; @@ -343,15 +398,17 @@ private: float fKLM[4]; // The last value is ignored. The effect expects a vec4f. }; - void onPrepareDraws(Target* target) override { - GrGeometryProcessor* gp = GrQuadEffect::Make(target->allocator(), this->color(), - SkMatrix::I(), this->edgeType(), - target->caps(), SkMatrix::I(), false); - if (!gp) { - return; + GrGeometryProcessor* makeGP(const GrCaps& caps, SkArenaAlloc* arena) final { + auto tmp = GrQuadEffect::Make(arena, this->color(), SkMatrix::I(), this->edgeType(), + caps, SkMatrix::I(), false); + if (!tmp) { + return nullptr; } + SkASSERT(tmp->vertexStride() == sizeof(Vertex)); + return tmp; + } - SkASSERT(gp->vertexStride() == sizeof(Vertex)); + void onPrepareDraws(Target* target) final { QuadHelper helper(target, sizeof(Vertex), 1); Vertex* verts = reinterpret_cast(helper.vertices()); if (!verts) { @@ -360,7 +417,8 @@ private: SkRect rect = this->rect(); SkPointPriv::SetRectTriStrip(&verts[0].fPosition, rect, sizeof(Vertex)); fDevToUV.apply(verts, 4, sizeof(Vertex), sizeof(SkPoint)); - helper.recordDraw(target, gp); + + fMesh = helper.mesh(); } GrPathUtils::QuadUVMatrix fDevToUV; diff --git a/src/gpu/ops/GrFillRRectOp.cpp b/src/gpu/ops/GrFillRRectOp.cpp index a7aa43cd34..684ccbcfef 100644 --- a/src/gpu/ops/GrFillRRectOp.cpp +++ b/src/gpu/ops/GrFillRRectOp.cpp @@ -20,6 +20,7 @@ #include "src/gpu/glsl/GrGLSLVarying.h" #include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h" #include "src/gpu/ops/GrDrawOp.h" +#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h" namespace { @@ -98,6 +99,13 @@ private: const GrSurfaceProxyView* outputView, GrAppliedClip&&, const GrXferProcessor::DstProxyView&); + GrProgramInfo* createProgramInfo(GrOpFlushState* flushState) { + return this->createProgramInfo(&flushState->caps(), + flushState->allocator(), + flushState->view(), + flushState->detachAppliedClip(), + flushState->dstProxyView()); + } const GrAAType fAAType; const SkPMColor4f fOriginalColor; @@ -568,7 +576,8 @@ void FillRRectOp::onPrePrepare(GrRecordingContext* context, // TODO: it would be cool if, right here, we created both the program info and desc // in the record-time arena. Then, if the program info had already been seen, we could // get pointers back to the prior versions and be able to return the allocated space - // back to the arena. + // back to the arena. Note that this would require separating the portions of the + // ProgramInfo that represent state from those that are just definitional. fProgramInfo = this->createProgramInfo(context->priv().caps(), arena, outputView, std::move(appliedClip), dstProxyView); @@ -868,38 +877,17 @@ GrProgramInfo* FillRRectOp::createProgramInfo(const GrCaps* caps, const GrSurfaceProxyView* outputView, GrAppliedClip&& appliedClip, const GrXferProcessor::DstProxyView& dstProxyView) { - GrGeometryProcessor* geomProc = Processor::Make(arena, fAAType, fFlags); - SkASSERT(geomProc->instanceStride() == (size_t)fInstanceStride); + GrGeometryProcessor* gp = Processor::Make(arena, fAAType, fFlags); + SkASSERT(gp->instanceStride() == (size_t)fInstanceStride); - GrPipeline::InitArgs initArgs; + GrPipeline::InputFlags flags = GrPipeline::InputFlags::kNone; if (GrAAType::kMSAA == fAAType) { - initArgs.fInputFlags = GrPipeline::InputFlags::kHWAntialias; - } - initArgs.fCaps = caps; - initArgs.fDstProxyView = dstProxyView; - initArgs.fOutputSwizzle = outputView->swizzle(); - - GrPipeline::FixedDynamicState* fixedDynamicState = nullptr; - - if (appliedClip.scissorState().enabled()) { - fixedDynamicState = arena->make( - appliedClip.scissorState().rect()); + flags = GrPipeline::InputFlags::kHWAntialias; } - GrPipeline* pipeline = arena->make(initArgs, - std::move(fProcessors), - std::move(appliedClip)); - - GrRenderTargetProxy* outputProxy = outputView->asRenderTargetProxy(); - return arena->make(outputProxy->numSamples(), - outputProxy->numStencilSamples(), - outputProxy->backendFormat(), - outputView->origin(), - pipeline, - geomProc, - fixedDynamicState, - nullptr, 0, - GrPrimitiveType::kTriangles); + return GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps, arena, outputView, + std::move(appliedClip), dstProxyView, + gp, std::move(fProcessors), flags); } void FillRRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { @@ -908,11 +896,7 @@ void FillRRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBound } if (!fProgramInfo) { - fProgramInfo = this->createProgramInfo(&flushState->caps(), - flushState->allocator(), - flushState->view(), - flushState->detachAppliedClip(), - flushState->dstProxyView()); + fProgramInfo = this->createProgramInfo(flushState); } GrMesh* mesh = flushState->allocator()->make(); diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h index c0c88ffcc5..db492af58b 100644 --- a/src/gpu/ops/GrMeshDrawOp.h +++ b/src/gpu/ops/GrMeshDrawOp.h @@ -50,6 +50,7 @@ protected: const GrPipeline::FixedDynamicState*) const; void* vertices() const { return fVertices; } + GrMesh* mesh() { return fMesh; } protected: PatternHelper() = default; @@ -71,6 +72,7 @@ protected: QuadHelper() = delete; QuadHelper(Target* target, size_t vertexStride, int quadsToDraw); + using PatternHelper::mesh; using PatternHelper::recordDraw; using PatternHelper::vertices; diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp index d847140a1e..310b9ded12 100644 --- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp +++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp @@ -7,6 +7,7 @@ #include "src/gpu/GrAppliedClip.h" #include "src/gpu/GrProcessorSet.h" +#include "src/gpu/GrProgramInfo.h" #include "src/gpu/GrUserStencilSettings.h" #include "src/gpu/SkGr.h" #include "src/gpu/geometry/GrRect.h" @@ -118,9 +119,9 @@ const GrPipeline* GrSimpleMeshDrawOpHelper::CreatePipeline( GrPipeline::InitArgs pipelineArgs; pipelineArgs.fInputFlags = pipelineFlags; - pipelineArgs.fDstProxyView = dstProxyView; - pipelineArgs.fCaps = caps; pipelineArgs.fUserStencil = stencilSettings; + pipelineArgs.fCaps = caps; + pipelineArgs.fDstProxyView = dstProxyView; pipelineArgs.fOutputSwizzle = outputView->swizzle(); return arena->make(pipelineArgs, @@ -153,6 +154,45 @@ const GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(GrOpFlushState* flush this->pipelineFlags()); } +GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo( + const GrCaps* caps, + SkArenaAlloc* arena, + const GrSurfaceProxyView* outputView, + GrAppliedClip&& appliedClip, + const GrXferProcessor::DstProxyView& dstProxyView, + GrGeometryProcessor* geometryProcessor, + GrProcessorSet&& processorSet, + GrPipeline::InputFlags pipelineFlags) { + static constexpr int kZeroPrimProcTextures = 0; + auto fixedDynamicState = GrMeshDrawOp::Target::MakeFixedDynamicState(arena, + &appliedClip, + kZeroPrimProcTextures); + + auto pipeline = CreatePipeline(caps, + arena, + outputView, + std::move(appliedClip), + dstProxyView, + std::move(processorSet), + pipelineFlags); + + GrRenderTargetProxy* outputProxy = outputView->asRenderTargetProxy(); + + static constexpr int kOneMesh = 1; + auto tmp = arena->make(outputProxy->numSamples(), + outputProxy->numStencilSamples(), + outputProxy->backendFormat(), + outputView->origin(), + pipeline, + geometryProcessor, + fixedDynamicState, + nullptr, + kOneMesh, + GrPrimitiveType::kTriangles); + SkASSERT(tmp->primProc().numTextureSamplers() <= 0); + return tmp; +} + #ifdef SK_DEBUG static void dump_pipeline_flags(GrPipeline::InputFlags flags, SkString* result) { if (GrPipeline::InputFlags::kNone != flags) { diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h index fa12a5a58e..63d1eb185f 100644 --- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h +++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h @@ -140,6 +140,19 @@ public: const GrPipeline* createPipeline(GrOpFlushState* flushState); + // Create a programInfo with the following properties: + // its primitive processor uses no textures + // it has no dynamic state besides the scissor clip + // it is only applied to a single kTriangles mesh + static GrProgramInfo* CreateProgramInfo(const GrCaps*, + SkArenaAlloc*, + const GrSurfaceProxyView* outputView, + GrAppliedClip&&, + const GrXferProcessor::DstProxyView&, + GrGeometryProcessor*, + GrProcessorSet&&, + GrPipeline::InputFlags pipelineFlags); + GrProcessorSet detachProcessorSet() { return fProcessors ? std::move(*fProcessors) : GrProcessorSet::MakeEmptySet(); } diff --git a/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp b/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp index f24d9244a2..bde33b6475 100644 --- a/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp +++ b/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp @@ -193,7 +193,7 @@ void WinGLTestContext::onPlatformMakeCurrent() const { } if (!wglMakeCurrent(dc, glrc)) { - SkDebugf("Could not create rendering context.\n"); + SkDebugf("Could not make current.\n"); } }