Lift calls for setting dynamic state to Ganesh level

Previously, all backends were responsible to check for dynamic state
and update it during their internal draw calls. This CL adds
setScissor() and bindTextures() methods to GrOpsRenderTask, and places
this responsibility to update dynamic state on Ganesh instead. It also
replaces the backend-specific "onDrawMeshes" call, with a singular
"onDrawMesh" call that gets called for each mesh.

For now we keep drawMeshes() on GrOpsRenderPass for convenience, but
it will soon be removed and each call site will be responsible to set
its own dynamic state.

Change-Id: If141feae857b22cbf04416557d0c89986eda2a62
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271976
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Chris Dalton 2020-02-21 15:17:59 -07:00 committed by Skia Commit-Bot
parent 7d25230226
commit 2e7ed26cc7
21 changed files with 262 additions and 224 deletions

View File

@ -625,6 +625,9 @@ public:
SK_ABORT("Manual framebuffer barrier not supported."); SK_ABORT("Manual framebuffer barrier not supported.");
} }
// Called before certain draws in order to guarantee coherent results from dst reads.
virtual void xferBarrier(GrRenderTarget*, GrXferBarrierType) = 0;
protected: protected:
static bool MipMapsAreCorrect(SkISize dimensions, GrMipMapped, const BackendTextureData*); static bool MipMapsAreCorrect(SkISize dimensions, GrMipMapped, const BackendTextureData*);
static bool CompressedDataIsCorrect(SkISize dimensions, SkImage::CompressionType, static bool CompressedDataIsCorrect(SkISize dimensions, SkImage::CompressionType,
@ -664,9 +667,6 @@ private:
// and queries the individual sample locations. // and queries the individual sample locations.
virtual void querySampleLocations(GrRenderTarget*, SkTArray<SkPoint>*) = 0; virtual void querySampleLocations(GrRenderTarget*, SkTArray<SkPoint>*) = 0;
// Called before certain draws in order to guarantee coherent results from dst reads.
virtual void xferBarrier(GrRenderTarget*, GrXferBarrierType) = 0;
// overridden by backend-specific derived class to create objects. // overridden by backend-specific derived class to create objects.
// Texture size, renderablility, format support, sample count will have already been validated // Texture size, renderablility, format support, sample count will have already been validated
// in base class before onCreateTexture is called. // in base class before onCreateTexture is called.

View File

@ -81,35 +81,90 @@ void GrOpsRenderPass::bindPipeline(const GrProgramInfo& programInfo, const SkRec
SkASSERT(this->gpu()->findOrAssignSamplePatternKey(fRenderTarget) SkASSERT(this->gpu()->findOrAssignSamplePatternKey(fRenderTarget)
== fRenderTarget->renderTargetPriv().getSamplePatternKey()); == fRenderTarget->renderTargetPriv().getSamplePatternKey());
} }
fScissorStatus = (programInfo.pipeline().isScissorTestEnabled()) ?
DynamicStateStatus::kUninitialized : DynamicStateStatus::kDisabled;
bool hasTextures = (programInfo.primProc().numTextureSamplers() > 0);
if (!hasTextures) {
programInfo.pipeline().visitProxies([&hasTextures](GrSurfaceProxy*, GrMipMapped) {
hasTextures = true;
});
}
fTextureBindingStatus = (hasTextures) ?
DynamicStateStatus::kUninitialized : DynamicStateStatus::kDisabled;
fHasVertexAttributes = programInfo.primProc().hasVertexAttributes();
fHasInstanceAttributes = programInfo.primProc().hasInstanceAttributes();
#endif #endif
fDrawPipelineStatus = DrawPipelineStatus::kOk; fDrawPipelineStatus = DrawPipelineStatus::kOk;
fXferBarrierType = programInfo.pipeline().xferBarrierType(fRenderTarget->asTexture(),
*this->gpu()->caps());
}
void GrOpsRenderPass::setScissorRect(const SkIRect& scissor) {
if (DrawPipelineStatus::kOk != fDrawPipelineStatus) {
SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
return;
}
SkASSERT(DynamicStateStatus::kDisabled != fScissorStatus);
this->onSetScissorRect(scissor);
SkDEBUGCODE(fScissorStatus = DynamicStateStatus::kConfigured);
}
void GrOpsRenderPass::bindTextures(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
const GrSurfaceProxy* const primProcTextures[]) {
if (DrawPipelineStatus::kOk != fDrawPipelineStatus) {
SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
return;
}
SkASSERT((primProc.numTextureSamplers() > 0) == SkToBool(primProcTextures));
// Don't assert on fTextureBindingStatus. onBindTextures() just turns into a no-op when there
// aren't any textures, and it's hard to tell from the GrPipeline whether there are any. For
// many clients it is easier to just always call this method.
if (!this->onBindTextures(primProc, pipeline, primProcTextures)) {
fDrawPipelineStatus = DrawPipelineStatus::kFailedToBind;
return;
}
SkDEBUGCODE(fTextureBindingStatus = DynamicStateStatus::kConfigured);
} }
void GrOpsRenderPass::drawMeshes(const GrProgramInfo& programInfo, const GrMesh meshes[], void GrOpsRenderPass::drawMeshes(const GrProgramInfo& programInfo, const GrMesh meshes[],
int meshCount) { int meshCount) {
if (programInfo.hasFixedScissor()) {
this->setScissorRect(programInfo.fixedScissor());
}
if (!programInfo.hasDynamicPrimProcTextures()) {
auto primProcTextures = (programInfo.hasFixedPrimProcTextures()) ?
programInfo.fixedPrimProcTextures() : nullptr;
this->bindTextures(programInfo.primProc(), programInfo.pipeline(), primProcTextures);
}
for (int i = 0; i < meshCount; ++i) {
if (programInfo.hasDynamicScissors()) {
this->setScissorRect(programInfo.dynamicScissor(i));
}
if (programInfo.hasDynamicPrimProcTextures()) {
this->bindTextures(programInfo.primProc(), programInfo.pipeline(),
programInfo.dynamicPrimProcTextures(i));
}
this->drawMesh(programInfo.primitiveType(), meshes[i]);
}
}
void GrOpsRenderPass::drawMesh(GrPrimitiveType primitiveType, const GrMesh& mesh) {
if (DrawPipelineStatus::kOk != fDrawPipelineStatus) { if (DrawPipelineStatus::kOk != fDrawPipelineStatus) {
SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus); SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
this->gpu()->stats()->incNumFailedDraws(); this->gpu()->stats()->incNumFailedDraws();
return; return;
} }
#ifdef SK_DEBUG SkASSERT(DynamicStateStatus::kUninitialized != fScissorStatus);
if (int numDynamicStateArrays = programInfo.numDynamicStateArrays()) { SkASSERT(DynamicStateStatus::kUninitialized != fTextureBindingStatus);
SkASSERT(meshCount == numDynamicStateArrays); SkASSERT(SkToBool(mesh.vertexBuffer()) == fHasVertexAttributes);
} SkASSERT(SkToBool(mesh.instanceBuffer()) == fHasInstanceAttributes);
for (int i = 0; i < meshCount; ++i) { SkASSERT(GrPrimitiveRestart::kNo == mesh.primitiveRestart() ||
SkASSERT(programInfo.primProc().hasVertexAttributes() == this->gpu()->caps()->usePrimitiveRestart());
SkToBool(meshes[i].vertexBuffer()));
SkASSERT(programInfo.primProc().hasInstanceAttributes() ==
SkToBool(meshes[i].instanceBuffer()));
if (GrPrimitiveRestart::kYes == meshes[i].primitiveRestart()) {
SkASSERT(this->gpu()->caps()->usePrimitiveRestart());
}
}
#endif
if (meshCount) { if (kNone_GrXferBarrierType != fXferBarrierType) {
this->onDrawMeshes(programInfo, meshes, meshCount); this->gpu()->xferBarrier(fRenderTarget, fXferBarrierType);
} }
this->onDrawMesh(primitiveType, mesh);
} }

