Add GrSimpleMeshDrawOpHelper::CreateProgramInfo
This helper method can be used by the MeshDrawOps to (pre-)create their GrProgramInfos. Bug: skia:9455 Change-Id: I41b7c2aefc0f633a1d32996c7f0cce3d11f8fcb1 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/273815 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
b62cee315e
commit
ce97857f5b
@ -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<SkPicture> inputPicture(recorder.finishRecordingAsPicture());
|
||||
@ -1657,6 +1659,8 @@ Result GPUDDLSink::ddlDraw(const Src& src,
|
||||
DDLPromiseImageHelper promiseImageHelper;
|
||||
sk_sp<SkData> compressedPictureData = promiseImageHelper.deflateSKP(inputPicture.get());
|
||||
if (!compressedPictureData) {
|
||||
gpuTaskGroup->add([gpuTestCtx] { gpuTestCtx->makeNotCurrent(); });
|
||||
gpuTaskGroup->wait();
|
||||
return Result::Fatal("GPUDDLSink: Couldn't deflate SkPicture");
|
||||
}
|
||||
|
||||
|
@ -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<GrDrawOp> 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<Vertex*>(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<Vertex*>(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;
|
||||
|
@ -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<GrPipeline::FixedDynamicState>(
|
||||
appliedClip.scissorState().rect());
|
||||
flags = GrPipeline::InputFlags::kHWAntialias;
|
||||
}
|
||||
|
||||
GrPipeline* pipeline = arena->make<GrPipeline>(initArgs,
|
||||
std::move(fProcessors),
|
||||
std::move(appliedClip));
|
||||
|
||||
GrRenderTargetProxy* outputProxy = outputView->asRenderTargetProxy();
|
||||
return arena->make<GrProgramInfo>(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<GrMesh>();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<GrPipeline>(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<GrProgramInfo>(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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user