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.");
|
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.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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()) {
|
||||||
|
@ -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());
|
||||||
|
@ -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());
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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; }
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user