View File

@ -51,16 +51,35 @@ public:
virtual void end() = 0; virtual void end() = 0;
// Updates the internal pipeline state for drawing with the provided GrProgramInfo. // Updates the internal pipeline state for drawing with the provided GrProgramInfo.
// Returns false if the state could not be set. // Enters an internal "bad" state if the pipeline could not be set.
void bindPipeline(const GrProgramInfo&, const SkRect& drawBounds); void bindPipeline(const GrProgramInfo&, const SkRect& drawBounds);
// The scissor rect is always dynamic state and therefore not stored on GrPipeline. If scissor
// test is enabled on the current pipeline, then the client must call setScissorRect() before
// drawing. The scissor rect may also be updated between draws without having to bind a new
// pipeline.
void setScissorRect(const SkIRect&);
// Texture bindings are dynamic state and therefore not set during bindPipeline(). If the
// current program uses textures, then the client must call bindTextures() before drawing.
// The primitive processor textures may also be updated between draws by calling bindTextures()
// again with a different array for primProcTextures. (On subsequent calls, if the backend is
// capable of updating the primitive processor textures independently, then it will
// automatically skip binding textures from GrPipeline.)
void bindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
const GrSurfaceProxy* const primProcTextures[]);
// Draws the given array of meshes using the current pipeline state. The client must call // Draws the given array of meshes using the current pipeline state. The client must call
// bindPipeline() before using this method. // bindPipeline() before using this method.
// //
// NOTE: This method will soon be replaced by individual calls for each draw type (indexed, // NOTE: This method will soon be deleted. While it continues to exist, it takes care of calling
// instanced, indexed-patterned, indirect, etc.). // setScissor() and bindTextures() on the client's behalf.
void drawMeshes(const GrProgramInfo&, const GrMesh[], int meshCount); void drawMeshes(const GrProgramInfo&, const GrMesh[], int meshCount);
// Draws the given mesh using the current pipeline state. The client must call bindPipeline(),
// followed setScissor() and/or bindTextures() if necessary, before using this method.
void drawMesh(GrPrimitiveType, const GrMesh&);
// Performs an upload of vertex data in the middle of a set of a set of draws // Performs an upload of vertex data in the middle of a set of a set of draws
virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0; virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0;
@ -99,7 +118,10 @@ private:
// overridden by backend-specific derived class to perform the rendering command. // overridden by backend-specific derived class to perform the rendering command.
virtual bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) = 0; virtual bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) = 0;
virtual void onDrawMeshes(const GrProgramInfo&, const GrMesh[], int meshCount) = 0; virtual void onSetScissorRect(const SkIRect&) = 0;
virtual bool onBindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
const GrSurfaceProxy* const primProcTextures[] = nullptr) = 0;
virtual void onDrawMesh(GrPrimitiveType, const GrMesh&) = 0;
virtual void onClear(const GrFixedClip&, const SkPMColor4f&) = 0; virtual void onClear(const GrFixedClip&, const SkPMColor4f&) = 0;
virtual void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) = 0; virtual void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) = 0;
virtual void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) {} virtual void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) {}
@ -111,6 +133,20 @@ private:
}; };
DrawPipelineStatus fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured; DrawPipelineStatus fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
GrXferBarrierType fXferBarrierType;
#ifdef SK_DEBUG
enum class DynamicStateStatus {
kDisabled,
kUninitialized,
kConfigured
};
DynamicStateStatus fScissorStatus = DynamicStateStatus::kDisabled;
DynamicStateStatus fTextureBindingStatus = DynamicStateStatus::kDisabled;
bool fHasVertexAttributes = false;
bool fHasInstanceAttributes = false;
#endif
typedef GrOpsRenderPass INHERITED; typedef GrOpsRenderPass INHERITED;
}; };

View File

