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:
parent
7d25230226
commit
2e7ed26cc7
@ -625,6 +625,9 @@ public:
|
||||
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:
|
||||
static bool MipMapsAreCorrect(SkISize dimensions, GrMipMapped, const BackendTextureData*);
|
||||
static bool CompressedDataIsCorrect(SkISize dimensions, SkImage::CompressionType,
|
||||
@ -664,9 +667,6 @@ private:
|
||||
// and queries the individual sample locations.
|
||||
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.
|
||||
// Texture size, renderablility, format support, sample count will have already been validated
|
||||
// in base class before onCreateTexture is called.
|
||||
|
@ -81,35 +81,90 @@ void GrOpsRenderPass::bindPipeline(const GrProgramInfo& programInfo, const SkRec
|
||||
SkASSERT(this->gpu()->findOrAssignSamplePatternKey(fRenderTarget)
|
||||
== 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
|
||||
|
||||
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[],
|
||||
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) {
|
||||
SkASSERT(DrawPipelineStatus::kNotConfigured != fDrawPipelineStatus);
|
||||
this->gpu()->stats()->incNumFailedDraws();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
if (int numDynamicStateArrays = programInfo.numDynamicStateArrays()) {
|
||||
SkASSERT(meshCount == numDynamicStateArrays);
|
||||
}
|
||||
for (int i = 0; i < meshCount; ++i) {
|
||||
SkASSERT(programInfo.primProc().hasVertexAttributes() ==
|
||||
SkToBool(meshes[i].vertexBuffer()));
|
||||
SkASSERT(programInfo.primProc().hasInstanceAttributes() ==
|
||||
SkToBool(meshes[i].instanceBuffer()));
|
||||
if (GrPrimitiveRestart::kYes == meshes[i].primitiveRestart()) {
|
||||
SkASSERT(this->gpu()->caps()->usePrimitiveRestart());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SkASSERT(DynamicStateStatus::kUninitialized != fScissorStatus);
|
||||
SkASSERT(DynamicStateStatus::kUninitialized != fTextureBindingStatus);
|
||||
SkASSERT(SkToBool(mesh.vertexBuffer()) == fHasVertexAttributes);
|
||||
SkASSERT(SkToBool(mesh.instanceBuffer()) == fHasInstanceAttributes);
|
||||
SkASSERT(GrPrimitiveRestart::kNo == mesh.primitiveRestart() ||
|
||||
this->gpu()->caps()->usePrimitiveRestart());
|
||||
|
||||
if (meshCount) {
|
||||
this->onDrawMeshes(programInfo, meshes, meshCount);
|
||||
if (kNone_GrXferBarrierType != fXferBarrierType) {
|
||||
this->gpu()->xferBarrier(fRenderTarget, fXferBarrierType);
|
||||
}
|
||||
this->onDrawMesh(primitiveType, mesh);
|
||||
}
|
||||
|
@ -51,16 +51,35 @@ public:
|
||||
virtual void end() = 0;
|
||||
|
||||
// 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);
|
||||
|
||||
// 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
|
||||
// bindPipeline() before using this method.
|
||||
//
|
||||
// NOTE: This method will soon be replaced by individual calls for each draw type (indexed,
|
||||
// instanced, indexed-patterned, indirect, etc.).
|
||||
// NOTE: This method will soon be deleted. While it continues to exist, it takes care of calling
|
||||
// setScissor() and bindTextures() on the client's behalf.
|
||||
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
|
||||
virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0;
|
||||
|
||||
@ -99,7 +118,10 @@ private:
|
||||
|
||||
// overridden by backend-specific derived class to perform the rendering command.
|
||||
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 onClearStencilClip(const GrFixedClip&, bool insideStencilMask) = 0;
|
||||
virtual void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) {}
|
||||
@ -111,6 +133,20 @@ private:
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
@ -23,7 +23,7 @@ GrPipeline::GrPipeline(const InitArgs& args, sk_sp<const GrXferProcessor> xferPr
|
||||
fFlags |= Flags::kHasStencilClip;
|
||||
}
|
||||
if (hardClip.scissorState().enabled()) {
|
||||
fFlags |= Flags::kScissorEnabled;
|
||||
fFlags |= Flags::kScissorTestEnabled;
|
||||
}
|
||||
|
||||
fWindowRectsState = hardClip.windowRectsState();
|
||||
@ -76,7 +76,7 @@ GrPipeline::GrPipeline(GrScissorTest scissorTest, sk_sp<const GrXferProcessor> x
|
||||
, fXferProcessor(std::move(xp))
|
||||
, fOutputSwizzle(outputSwizzle) {
|
||||
if (GrScissorTest::kEnabled == scissorTest) {
|
||||
fFlags |= Flags::kScissorEnabled;
|
||||
fFlags |= Flags::kScissorTestEnabled;
|
||||
}
|
||||
this->setUserStencil(userStencil);
|
||||
}
|
||||
|
@ -194,8 +194,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool isScissorEnabled() const {
|
||||
return SkToBool(fFlags & Flags::kScissorEnabled);
|
||||
bool isScissorTestEnabled() const {
|
||||
return SkToBool(fFlags & Flags::kScissorTestEnabled);
|
||||
}
|
||||
|
||||
const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
|
||||
@ -243,7 +243,7 @@ private:
|
||||
enum class Flags : uint8_t {
|
||||
kHasStencilClip = (kLastInputFlag << 1),
|
||||
kStencilEnabled = (kLastInputFlag << 2),
|
||||
kScissorEnabled = (kLastInputFlag << 3),
|
||||
kScissorTestEnabled = (kLastInputFlag << 3),
|
||||
};
|
||||
|
||||
GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
|
||||
|
@ -39,7 +39,7 @@ void GrProgramInfo::validate(bool flushTime) const {
|
||||
SkASSERT(!fPrimProc->numTextureSamplers());
|
||||
}
|
||||
|
||||
SkASSERT(!fPipeline->isScissorEnabled() || this->hasFixedScissor() ||
|
||||
SkASSERT(!fPipeline->isScissorTestEnabled() || this->hasFixedScissor() ||
|
||||
this->hasDynamicScissors());
|
||||
|
||||
if (this->hasDynamicPrimProcTextures()) {
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
int numDynamicStateArrays() const { return fNumDynamicStateArrays; }
|
||||
|
||||
bool hasDynamicScissors() const {
|
||||
return fPipeline->isScissorEnabled() &&
|
||||
return fPipeline->isScissorTestEnabled() &&
|
||||
fDynamicStateArrays && fDynamicStateArrays->fScissorRects;
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ public:
|
||||
return fDynamicStateArrays->fScissorRects[i];
|
||||
}
|
||||
|
||||
bool hasFixedScissor() const { return fPipeline->isScissorEnabled() && fFixedDynamicState; }
|
||||
bool hasFixedScissor() const { return fPipeline->isScissorTestEnabled() && fFixedDynamicState; }
|
||||
|
||||
const SkIRect& fixedScissor() const {
|
||||
SkASSERT(this->hasFixedScissor());
|
||||
|
@ -519,7 +519,7 @@ void GrCCFiller::drawFills(
|
||||
void GrCCFiller::drawPrimitives(
|
||||
GrOpFlushState* flushState, const GrCCCoverageProcessor& proc, const GrPipeline& pipeline,
|
||||
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.
|
||||
fMeshesScratchBuffer.pop_back_n(fMeshesScratchBuffer.count());
|
||||
|
@ -1373,7 +1373,7 @@ sk_sp<GrTexture> GrGLGpu::onCreateTexture(SkISize dimensions,
|
||||
}
|
||||
} else if (this->glCaps().canFormatBeFBOColorAttachment(format.asGLFormat()) &&
|
||||
!this->glCaps().performColorClearsAsDraws()) {
|
||||
this->disableScissor();
|
||||
this->flushScissorTest(GrScissorTest::kDisabled);
|
||||
this->disableWindowRectangles();
|
||||
this->flushColorWrite(true);
|
||||
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);
|
||||
}
|
||||
|
||||
void GrGLGpu::flushScissor(const GrScissorState& scissorState, int rtWidth, int rtHeight,
|
||||
GrSurfaceOrigin rtOrigin) {
|
||||
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;
|
||||
}
|
||||
void GrGLGpu::flushScissorTest(GrScissorTest scissorTest) {
|
||||
if (GrScissorTest::kEnabled == scissorTest) {
|
||||
if (kYes_TriState != fHWScissorSettings.fEnabled) {
|
||||
GL_CALL(Enable(GR_GL_SCISSOR_TEST));
|
||||
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
|
||||
this->disableScissor();
|
||||
void GrGLGpu::flushScissorRect(const SkIRect& scissor, int rtWidth, int rtHeight,
|
||||
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,
|
||||
@ -1842,11 +1847,6 @@ bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, const GrProgramInfo& pr
|
||||
programInfo.pipeline().outputSwizzle());
|
||||
|
||||
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);
|
||||
GrStencilSettings stencil;
|
||||
@ -1857,14 +1857,7 @@ bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, const GrProgramInfo& pr
|
||||
glRT->renderTargetPriv().numStencilBits());
|
||||
}
|
||||
this->flushStencil(stencil, programInfo.origin());
|
||||
if (programInfo.pipeline().isScissorEnabled()) {
|
||||
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->flushScissorTest(GrScissorTest(programInfo.pipeline().isScissorTestEnabled()));
|
||||
this->flushWindowRectangles(programInfo.pipeline().getWindowRectsState(),
|
||||
glRT, programInfo.origin());
|
||||
this->flushHWAAState(glRT, programInfo.pipeline().isHWAntialiasState());
|
||||
@ -1979,13 +1972,6 @@ GrGLenum GrGLGpu::bindBuffer(GrGpuBufferType type, const GrBuffer* buffer) {
|
||||
|
||||
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,
|
||||
GrRenderTarget* target, GrSurfaceOrigin origin) {
|
||||
@ -2023,7 +2009,7 @@ void GrGLGpu::clearStencil(GrRenderTarget* target, int clearValue) {
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
|
||||
this->flushRenderTargetNoColorWrites(glRT);
|
||||
|
||||
this->disableScissor();
|
||||
this->flushScissorTest(GrScissorTest::kDisabled);
|
||||
this->disableWindowRectangles();
|
||||
|
||||
GL_CALL(StencilMask(0xffffffff));
|
||||
@ -2074,7 +2060,7 @@ void GrGLGpu::beginCommandBuffer(GrRenderTarget* rt, const SkIRect& bounds, GrSu
|
||||
clearMask |= GR_GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
if (clearMask) {
|
||||
this->disableScissor();
|
||||
this->flushScissorTest(GrScissorTest::kDisabled);
|
||||
this->disableWindowRectangles();
|
||||
GL_CALL(Clear(clearMask));
|
||||
}
|
||||
@ -2374,38 +2360,17 @@ void GrGLGpu::flushViewport(int width, int height) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void GrGLGpu::drawMeshes(GrRenderTarget* renderTarget, const GrProgramInfo& programInfo,
|
||||
const GrMesh meshes[], int meshCount) {
|
||||
SkASSERT(meshCount); // guaranteed by GrOpsRenderPass::draw
|
||||
|
||||
bool hasDynamicScissors = programInfo.hasDynamicScissors();
|
||||
bool hasDynamicPrimProcTextures = programInfo.hasDynamicPrimProcTextures();
|
||||
|
||||
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();
|
||||
void GrGLGpu::drawMesh(GrRenderTarget* renderTarget, GrPrimitiveType primitiveType,
|
||||
const GrMesh& mesh) {
|
||||
if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
|
||||
GrIsPrimTypeLines(primitiveType) && !GrIsPrimTypeLines(fLastPrimitiveType)) {
|
||||
GL_CALL(Enable(GR_GL_CULL_FACE));
|
||||
GL_CALL(Disable(GR_GL_CULL_FACE));
|
||||
}
|
||||
|
||||
mesh.sendToGpu(primitiveType, this);
|
||||
fLastPrimitiveType = primitiveType;
|
||||
|
||||
#if SWAP_PER_DRAW
|
||||
glFlush();
|
||||
#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.
|
||||
this->disableScissor();
|
||||
this->flushScissorTest(GrScissorTest::kDisabled);
|
||||
this->disableWindowRectangles();
|
||||
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->flushConservativeRasterState(false);
|
||||
this->flushWireframeState(false);
|
||||
this->disableScissor();
|
||||
this->flushScissorTest(GrScissorTest::kDisabled);
|
||||
this->disableWindowRectangles();
|
||||
this->disableStencil();
|
||||
if (this->glCaps().srgbWriteControl()) {
|
||||
@ -3590,7 +3555,7 @@ bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const
|
||||
fHWBoundRenderTargetUniqueID.makeInvalid();
|
||||
|
||||
// BlitFrameBuffer respects the scissor, so disable it.
|
||||
this->disableScissor();
|
||||
this->flushScissorTest(GrScissorTest::kDisabled);
|
||||
this->disableWindowRectangles();
|
||||
|
||||
GL_CALL(BlitFramebuffer(srcRect.fLeft,
|
||||
@ -3672,7 +3637,7 @@ bool GrGLGpu::onRegenerateMipMapLevels(GrTexture* texture) {
|
||||
// Set "simple" state once:
|
||||
this->flushBlendAndColorWrite(GrXferProcessor::BlendInfo(), GrSwizzle::RGBA());
|
||||
this->flushHWAAState(nullptr, false);
|
||||
this->disableScissor();
|
||||
this->flushScissorTest(GrScissorTest::kDisabled);
|
||||
this->disableWindowRectangles();
|
||||
this->disableStencil();
|
||||
|
||||
|
@ -75,13 +75,18 @@ public:
|
||||
|
||||
// Flushes state from GrProgramInfo to GL. Returns false if the state couldn't be set.
|
||||
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.
|
||||
// Thus this is the implementation of the draw call for the corresponding passthrough function
|
||||
// on GrGLOpsRenderPass.
|
||||
//
|
||||
// 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.
|
||||
// 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
|
||||
// flushing the scissor after that function is called.
|
||||
void flushScissor(const GrScissorState&, int rtWidth, int rtHeight, GrSurfaceOrigin rtOrigin);
|
||||
|
||||
// disables the scissor
|
||||
void disableScissor();
|
||||
void flushScissor(const GrScissorState& scissorState, int rtWidth, int rtHeight,
|
||||
GrSurfaceOrigin rtOrigin) {
|
||||
this->flushScissorTest(GrScissorTest(scissorState.enabled()));
|
||||
if (scissorState.enabled()) {
|
||||
this->flushScissorRect(scissorState.rect(), rtWidth, rtHeight, rtOrigin);
|
||||
}
|
||||
}
|
||||
void flushScissorTest(GrScissorTest);
|
||||
|
||||
void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
|
||||
void disableWindowRectangles();
|
||||
|
@ -53,9 +53,18 @@ private:
|
||||
return fGpu->flushGLState(fRenderTarget, programInfo);
|
||||
}
|
||||
|
||||
void onDrawMeshes(const GrProgramInfo& programInfo, const GrMesh mesh[],
|
||||
int meshCount) override {
|
||||
fGpu->drawMeshes(fRenderTarget, programInfo, mesh, meshCount);
|
||||
void onSetScissorRect(const SkIRect& scissor) override {
|
||||
fGpu->flushScissorRect(scissor, fRenderTarget->width(), fRenderTarget->height(), fOrigin);
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -5,16 +5,14 @@
|
||||
* 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/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_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 GrStencilSettings& stencilPassSettings,
|
||||
const GrPath* path) {
|
||||
SkASSERT(!programInfo.hasDynamicScissors());
|
||||
SkASSERT(!programInfo.hasDynamicPrimProcTextures());
|
||||
if (!this->gpu()->flushGLState(renderTarget, programInfo)) {
|
||||
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);
|
||||
|
||||
|
@ -101,11 +101,10 @@ void GrGLProgram::updateUniforms(const GrRenderTarget* renderTarget,
|
||||
}
|
||||
|
||||
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) {
|
||||
SkASSERT(primProcTextureOverrides[i]->asTextureProxy());
|
||||
auto* overrideTexture = static_cast<GrGLTexture*>(
|
||||
primProcTextureOverrides[i]->peekTexture());
|
||||
SkASSERT(primProcTextures[i]->asTextureProxy());
|
||||
auto* overrideTexture = static_cast<GrGLTexture*>(primProcTextures[i]->peekTexture());
|
||||
fGpu->bindTexture(i, primProc.textureSampler(i).samplerState(),
|
||||
primProc.textureSampler(i).swizzle(), overrideTexture);
|
||||
}
|
||||
|
@ -120,12 +120,10 @@ public:
|
||||
void updateUniforms(const GrRenderTarget*, const GrProgramInfo&);
|
||||
|
||||
/**
|
||||
* Binds all primitive processor and fragment processor textures. We configure primitive
|
||||
* processor samplers based on the proxies on the processor itself, but the actual textures we
|
||||
* bind come from primProcTextureOverrides.
|
||||
* Binds all primitive processor and fragment processor textures.
|
||||
*/
|
||||
void bindTextures(const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrSurfaceProxy* const primProcTextureOverrides[]);
|
||||
const GrSurfaceProxy* const primProcTextures[]);
|
||||
|
||||
int vertexStride() const { return fVertexStride; }
|
||||
int instanceStride() const { return fInstanceStride; }
|
||||
|
@ -37,7 +37,12 @@ private:
|
||||
bool onBindPipeline(const GrProgramInfo&, const SkRect&) override {
|
||||
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();
|
||||
++fNumDraws;
|
||||
}
|
||||
@ -45,7 +50,6 @@ private:
|
||||
this->markRenderTargetDirty();
|
||||
}
|
||||
void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override {}
|
||||
|
||||
void markRenderTargetDirty() {
|
||||
if (auto* tex = fRenderTarget->asTexture()) {
|
||||
tex->texturePriv().markMipMapsDirty();
|
||||
|
@ -40,8 +40,10 @@ private:
|
||||
GrGpu* gpu() override { return fGpu; }
|
||||
|
||||
bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) override;
|
||||
|
||||
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;
|
||||
void onDrawMesh(GrPrimitiveType, const GrMesh&) override;
|
||||
|
||||
void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override;
|
||||
|
||||
|
@ -75,48 +75,39 @@ bool GrMtlOpsRenderPass::onBindPipeline(const GrProgramInfo& programInfo,
|
||||
[fActiveRenderCmdEncoder setTriangleFillMode:MTLTriangleFillModeFill];
|
||||
}
|
||||
|
||||
if (!programInfo.pipeline().isScissorEnabled()) {
|
||||
if (!programInfo.pipeline().isScissorTestEnabled()) {
|
||||
// "Disable" scissor by setting it to the full pipeline bounds.
|
||||
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder,
|
||||
fRenderTarget, fOrigin,
|
||||
SkIRect::MakeWH(fRenderTarget->width(),
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrMtlOpsRenderPass::onDrawMeshes(const GrProgramInfo& programInfo, const GrMesh meshes[],
|
||||
int meshCount) {
|
||||
void GrMtlOpsRenderPass::onSetScissorRect(const SkIRect& scissor) {
|
||||
SkASSERT(fActivePipelineState);
|
||||
SkASSERT(fActiveRenderCmdEncoder);
|
||||
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder, fRenderTarget,
|
||||
fOrigin, scissor);
|
||||
}
|
||||
|
||||
for (int i = 0; i < meshCount; ++i) {
|
||||
const GrMesh& mesh = meshes[i];
|
||||
SkASSERT(nil != fActiveRenderCmdEncoder);
|
||||
bool GrMtlOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrSurfaceProxy* const primProcTextures[]) {
|
||||
SkASSERT(fActivePipelineState);
|
||||
SkASSERT(fActiveRenderCmdEncoder);
|
||||
fActivePipelineState->setTextures(primProc, pipeline, primProcTextures);
|
||||
fActivePipelineState->bindTextures(fActiveRenderCmdEncoder);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (programInfo.hasDynamicScissors()) {
|
||||
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder, fRenderTarget,
|
||||
fOrigin,
|
||||
programInfo.dynamicScissor(i));
|
||||
}
|
||||
if (programInfo.hasDynamicPrimProcTextures()) {
|
||||
auto meshProxies = programInfo.dynamicPrimProcTextures(i);
|
||||
fActivePipelineState->setTextures(programInfo, meshProxies);
|
||||
fActivePipelineState->bindTextures(fActiveRenderCmdEncoder);
|
||||
}
|
||||
|
||||
mesh.sendToGpu(programInfo.primitiveType(), this);
|
||||
}
|
||||
void GrMtlOpsRenderPass::onDrawMesh(GrPrimitiveType primitiveType, const GrMesh& mesh) {
|
||||
SkASSERT(fActivePipelineState);
|
||||
SkASSERT(nil != fActiveRenderCmdEncoder);
|
||||
mesh.sendToGpu(primitiveType, this);
|
||||
}
|
||||
|
||||
void GrMtlOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
|
||||
|
@ -48,8 +48,7 @@ public:
|
||||
|
||||
void setData(const GrRenderTarget*, const GrProgramInfo&);
|
||||
|
||||
void setTextures(const GrProgramInfo& programInfo,
|
||||
const GrSurfaceProxy* const primProcTextures[]);
|
||||
void setTextures(const GrPrimitiveProcessor&, const GrPipeline&, const GrSurfaceProxy* const[]);
|
||||
void bindTextures(id<MTLRenderCommandEncoder> renderCmdEncoder);
|
||||
|
||||
void setDrawState(id<MTLRenderCommandEncoder>, const GrSwizzle& outputSwizzle,
|
||||
|
@ -76,11 +76,6 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
|
||||
offset);
|
||||
}
|
||||
|
||||
if (!programInfo.hasDynamicPrimProcTextures()) {
|
||||
auto proxies = programInfo.hasFixedPrimProcTextures() ? programInfo.fixedPrimProcTextures()
|
||||
: nullptr;
|
||||
this->setTextures(programInfo, proxies);
|
||||
}
|
||||
fDataManager.resetDirtyBits();
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
@ -93,17 +88,18 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
|
||||
fStencil = programInfo.nonGLStencilSettings();
|
||||
}
|
||||
|
||||
void GrMtlPipelineState::setTextures(const GrProgramInfo& programInfo,
|
||||
void GrMtlPipelineState::setTextures(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrSurfaceProxy* const primProcTextures[]) {
|
||||
fSamplerBindings.reset();
|
||||
for (int i = 0; i < programInfo.primProc().numTextureSamplers(); ++i) {
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
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());
|
||||
fSamplerBindings.emplace_back(sampler.samplerState(), texture, fGpu);
|
||||
}
|
||||
|
||||
GrFragmentProcessor::CIter fpIter(programInfo.pipeline());
|
||||
GrFragmentProcessor::CIter fpIter(pipeline);
|
||||
for (; fpIter; ++fpIter) {
|
||||
for (int i = 0; i < fpIter->numTextureSamplers(); ++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(
|
||||
GrSamplerState::Filter::kNearest, dstTextureProxy->peekTexture(), fGpu);
|
||||
}
|
||||
|
@ -557,28 +557,10 @@ bool GrVkOpsRenderPass::onBindPipeline(const GrProgramInfo& programInfo, const S
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check whether we need to bind textures between each GrMesh. If not we can bind them all now.
|
||||
if (!programInfo.hasDynamicPrimProcTextures()) {
|
||||
auto proxies = programInfo.hasFixedPrimProcTextures() ? programInfo.fixedPrimProcTextures()
|
||||
: nullptr;
|
||||
if (!fCurrentPipelineState->setAndBindTextures(
|
||||
fGpu, programInfo.primProc(), programInfo.pipeline(), proxies, currentCB)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!programInfo.pipeline().isScissorEnabled()) {
|
||||
if (!programInfo.pipeline().isScissorTestEnabled()) {
|
||||
// "Disable" scissor by setting it to the full pipeline bounds.
|
||||
GrVkPipeline::SetDynamicScissorRectState(fGpu, currentCB, fRenderTarget, fOrigin,
|
||||
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::SetDynamicBlendConstantState(fGpu, currentCB,
|
||||
@ -588,50 +570,36 @@ bool GrVkOpsRenderPass::onBindPipeline(const GrProgramInfo& programInfo, const S
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrVkOpsRenderPass::onDrawMeshes(const GrProgramInfo& programInfo, const GrMesh meshes[],
|
||||
int meshCount) {
|
||||
void GrVkOpsRenderPass::onSetScissorRect(const SkIRect& scissor) {
|
||||
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) {
|
||||
SkASSERT(fGpu->isDeviceLost());
|
||||
return;
|
||||
}
|
||||
|
||||
SkASSERT(fCurrentPipelineState);
|
||||
SkASSERT(meshCount); // guaranteed by GrOpsRenderPass::draw
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
mesh.sendToGpu(primitiveType, this);
|
||||
fCurrentCBIsEmpty = false;
|
||||
}
|
||||
|
||||
void GrVkOpsRenderPass::sendInstancedMeshToGpu(GrPrimitiveType, const GrMesh& mesh, int vertexCount,
|
||||
int baseVertex, int instanceCount,
|
||||
int baseInstance)
|
||||
{
|
||||
int baseInstance) {
|
||||
SkASSERT(!mesh.vertexBuffer() || !mesh.vertexBuffer()->isCpuBuffer());
|
||||
SkASSERT(!mesh.instanceBuffer() || !mesh.instanceBuffer()->isCpuBuffer());
|
||||
auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(mesh.vertexBuffer());
|
||||
|
@ -69,8 +69,10 @@ private:
|
||||
const GrGpuBuffer* instanceBuffer);
|
||||
|
||||
bool onBindPipeline(const GrProgramInfo&, const SkRect& drawBounds) override;
|
||||
|
||||
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;
|
||||
void onDrawMesh(GrPrimitiveType, const GrMesh&) override;
|
||||
|
||||
// GrMesh::SendToGpuImpl methods. These issue the actual Vulkan draw commands.
|
||||
// Marked final as a hint to the compiler to not use virtual dispatch.
|
||||
|
Loading…
Reference in New Issue
Block a user