@ -23,7 +23,7 @@ GrPipeline::GrPipeline(const InitArgs& args, sk_sp<const GrXferProcessor> xferPr
fFlags |= Flags::kHasStencilClip; fFlags |= Flags::kHasStencilClip;
} }
if (hardClip.scissorState().enabled()) { if (hardClip.scissorState().enabled()) {
fFlags |= Flags::kScissorEnabled; fFlags |= Flags::kScissorTestEnabled;
} }
fWindowRectsState = hardClip.windowRectsState(); fWindowRectsState = hardClip.windowRectsState();
@ -76,7 +76,7 @@ GrPipeline::GrPipeline(GrScissorTest scissorTest, sk_sp<const GrXferProcessor> x
, fXferProcessor(std::move(xp)) , fXferProcessor(std::move(xp))
, fOutputSwizzle(outputSwizzle) { , fOutputSwizzle(outputSwizzle) {
if (GrScissorTest::kEnabled == scissorTest) { if (GrScissorTest::kEnabled == scissorTest) {
fFlags |= Flags::kScissorEnabled; fFlags |= Flags::kScissorTestEnabled;
} }
this->setUserStencil(userStencil); this->setUserStencil(userStencil);
} }

View File

@ -194,8 +194,8 @@ public:
} }
} }
bool isScissorEnabled() const { bool isScissorTestEnabled() const {
return SkToBool(fFlags & Flags::kScissorEnabled); return SkToBool(fFlags & Flags::kScissorTestEnabled);
} }
const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; } const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
@ -243,7 +243,7 @@ private:
enum class Flags : uint8_t { enum class Flags : uint8_t {
kHasStencilClip = (kLastInputFlag << 1), kHasStencilClip = (kLastInputFlag << 1),
kStencilEnabled = (kLastInputFlag << 2), kStencilEnabled = (kLastInputFlag << 2),
kScissorEnabled = (kLastInputFlag << 3), kScissorTestEnabled = (kLastInputFlag << 3),
}; };
GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags); GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);

View File

@ -39,7 +39,7 @@ void GrProgramInfo::validate(bool flushTime) const {
SkASSERT(!fPrimProc->numTextureSamplers()); SkASSERT(!fPrimProc->numTextureSamplers());
} }
SkASSERT(!fPipeline->isScissorEnabled() || this->hasFixedScissor() || SkASSERT(!fPipeline->isScissorTestEnabled() || this->hasFixedScissor() ||
this->hasDynamicScissors()); this->hasDynamicScissors());
if (this->hasDynamicPrimProcTextures()) { if (this->hasDynamicPrimProcTextures()) {

View File

@ -65,7 +65,7 @@ public:
int numDynamicStateArrays() const { return fNumDynamicStateArrays; } int numDynamicStateArrays() const { return fNumDynamicStateArrays; }
bool hasDynamicScissors() const { bool hasDynamicScissors() const {
return fPipeline->isScissorEnabled() && return fPipeline->isScissorTestEnabled() &&
fDynamicStateArrays && fDynamicStateArrays->fScissorRects; fDynamicStateArrays && fDynamicStateArrays->fScissorRects;
} }
@ -75,7 +75,7 @@ public:
return fDynamicStateArrays->fScissorRects[i]; return fDynamicStateArrays->fScissorRects[i];
} }
bool hasFixedScissor() const { return fPipeline->isScissorEnabled() && fFixedDynamicState; } bool hasFixedScissor() const { return fPipeline->isScissorTestEnabled() && fFixedDynamicState; }
const SkIRect& fixedScissor() const { const SkIRect& fixedScissor() const {
SkASSERT(this->hasFixedScissor()); SkASSERT(this->hasFixedScissor());

View File

@ -519,7 +519,7 @@ void GrCCFiller::drawFills(
void GrCCFiller::drawPrimitives( void GrCCFiller::drawPrimitives(
GrOpFlushState* flushState, const GrCCCoverageProcessor& proc, const GrPipeline& pipeline, GrOpFlushState* flushState, const GrCCCoverageProcessor& proc, const GrPipeline& pipeline,
BatchID batchID, int PrimitiveTallies::*instanceType, const SkIRect& drawBounds) const { BatchID batchID, int PrimitiveTallies::*instanceType, const SkIRect& drawBounds) const {
SkASSERT(pipeline.isScissorEnabled()); SkASSERT(pipeline.isScissorTestEnabled());
// Don't call reset(), as that also resets the reserve count. // Don't call reset(), as that also resets the reserve count.
fMeshesScratchBuffer.pop_back_n(fMeshesScratchBuffer.count()); fMeshesScratchBuffer.pop_back_n(fMeshesScratchBuffer.count());

View File

@ -1373,7 +1373,7 @@ sk_sp<GrTexture> GrGLGpu::onCreateTexture(SkISize dimensions,
} }
} else if (this->glCaps().canFormatBeFBOColorAttachment(format.asGLFormat()) && } else if (this->glCaps().canFormatBeFBOColorAttachment(format.asGLFormat()) &&
!this->glCaps().performColorClearsAsDraws()) { !this->glCaps().performColorClearsAsDraws()) {
this->disableScissor(); this->flushScissorTest(GrScissorTest::kDisabled);
this->disableWindowRectangles(); this->disableWindowRectangles();
this->flushColorWrite(true); this->flushColorWrite(true);
this->flushClearColor(SK_PMColor4fTRANSPARENT); this->flushClearColor(SK_PMColor4fTRANSPARENT);
@ -1763,23 +1763,28 @@ sk_sp<GrGpuBuffer> GrGLGpu::onCreateBuffer(size_t size, GrGpuBufferType intended
return GrGLBuffer::Make(this, size, intendedType, accessPattern, data); return GrGLBuffer::Make(this, size, intendedType, accessPattern, data);
} }
void GrGLGpu::flushScissor(const GrScissorState& scissorState, int rtWidth, int rtHeight, void GrGLGpu::flushScissorTest(GrScissorTest scissorTest) {
GrSurfaceOrigin rtOrigin) { if (GrScissorTest::kEnabled == scissorTest) {
if (scissorState.enabled()) {
auto scissor = GrNativeRect::MakeRelativeTo(rtOrigin, rtHeight, scissorState.rect());
if (fHWScissorSettings.fRect != scissor) {
GL_CALL(Scissor(scissor.fX, scissor.fY, scissor.fWidth, scissor.fHeight));
fHWScissorSettings.fRect = scissor;
}
if (kYes_TriState != fHWScissorSettings.fEnabled) { if (kYes_TriState != fHWScissorSettings.fEnabled) {
GL_CALL(Enable(GR_GL_SCISSOR_TEST)); GL_CALL(Enable(GR_GL_SCISSOR_TEST));
fHWScissorSettings.fEnabled = kYes_TriState; fHWScissorSettings.fEnabled = kYes_TriState;
} }
return; } else {
if (kNo_TriState != fHWScissorSettings.fEnabled) {
GL_CALL(Disable(GR_GL_SCISSOR_TEST));
fHWScissorSettings.fEnabled = kNo_TriState;
}
} }
}
// See fall through note above void GrGLGpu::flushScissorRect(const SkIRect& scissor, int rtWidth, int rtHeight,
this->disableScissor(); GrSurfaceOrigin rtOrigin) {
auto nativeScissor = GrNativeRect::MakeRelativeTo(rtOrigin, rtHeight, scissor);
if (fHWScissorSettings.fRect != nativeScissor) {
GL_CALL(Scissor(nativeScissor.fX, nativeScissor.fY, nativeScissor.fWidth,
nativeScissor.fHeight));
fHWScissorSettings.fRect = nativeScissor;
}
} }
void GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState, void GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState,
@ -1842,11 +1847,6 @@ bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, const GrProgramInfo& pr
programInfo.pipeline().outputSwizzle()); programInfo.pipeline().outputSwizzle());
fHWProgram->updateUniforms(renderTarget, programInfo); fHWProgram->updateUniforms(renderTarget, programInfo);
if (!programInfo.hasDynamicPrimProcTextures()) {
auto* primProcTextures = (programInfo.hasFixedPrimProcTextures())
? programInfo.fixedPrimProcTextures() : nullptr;
fHWProgram->bindTextures(programInfo.primProc(), programInfo.pipeline(), primProcTextures);
}
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget); GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
GrStencilSettings stencil; GrStencilSettings stencil;
@ -1857,14 +1857,7 @@ bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, const GrProgramInfo& pr
glRT->renderTargetPriv().numStencilBits()); glRT->renderTargetPriv().numStencilBits());
} }
this->flushStencil(stencil, programInfo.origin()); this->flushStencil(stencil, programInfo.origin());
if (programInfo.pipeline().isScissorEnabled()) { this->flushScissorTest(GrScissorTest(programInfo.pipeline().isScissorTestEnabled()));
static constexpr SkIRect kBogusScissor{0, 0, 1, 1};
GrScissorState state(programInfo.fixedDynamicState() ? programInfo.fixedScissor()
: kBogusScissor);
this->flushScissor(state, glRT->width(), glRT->height(), programInfo.origin());
} else {
this->disableScissor();
}
this->flushWindowRectangles(programInfo.pipeline().getWindowRectsState(), this->flushWindowRectangles(programInfo.pipeline().getWindowRectsState(),
glRT, programInfo.origin()); glRT, programInfo.origin());
this->flushHWAAState(glRT, programInfo.pipeline().isHWAntialiasState()); this->flushHWAAState(glRT, programInfo.pipeline().isHWAntialiasState());
@ -1979,13 +1972,6 @@ GrGLenum GrGLGpu::bindBuffer(GrGpuBufferType type, const GrBuffer* buffer) {
return bufferState->fGLTarget; return bufferState->fGLTarget;
} }
void GrGLGpu::disableScissor() {
if (kNo_TriState != fHWScissorSettings.fEnabled) {
GL_CALL(Disable(GR_GL_SCISSOR_TEST));
fHWScissorSettings.fEnabled = kNo_TriState;
return;
}
}
void GrGLGpu::clear(const GrFixedClip& clip, const SkPMColor4f& color, void GrGLGpu::clear(const GrFixedClip& clip, const SkPMColor4f& color,
GrRenderTarget* target, GrSurfaceOrigin origin) { GrRenderTarget* target, GrSurfaceOrigin origin) {
@ -2023,7 +2009,7 @@ void GrGLGpu::clearStencil(GrRenderTarget* target, int clearValue) {
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
this->flushRenderTargetNoColorWrites(glRT); this->flushRenderTargetNoColorWrites(glRT);
this->disableScissor(); this->flushScissorTest(GrScissorTest::kDisabled);
this->disableWindowRectangles(); this->disableWindowRectangles();
GL_CALL(StencilMask(0xffffffff)); GL_CALL(StencilMask(0xffffffff));
@ -2074,7 +2060,7 @@ void GrGLGpu::beginCommandBuffer(GrRenderTarget* rt, const SkIRect& bounds, GrSu
clearMask |= GR_GL_STENCIL_BUFFER_BIT; clearMask |= GR_GL_STENCIL_BUFFER_BIT;
} }
if (clearMask) { if (clearMask) {
this->disableScissor(); this->flushScissorTest(GrScissorTest::kDisabled);
this->disableWindowRectangles(); this->disableWindowRectangles();
GL_CALL(Clear(clearMask)); GL_CALL(Clear(clearMask));
} }
@ -2374,38 +2360,17 @@ void GrGLGpu::flushViewport(int width, int height) {
#endif #endif
#endif #endif
void GrGLGpu::drawMeshes(GrRenderTarget* renderTarget, const GrProgramInfo& programInfo, void GrGLGpu::drawMesh(GrRenderTarget* renderTarget, GrPrimitiveType primitiveType,
const GrMesh meshes[], int meshCount) { const GrMesh& mesh) {
SkASSERT(meshCount); // guaranteed by GrOpsRenderPass::draw if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
GrIsPrimTypeLines(primitiveType) && !GrIsPrimTypeLines(fLastPrimitiveType)) {
bool hasDynamicScissors = programInfo.hasDynamicScissors(); GL_CALL(Enable(GR_GL_CULL_FACE));
bool hasDynamicPrimProcTextures = programInfo.hasDynamicPrimProcTextures(); GL_CALL(Disable(GR_GL_CULL_FACE));
for (int m = 0; m < meshCount; ++m) {
if (auto barrierType = programInfo.pipeline().xferBarrierType(renderTarget->asTexture(),
*this->caps())) {
this->xferBarrier(renderTarget, barrierType);
}
if (hasDynamicScissors) {
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
this->flushScissor(GrScissorState(programInfo.dynamicScissor(m)),
glRT->width(), glRT->height(), programInfo.origin());
}
if (hasDynamicPrimProcTextures) {
fHWProgram->bindTextures(programInfo.primProc(), programInfo.pipeline(),
programInfo.dynamicPrimProcTextures(m));
}
if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
GrIsPrimTypeLines(programInfo.primitiveType()) &&
!GrIsPrimTypeLines(fLastPrimitiveType)) {
GL_CALL(Enable(GR_GL_CULL_FACE));
GL_CALL(Disable(GR_GL_CULL_FACE));
}
meshes[m].sendToGpu(programInfo.primitiveType(), this);
fLastPrimitiveType = programInfo.primitiveType();
} }
mesh.sendToGpu(primitiveType, this);
fLastPrimitiveType = primitiveType;
#if SWAP_PER_DRAW #if SWAP_PER_DRAW
glFlush(); glFlush();
#if defined(SK_BUILD_FOR_MAC) #if defined(SK_BUILD_FOR_MAC)
@ -2550,7 +2515,7 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resol
} }
// BlitFrameBuffer respects the scissor, so disable it. // BlitFrameBuffer respects the scissor, so disable it.
this->disableScissor(); this->flushScissorTest(GrScissorTest::kDisabled);
this->disableWindowRectangles(); this->disableWindowRectangles();
GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t, GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t, GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
} }
@ -3539,7 +3504,7 @@ bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurface* src, const SkIRect& s
this->flushHWAAState(nullptr, false); this->flushHWAAState(nullptr, false);
this->flushConservativeRasterState(false); this->flushConservativeRasterState(false);
this->flushWireframeState(false); this->flushWireframeState(false);
this->disableScissor(); this->flushScissorTest(GrScissorTest::kDisabled);
this->disableWindowRectangles(); this->disableWindowRectangles();
this->disableStencil(); this->disableStencil();
if (this->glCaps().srgbWriteControl()) { if (this->glCaps().srgbWriteControl()) {
@ -3590,7 +3555,7 @@ bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const
fHWBoundRenderTargetUniqueID.makeInvalid(); fHWBoundRenderTargetUniqueID.makeInvalid();
// BlitFrameBuffer respects the scissor, so disable it. // BlitFrameBuffer respects the scissor, so disable it.
this->disableScissor(); this->flushScissorTest(GrScissorTest::kDisabled);
this->disableWindowRectangles(); this->disableWindowRectangles();
GL_CALL(BlitFramebuffer(srcRect.fLeft, GL_CALL(BlitFramebuffer(srcRect.fLeft,
@ -3672,7 +3637,7 @@ bool GrGLGpu::onRegenerateMipMapLevels(GrTexture* texture) {
// Set "simple" state once: // Set "simple" state once:
this->flushBlendAndColorWrite(GrXferProcessor::BlendInfo(), GrSwizzle::RGBA()); this->flushBlendAndColorWrite(GrXferProcessor::BlendInfo(), GrSwizzle::RGBA());
this->flushHWAAState(nullptr, false); this->flushHWAAState(nullptr, false);
this->disableScissor(); this->flushScissorTest(GrScissorTest::kDisabled);
this->disableWindowRectangles(); this->disableWindowRectangles();
this->disableStencil(); this->disableStencil();

View File

@ -75,13 +75,18 @@ public:
// Flushes state from GrProgramInfo to GL. Returns false if the state couldn't be set. // Flushes state from GrProgramInfo to GL. Returns false if the state couldn't be set.
bool flushGLState(GrRenderTarget*, const GrProgramInfo&); bool flushGLState(GrRenderTarget*, const GrProgramInfo&);
void flushScissorRect(const SkIRect&, int rtWidth, int rtHeight, GrSurfaceOrigin);
void bindTextures(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
const GrSurfaceProxy* const primProcTextures[] = nullptr) {
fHWProgram->bindTextures(primProc, pipeline, primProcTextures);
}
// The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu. // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
// Thus this is the implementation of the draw call for the corresponding passthrough function // Thus this is the implementation of the draw call for the corresponding passthrough function
// on GrGLOpsRenderPass. // on GrGLOpsRenderPass.
// //
// The client must call flushGLState before this method. // The client must call flushGLState before this method.
void drawMeshes(GrRenderTarget*, const GrProgramInfo&, const GrMesh[], int meshCount); void drawMesh(GrRenderTarget*, GrPrimitiveType, const GrMesh&);
// GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls. // GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls.
// Marked final as a hint to the compiler to not use virtual dispatch. // Marked final as a hint to the compiler to not use virtual dispatch.
@ -357,10 +362,14 @@ private:
// flushes the scissor. see the note on flushBoundTextureAndParams about // flushes the scissor. see the note on flushBoundTextureAndParams about
// flushing the scissor after that function is called. // flushing the scissor after that function is called.
void flushScissor(const GrScissorState&, int rtWidth, int rtHeight, GrSurfaceOrigin rtOrigin); void flushScissor(const GrScissorState& scissorState, int rtWidth, int rtHeight,
GrSurfaceOrigin rtOrigin) {
// disables the scissor this->flushScissorTest(GrScissorTest(scissorState.enabled()));
void disableScissor(); if (scissorState.enabled()) {
this->flushScissorRect(scissorState.rect(), rtWidth, rtHeight, rtOrigin);
}
}
void flushScissorTest(GrScissorTest);
void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin); void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
void disableWindowRectangles(); void disableWindowRectangles();

View File

@ -53,9 +53,18 @@ private:
return fGpu->flushGLState(fRenderTarget, programInfo); return fGpu->flushGLState(fRenderTarget, programInfo);
} }
void onDrawMeshes(const GrProgramInfo& programInfo, const GrMesh mesh[], void onSetScissorRect(const SkIRect& scissor) override {
int meshCount) override { fGpu->flushScissorRect(scissor, fRenderTarget->width(), fRenderTarget->height(), fOrigin);
fGpu->drawMeshes(fRenderTarget, programInfo, mesh, meshCount); }
bool onBindTextures(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
const GrSurfaceProxy* const primProcTextures[]) override {
fGpu->bindTextures(primProc, pipeline, primProcTextures);
return true;
}
void onDrawMesh(GrPrimitiveType primitiveType, const GrMesh& mesh) override {
fGpu->drawMesh(fRenderTarget, primitiveType, mesh);
} }
void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override { void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override {

View File

@ -5,16 +5,14 @@
* found in the LICENSE file. * found in the LICENSE file.
*/ */
#include "src/gpu/gl/GrGLGpu.h"
#include "src/gpu/gl/GrGLPathRendering.h"
#include "src/gpu/gl/GrGLUtil.h"
#include "src/gpu/GrRenderTargetProxy.h"
#include "src/gpu/gl/GrGLPath.h"
#include "src/gpu/gl/GrGLPathRendering.h"
#include "include/core/SkStream.h" #include "include/core/SkStream.h"
#include "include/core/SkTypeface.h" #include "include/core/SkTypeface.h"
#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRenderTargetProxy.h"
#include "src/gpu/gl/GrGLGpu.h"
#include "src/gpu/gl/GrGLPath.h"
#include "src/gpu/gl/GrGLPathRendering.h"
#include "src/gpu/gl/GrGLUtil.h"
#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->gpu()->glInterface(), RET, X) #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->gpu()->glInterface(), RET, X)
@ -115,9 +113,16 @@ void GrGLPathRendering::onDrawPath(GrRenderTarget* renderTarget,
const GrProgramInfo& programInfo, const GrProgramInfo& programInfo,
const GrStencilSettings& stencilPassSettings, const GrStencilSettings& stencilPassSettings,
const GrPath* path) { const GrPath* path) {
SkASSERT(!programInfo.hasDynamicScissors());
SkASSERT(!programInfo.hasDynamicPrimProcTextures());
if (!this->gpu()->flushGLState(renderTarget, programInfo)) { if (!this->gpu()->flushGLState(renderTarget, programInfo)) {
return; return;
} }
if (programInfo.hasFixedScissor()) {
this->gpu()->flushScissorRect(programInfo.fixedScissor(), renderTarget->width(),
renderTarget->height(), programInfo.origin());
}
this->gpu()->bindTextures(programInfo.primProc(), programInfo.pipeline());
const GrGLPath* glPath = static_cast<const GrGLPath*>(path); const GrGLPath* glPath = static_cast<const GrGLPath*>(path);

View File

@ -101,11 +101,10 @@ void GrGLProgram::updateUniforms(const GrRenderTarget* renderTarget,
} }
void GrGLProgram::bindTextures(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, void GrGLProgram::bindTextures(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
const GrSurfaceProxy* const primProcTextureOverrides[]) { const GrSurfaceProxy* const primProcTextures[]) {
for (int i = 0; i < primProc.numTextureSamplers(); ++i) { for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
SkASSERT(primProcTextureOverrides[i]->asTextureProxy()); SkASSERT(primProcTextures[i]->asTextureProxy());
auto* overrideTexture = static_cast<GrGLTexture*>( auto* overrideTexture = static_cast<GrGLTexture*>(primProcTextures[i]->peekTexture());
primProcTextureOverrides[i]->peekTexture());
fGpu->bindTexture(i, primProc.textureSampler(i).samplerState(), fGpu->bindTexture(i, primProc.textureSampler(i).samplerState(),
primProc.textureSampler(i).swizzle(), overrideTexture); primProc.textureSampler(i).swizzle(), overrideTexture);
} }

View File

@ -120,12 +120,10 @@ public:
void updateUniforms(const GrRenderTarget*, const GrProgramInfo&); void updateUniforms(const GrRenderTarget*, const GrProgramInfo&);
/** /**
* Binds all primitive processor and fragment processor textures. We configure primitive * Binds all primitive processor and fragment processor textures.
* processor samplers based on the proxies on the processor itself, but the actual textures we
* bind come from primProcTextureOverrides.
*/ */
void bindTextures(const GrPrimitiveProcessor&, const GrPipeline&, void bindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
const GrSurfaceProxy* const primProcTextureOverrides[]); const GrSurfaceProxy* const primProcTextures[]);
int vertexStride() const { return fVertexStride; } int vertexStride() const { return fVertexStride; }
int instanceStride() const { return fInstanceStride; } int instanceStride() const { return fInstanceStride; }

View File

@ -37,7 +37,12 @@ private:
bool onBindPipeline(const GrProgramInfo&, const SkRect&) override { bool onBindPipeline(const GrProgramInfo&, const SkRect&) override {
return true; return true;
} }
void onDrawMeshes(const GrProgramInfo&, const GrMesh[], int meshCount) override { void onSetScissorRect(const SkIRect&) override {}
bool onBindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
const GrSurfaceProxy* const primProcTextures[]) override {
return true;
}
void onDrawMesh(GrPrimitiveType, const GrMesh&) override {
this->markRenderTargetDirty(); this->markRenderTargetDirty();
++fNumDraws; ++fNumDraws;
} }
@ -45,7 +50,6 @@ private:
this->markRenderTargetDirty(); this->markRenderTargetDirty();
} }
void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override {} void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override {}
void markRenderTargetDirty() { void markRenderTargetDirty() {
if (auto* tex = fRenderTarget->asTexture()) { if (auto* tex = fRenderTarget->asTexture()) {
tex->texturePriv().markMipMapsDirty(); tex->texturePriv().markMipMapsDirty();

View File

@ -40,8 +40,10 @@ private:
GrGpu* gpu() override { return fGpu; } GrGpu* gpu() override { return fGpu; }
bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) override; bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) override;
void onSetScissorRect(const SkIRect&) override;
void onDrawMeshes(const GrProgramInfo&, const GrMesh[], int meshCount) override; bool onBindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
const GrSurfaceProxy* const primProcTextures[]) override;
void onDrawMesh(GrPrimitiveType, const GrMesh&) override;
void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override; void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override;

View File

@ -75,48 +75,39 @@ bool GrMtlOpsRenderPass::onBindPipeline(const GrProgramInfo& programInfo,
[fActiveRenderCmdEncoder setTriangleFillMode:MTLTriangleFillModeFill]; [fActiveRenderCmdEncoder setTriangleFillMode:MTLTriangleFillModeFill];
} }
if (!programInfo.pipeline().isScissorEnabled()) { if (!programInfo.pipeline().isScissorTestEnabled()) {
// "Disable" scissor by setting it to the full pipeline bounds.
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder, GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder,
fRenderTarget, fOrigin, fRenderTarget, fOrigin,
SkIRect::MakeWH(fRenderTarget->width(), SkIRect::MakeWH(fRenderTarget->width(),
fRenderTarget->height())); fRenderTarget->height()));
} else if (!programInfo.hasDynamicScissors()) {
SkASSERT(programInfo.hasFixedScissor());
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder,
fRenderTarget, fOrigin,
programInfo.fixedScissor());
}
if (!programInfo.hasDynamicPrimProcTextures()) {
fActivePipelineState->bindTextures(fActiveRenderCmdEncoder);
} }
fBounds.join(drawBounds); fBounds.join(drawBounds);
return true; return true;
} }
void GrMtlOpsRenderPass::onDrawMeshes(const GrProgramInfo& programInfo, const GrMesh meshes[], void GrMtlOpsRenderPass::onSetScissorRect(const SkIRect& scissor) {
int meshCount) {
SkASSERT(fActivePipelineState); SkASSERT(fActivePipelineState);
SkASSERT(fActiveRenderCmdEncoder);
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder, fRenderTarget,
fOrigin, scissor);
}
for (int i = 0; i < meshCount; ++i) { bool GrMtlOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc,
const GrMesh& mesh = meshes[i]; const GrPipeline& pipeline,
SkASSERT(nil != fActiveRenderCmdEncoder); const GrSurfaceProxy* const primProcTextures[]) {
SkASSERT(fActivePipelineState);
SkASSERT(fActiveRenderCmdEncoder);
fActivePipelineState->setTextures(primProc, pipeline, primProcTextures);
fActivePipelineState->bindTextures(fActiveRenderCmdEncoder);
return true;
}
if (programInfo.hasDynamicScissors()) { void GrMtlOpsRenderPass::onDrawMesh(GrPrimitiveType primitiveType, const GrMesh& mesh) {
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder, fRenderTarget, SkASSERT(fActivePipelineState);
fOrigin, SkASSERT(nil != fActiveRenderCmdEncoder);
programInfo.dynamicScissor(i)); mesh.sendToGpu(primitiveType, this);
}
if (programInfo.hasDynamicPrimProcTextures()) {
auto meshProxies = programInfo.dynamicPrimProcTextures(i);
fActivePipelineState->setTextures(programInfo, meshProxies);
fActivePipelineState->bindTextures(fActiveRenderCmdEncoder);
}
mesh.sendToGpu(programInfo.primitiveType(), this);
}
} }
void GrMtlOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) { void GrMtlOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {

View File

@ -48,8 +48,7 @@ public:
void setData(const GrRenderTarget*, const GrProgramInfo&); void setData(const GrRenderTarget*, const GrProgramInfo&);
void setTextures(const GrProgramInfo& programInfo, void setTextures(const GrPrimitiveProcessor&, const GrPipeline&, const GrSurfaceProxy* const[]);
const GrSurfaceProxy* const primProcTextures[]);
void bindTextures(id<MTLRenderCommandEncoder> renderCmdEncoder); void bindTextures(id<MTLRenderCommandEncoder> renderCmdEncoder);
void setDrawState(id<MTLRenderCommandEncoder>, const GrSwizzle& outputSwizzle, void setDrawState(id<MTLRenderCommandEncoder>, const GrSwizzle& outputSwizzle,

View File

@ -76,11 +76,6 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
offset); offset);
} }
if (!programInfo.hasDynamicPrimProcTextures()) {
auto proxies = programInfo.hasFixedPrimProcTextures() ? programInfo.fixedPrimProcTextures()
: nullptr;
this->setTextures(programInfo, proxies);
}
fDataManager.resetDirtyBits(); fDataManager.resetDirtyBits();
#ifdef SK_DEBUG #ifdef SK_DEBUG
@ -93,17 +88,18 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
fStencil = programInfo.nonGLStencilSettings(); fStencil = programInfo.nonGLStencilSettings();
} }
void GrMtlPipelineState::setTextures(const GrProgramInfo& programInfo, void GrMtlPipelineState::setTextures(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
const GrSurfaceProxy* const primProcTextures[]) { const GrSurfaceProxy* const primProcTextures[]) {
fSamplerBindings.reset(); fSamplerBindings.reset();
for (int i = 0; i < programInfo.primProc().numTextureSamplers(); ++i) { for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
SkASSERT(primProcTextures[i]->asTextureProxy()); SkASSERT(primProcTextures[i]->asTextureProxy());
const auto& sampler = programInfo.primProc().textureSampler(i); const auto& sampler = primProc.textureSampler(i);
auto texture = static_cast<GrMtlTexture*>(primProcTextures[i]->peekTexture()); auto texture = static_cast<GrMtlTexture*>(primProcTextures[i]->peekTexture());
fSamplerBindings.emplace_back(sampler.samplerState(), texture, fGpu); fSamplerBindings.emplace_back(sampler.samplerState(), texture, fGpu);
} }
GrFragmentProcessor::CIter fpIter(programInfo.pipeline()); GrFragmentProcessor::CIter fpIter(pipeline);
for (; fpIter; ++fpIter) { for (; fpIter; ++fpIter) {
for (int i = 0; i < fpIter->numTextureSamplers(); ++i) { for (int i = 0; i < fpIter->numTextureSamplers(); ++i) {
const auto& sampler = fpIter->textureSampler(i); const auto& sampler = fpIter->textureSampler(i);
@ -111,7 +107,7 @@ void GrMtlPipelineState::setTextures(const GrProgramInfo& programInfo,
} }
} }
if (GrTextureProxy* dstTextureProxy = programInfo.pipeline().dstProxyView().asTextureProxy()) { if (GrTextureProxy* dstTextureProxy = pipeline.dstProxyView().asTextureProxy()) {
fSamplerBindings.emplace_back( fSamplerBindings.emplace_back(
GrSamplerState::Filter::kNearest, dstTextureProxy->peekTexture(), fGpu); GrSamplerState::Filter::kNearest, dstTextureProxy->peekTexture(), fGpu);
} }

View File

@ -557,28 +557,10 @@ bool GrVkOpsRenderPass::onBindPipeline(const GrProgramInfo& programInfo, const S
return false; return false;
} }
// Check whether we need to bind textures between each GrMesh. If not we can bind them all now. if (!programInfo.pipeline().isScissorTestEnabled()) {
if (!programInfo.hasDynamicPrimProcTextures()) { // "Disable" scissor by setting it to the full pipeline bounds.
auto proxies = programInfo.hasFixedPrimProcTextures() ? programInfo.fixedPrimProcTextures()
: nullptr;
if (!fCurrentPipelineState->setAndBindTextures(
fGpu, programInfo.primProc(), programInfo.pipeline(), proxies, currentCB)) {
return false;
}
}
if (!programInfo.pipeline().isScissorEnabled()) {
GrVkPipeline::SetDynamicScissorRectState(fGpu, currentCB, fRenderTarget, fOrigin, GrVkPipeline::SetDynamicScissorRectState(fGpu, currentCB, fRenderTarget, fOrigin,
fCurrentPipelineBounds); fCurrentPipelineBounds);
} else if (!programInfo.hasDynamicScissors()) {
SkASSERT(programInfo.hasFixedScissor());
SkIRect combinedScissorRect;
if (!combinedScissorRect.intersect(fCurrentPipelineBounds, programInfo.fixedScissor())) {
combinedScissorRect = SkIRect::MakeEmpty();
}
GrVkPipeline::SetDynamicScissorRectState(fGpu, currentCB, fRenderTarget, fOrigin,
combinedScissorRect);
} }
GrVkPipeline::SetDynamicViewportState(fGpu, currentCB, fRenderTarget); GrVkPipeline::SetDynamicViewportState(fGpu, currentCB, fRenderTarget);
GrVkPipeline::SetDynamicBlendConstantState(fGpu, currentCB, GrVkPipeline::SetDynamicBlendConstantState(fGpu, currentCB,
@ -588,50 +570,36 @@ bool GrVkOpsRenderPass::onBindPipeline(const GrProgramInfo& programInfo, const S
return true; return true;
} }
void GrVkOpsRenderPass::onDrawMeshes(const GrProgramInfo& programInfo, const GrMesh meshes[], void GrVkOpsRenderPass::onSetScissorRect(const SkIRect& scissor) {
int meshCount) { SkIRect combinedScissorRect;
if (!combinedScissorRect.intersect(fCurrentPipelineBounds, scissor)) {
combinedScissorRect = SkIRect::MakeEmpty();
}
GrVkPipeline::SetDynamicScissorRectState(fGpu, this->currentCommandBuffer(), fRenderTarget,
fOrigin, combinedScissorRect);
}
bool GrVkOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
const GrSurfaceProxy* const primProcTextures[]) {
return fCurrentPipelineState->setAndBindTextures(fGpu, primProc, pipeline, primProcTextures,
this->currentCommandBuffer());
}
void GrVkOpsRenderPass::onDrawMesh(GrPrimitiveType primitiveType, const GrMesh& mesh) {
if (!fCurrentRenderPass) { if (!fCurrentRenderPass) {
SkASSERT(fGpu->isDeviceLost()); SkASSERT(fGpu->isDeviceLost());
return; return;
} }
SkASSERT(fCurrentPipelineState); SkASSERT(fCurrentPipelineState);
SkASSERT(meshCount); // guaranteed by GrOpsRenderPass::draw mesh.sendToGpu(primitiveType, this);
for (int i = 0; i < meshCount; ++i) {
const GrMesh& mesh = meshes[i];
if (programInfo.hasDynamicScissors()) {
SkIRect combinedScissorRect;
if (!combinedScissorRect.intersect(fCurrentPipelineBounds,
programInfo.dynamicScissor(i))) {
combinedScissorRect = SkIRect::MakeEmpty();
}
GrVkPipeline::SetDynamicScissorRectState(fGpu, this->currentCommandBuffer(),
fRenderTarget, fOrigin, combinedScissorRect);
}
if (programInfo.hasDynamicPrimProcTextures()) {
auto meshProxies = programInfo.dynamicPrimProcTextures(i);
if (!fCurrentPipelineState->setAndBindTextures(fGpu, programInfo.primProc(),
programInfo.pipeline(), meshProxies,
this->currentCommandBuffer())) {
if (fGpu->isDeviceLost()) {
return;
} else {
continue;
}
}
}
mesh.sendToGpu(programInfo.primitiveType(), this);
}
fCurrentCBIsEmpty = false; fCurrentCBIsEmpty = false;
} }
void GrVkOpsRenderPass::sendInstancedMeshToGpu(GrPrimitiveType, const GrMesh& mesh, int vertexCount, void GrVkOpsRenderPass::sendInstancedMeshToGpu(GrPrimitiveType, const GrMesh& mesh, int vertexCount,
int baseVertex, int instanceCount, int baseVertex, int instanceCount,
int baseInstance) int baseInstance) {
{
SkASSERT(!mesh.vertexBuffer() || !mesh.vertexBuffer()->isCpuBuffer()); SkASSERT(!mesh.vertexBuffer() || !mesh.vertexBuffer()->isCpuBuffer());
SkASSERT(!mesh.instanceBuffer() || !mesh.instanceBuffer()->isCpuBuffer()); SkASSERT(!mesh.instanceBuffer() || !mesh.instanceBuffer()->isCpuBuffer());
auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(mesh.vertexBuffer()); auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(mesh.vertexBuffer());

View File

@ -69,8 +69,10 @@ private:
const GrGpuBuffer* instanceBuffer); const GrGpuBuffer* instanceBuffer);
bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) override; bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) override;
void onSetScissorRect(const SkIRect&) override;
void onDrawMeshes(const GrProgramInfo&, const GrMesh[], int meshCount) override; bool onBindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
const GrSurfaceProxy* const primProcTextures[]) override;
void onDrawMesh(GrPrimitiveType, const GrMesh&) override;
// GrMesh::SendToGpuImpl methods. These issue the actual Vulkan draw commands. // GrMesh::SendToGpuImpl methods. These issue the actual Vulkan draw commands.
// Marked final as a hint to the compiler to not use virtual dispatch. // Marked final as a hint to the compiler to not use virtual dispatch.