Revert "Add ability to specify different GP textures for each mesh in a draw."
This reverts commit d1b8a166db
.
Reason for revert: breaks android apps, by drawing overlapping content out of painters order.
Original change's description:
> Add ability to specify different GP textures for each mesh in a draw.
>
> Uses GrPipeline::DynamicStateArrays to allow per-mesh GP textures when
> drawing an array of GrMeshes.
>
> Uses this along with op-chaining to make drawing multiple TextureOps
> with different textures faster.
>
> Change-Id: Iec4da1b72a13d0e0c94c8a8568fe4221c539dfcf
> Reviewed-on: https://skia-review.googlesource.com/145960
> Commit-Queue: Brian Salomon <bsalomon@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>
TBR=bsalomon@google.com,robertphillips@google.com,brianosman@google.com
# Not skipping CQ checks because original CL landed > 1 day ago.
Change-Id: I5c686b85adb378ba7faf34576efce74aebd348f7
Reviewed-on: https://skia-review.googlesource.com/147260
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
827513296e
commit
deeb655912
@ -61,7 +61,6 @@ GrCaps::GrCaps(const GrContextOptions& options) {
|
||||
fSampleShadingSupport = false;
|
||||
fFenceSyncSupport = false;
|
||||
fCrossContextTextureSupport = false;
|
||||
fDynamicStateArrayGeometryProcessorTextureSupport = false;
|
||||
|
||||
fBlendEquationSupport = kBasic_BlendEquationSupport;
|
||||
fAdvBlendEqBlacklist = 0;
|
||||
@ -173,8 +172,6 @@ void GrCaps::dumpJSON(SkJSONWriter* writer) const {
|
||||
writer->appendBool("Sample shading support", fSampleShadingSupport);
|
||||
writer->appendBool("Fence sync support", fFenceSyncSupport);
|
||||
writer->appendBool("Cross context texture support", fCrossContextTextureSupport);
|
||||
writer->appendBool("Specify GeometryProcessor textures as a dynamic state array",
|
||||
fDynamicStateArrayGeometryProcessorTextureSupport);
|
||||
|
||||
writer->appendBool("Blacklist Coverage Counting Path Renderer [workaround]",
|
||||
fBlacklistCoverageCounting);
|
||||
|
@ -234,16 +234,13 @@ public:
|
||||
|
||||
bool fenceSyncSupport() const { return fFenceSyncSupport; }
|
||||
bool crossContextTextureSupport() const { return fCrossContextTextureSupport; }
|
||||
|
||||
/**
|
||||
* Returns whether or not we will be able to do a copy given the passed in params
|
||||
*/
|
||||
virtual bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
|
||||
const SkIRect& srcRect, const SkIPoint& dstPoint) const = 0;
|
||||
|
||||
bool dynamicStateArrayGeometryProcessorTextureSupport() const {
|
||||
return fDynamicStateArrayGeometryProcessorTextureSupport;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is can be called before allocating a texture to be a dst for copySurface. This is only
|
||||
* used for doing dst copies needed in blends, thus the src is always a GrRenderTargetProxy. It
|
||||
@ -330,12 +327,9 @@ protected:
|
||||
// TODO: this may need to be an enum to support different fence types
|
||||
bool fFenceSyncSupport : 1;
|
||||
|
||||
// Requires fence sync support in GL.
|
||||
// Vulkan doesn't support this (yet) and some drivers have issues, too
|
||||
bool fCrossContextTextureSupport : 1;
|
||||
|
||||
// Not (yet) implemented in VK backend.
|
||||
bool fDynamicStateArrayGeometryProcessorTextureSupport : 1;
|
||||
|
||||
BlendEquationSupport fBlendEquationSupport;
|
||||
uint32_t fAdvBlendEqBlacklist;
|
||||
GR_STATIC_ASSERT(kLast_GrBlendEquation < 32);
|
||||
|
@ -47,20 +47,9 @@ bool GrGpuRTCommandBuffer::draw(const GrPrimitiveProcessor& primProc, const GrPi
|
||||
if (pipeline.isBad()) {
|
||||
return false;
|
||||
}
|
||||
if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
if (!fixedDynamicState->fPrimitiveProcessorTextures[i]->instantiate(resourceProvider)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
|
||||
int n = primProc.numTextureSamplers() * meshCount;
|
||||
const auto* textures = dynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (!textures[i]->instantiate(resourceProvider)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
if (!fixedDynamicState->fPrimitiveProcessorTextures[i]->instantiate(resourceProvider)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,28 +102,19 @@ GrDeferredUploadToken GrOpFlushState::addASAPUpload(GrDeferredTextureUploadFn&&
|
||||
|
||||
void GrOpFlushState::draw(sk_sp<const GrGeometryProcessor> gp, const GrPipeline* pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
const GrMesh meshes[], int meshCnt) {
|
||||
SkASSERT(fOpArgs);
|
||||
SkASSERT(fOpArgs->fOp);
|
||||
bool firstDraw = fDraws.begin() == fDraws.end();
|
||||
auto& draw = fDraws.append(&fArena);
|
||||
GrDeferredUploadToken token = fTokenTracker->issueDrawToken();
|
||||
if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
|
||||
for (int i = 0; i < gp->numTextureSamplers(); ++i) {
|
||||
fixedDynamicState->fPrimitiveProcessorTextures[i]->addPendingRead();
|
||||
}
|
||||
}
|
||||
if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
|
||||
int n = gp->numTextureSamplers() * meshCnt;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
dynamicStateArrays->fPrimitiveProcessorTextures[i]->addPendingRead();
|
||||
}
|
||||
for (int i = 0; i < gp->numTextureSamplers(); ++i) {
|
||||
fixedDynamicState->fPrimitiveProcessorTextures[i]->addPendingRead();
|
||||
}
|
||||
draw.fGeometryProcessor = std::move(gp);
|
||||
draw.fPipeline = pipeline;
|
||||
draw.fFixedDynamicState = fixedDynamicState;
|
||||
draw.fDynamicStateArrays = dynamicStateArrays;
|
||||
draw.fDynamicStateArrays = nullptr;
|
||||
draw.fMeshes = meshes;
|
||||
draw.fMeshCnt = meshCnt;
|
||||
draw.fOpID = fOpArgs->fOp->uniqueID();
|
||||
@ -174,20 +165,3 @@ GrGlyphCache* GrOpFlushState::glyphCache() const {
|
||||
GrAtlasManager* GrOpFlushState::atlasManager() const {
|
||||
return fGpu->getContext()->contextPriv().getAtlasManager();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrOpFlushState::Draw::~Draw() {
|
||||
if (fFixedDynamicState && fFixedDynamicState->fPrimitiveProcessorTextures) {
|
||||
for (int i = 0; i < fGeometryProcessor->numTextureSamplers(); ++i) {
|
||||
fFixedDynamicState->fPrimitiveProcessorTextures[i]->completedRead();
|
||||
}
|
||||
}
|
||||
if (fDynamicStateArrays && fDynamicStateArrays->fPrimitiveProcessorTextures) {
|
||||
int n = fGeometryProcessor->numTextureSamplers() * fMeshCnt;
|
||||
const auto* textures = fDynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
textures[i]->completedRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,9 +76,8 @@ public:
|
||||
void draw(sk_sp<const GrGeometryProcessor>,
|
||||
const GrPipeline*,
|
||||
const GrPipeline::FixedDynamicState*,
|
||||
const GrPipeline::DynamicStateArrays*,
|
||||
const GrMesh[],
|
||||
int meshCnt) final;
|
||||
int meshCount) final;
|
||||
void* makeVertexSpace(size_t vertexSize, int vertexCount, const GrBuffer**,
|
||||
int* startVertex) final;
|
||||
uint16_t* makeIndexSpace(int indexCount, const GrBuffer**, int* startIndex) final;
|
||||
@ -121,7 +120,11 @@ private:
|
||||
// that share a geometry processor into a Draw is that it allows the Gpu object to setup
|
||||
// the shared state once and then issue draws for each mesh.
|
||||
struct Draw {
|
||||
~Draw();
|
||||
~Draw() {
|
||||
for (int i = 0; i < fGeometryProcessor->numTextureSamplers(); ++i) {
|
||||
fFixedDynamicState->fPrimitiveProcessorTextures[i]->completedRead();
|
||||
}
|
||||
}
|
||||
sk_sp<const GrGeometryProcessor> fGeometryProcessor;
|
||||
const GrPipeline* fPipeline = nullptr;
|
||||
const GrPipeline::FixedDynamicState* fFixedDynamicState;
|
||||
|
@ -73,8 +73,7 @@ public:
|
||||
explicit FixedDynamicState(const SkIRect& scissorRect) : fScissorRect(scissorRect) {}
|
||||
FixedDynamicState() = default;
|
||||
SkIRect fScissorRect = SkIRect::EmptyIRect();
|
||||
// Must have GrPrimitiveProcessor::numTextureSamplers() entries. Can be null if no samplers
|
||||
// or textures are passed using DynamicStateArrays.
|
||||
// Must have GrPrimitiveProcessor::numTextureSamplers() entries. Can be null if no samplers.
|
||||
GrTextureProxy** fPrimitiveProcessorTextures = nullptr;
|
||||
};
|
||||
|
||||
@ -84,10 +83,6 @@ public:
|
||||
*/
|
||||
struct DynamicStateArrays {
|
||||
const SkIRect* fScissorRects = nullptr;
|
||||
// Must have GrPrimitiveProcessor::numTextureSamplers() * num_meshes entries.
|
||||
// Can be null if no samplers or to use the same textures for all meshes via'
|
||||
// FixedDynamicState.
|
||||
GrTextureProxy** fPrimitiveProcessorTextures = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -179,7 +179,7 @@ private:
|
||||
int fLastClipNumAnalyticFPs;
|
||||
|
||||
// For ops/opList we have mean: 5 stdDev: 28
|
||||
SkSTArray<25, RecordedOp, true> fRecordedOps;
|
||||
SkSTArray<5, RecordedOp, true> fRecordedOps;
|
||||
|
||||
// MDB TODO: 4096 for the first allocation of the clip space will be huge overkill.
|
||||
// Gather statistics to determine the correct size.
|
||||
|
@ -571,8 +571,6 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
||||
// Safely moving textures between contexts requires fences.
|
||||
fCrossContextTextureSupport = fFenceSyncSupport;
|
||||
|
||||
fDynamicStateArrayGeometryProcessorTextureSupport = true;
|
||||
|
||||
if (kGL_GrGLStandard == standard) {
|
||||
if (version >= GR_GL_VER(4, 1)) {
|
||||
fProgramBinarySupport = true;
|
||||
|
@ -1674,11 +1674,9 @@ void GrGLGpu::flushMinSampleShading(float minSampleShading) {
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLGpu::resolveAndGenerateMipMapsForProcessorTextures(
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrTextureProxy* const primProcTextures[],
|
||||
int numPrimitiveProcessorTextureSets) {
|
||||
void GrGLGpu::generateMipmapsForProcessorTextures(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrTextureProxy* const primProcTextures[]) {
|
||||
auto genLevelsIfNeeded = [this](GrTexture* tex, const GrSamplerState& sampler) {
|
||||
SkASSERT(tex);
|
||||
if (sampler.filter() == GrSamplerState::Filter::kMipMap &&
|
||||
@ -1686,19 +1684,12 @@ void GrGLGpu::resolveAndGenerateMipMapsForProcessorTextures(
|
||||
tex->texturePriv().mipMapsAreDirty()) {
|
||||
SkASSERT(this->caps()->mipMapSupport());
|
||||
this->regenerateMipMapLevels(static_cast<GrGLTexture*>(tex));
|
||||
SkASSERT(!tex->asRenderTarget() || !tex->asRenderTarget()->needsResolve());
|
||||
} else if (auto* rt = tex->asRenderTarget()) {
|
||||
if (rt->needsResolve()) {
|
||||
this->resolveRenderTarget(rt);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (int set = 0, tex = 0; set < numPrimitiveProcessorTextureSets; ++set) {
|
||||
for (int sampler = 0; sampler < primProc.numTextureSamplers(); ++sampler, ++tex) {
|
||||
GrTexture* texture = primProcTextures[tex]->peekTexture();
|
||||
genLevelsIfNeeded(texture, primProc.textureSampler(sampler).samplerState());
|
||||
}
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
GrTexture* tex = primProcTextures[i]->peekTexture();
|
||||
genLevelsIfNeeded(tex, primProc.textureSampler(i).samplerState());
|
||||
}
|
||||
|
||||
GrFragmentProcessor::Iter iter(pipeline);
|
||||
@ -1713,26 +1704,17 @@ void GrGLGpu::resolveAndGenerateMipMapsForProcessorTextures(
|
||||
bool GrGLGpu::flushGLState(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
int dynamicStateArraysLength,
|
||||
bool willDrawPoints) {
|
||||
sk_sp<GrGLProgram> program(fProgramCache->refProgram(this, primProc, pipeline, willDrawPoints));
|
||||
if (!program) {
|
||||
GrCapsDebugf(this->caps(), "Failed to create program!\n");
|
||||
return false;
|
||||
}
|
||||
const GrTextureProxy* const* primProcProxiesForMipRegen = nullptr;
|
||||
const GrTextureProxy* const* primProcProxiesToBind = nullptr;
|
||||
int numPrimProcTextureSets = 1; // number of texture per prim proc sampler.
|
||||
if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
|
||||
primProcProxiesForMipRegen = dynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
numPrimProcTextureSets = dynamicStateArraysLength;
|
||||
} else if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
|
||||
primProcProxiesForMipRegen = fixedDynamicState->fPrimitiveProcessorTextures;
|
||||
primProcProxiesToBind = fixedDynamicState->fPrimitiveProcessorTextures;
|
||||
const GrTextureProxy* const* primProcProxies = nullptr;
|
||||
if (fixedDynamicState) {
|
||||
primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
|
||||
}
|
||||
this->resolveAndGenerateMipMapsForProcessorTextures(
|
||||
primProc, pipeline, primProcProxiesForMipRegen, numPrimProcTextureSets);
|
||||
this->generateMipmapsForProcessorTextures(primProc, pipeline, primProcProxies);
|
||||
|
||||
GrXferProcessor::BlendInfo blendInfo;
|
||||
pipeline.getXferProcessor().getBlendInfo(&blendInfo);
|
||||
@ -1749,7 +1731,7 @@ bool GrGLGpu::flushGLState(const GrPrimitiveProcessor& primProc,
|
||||
this->flushBlend(blendInfo, swizzle);
|
||||
}
|
||||
|
||||
fHWProgram->updateUniformsAndTextureBindings(primProc, pipeline, primProcProxiesToBind);
|
||||
fHWProgram->updateUniformsAndTextureBindings(primProc, pipeline, primProcProxies);
|
||||
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.renderTarget());
|
||||
GrStencilSettings stencil;
|
||||
@ -2272,40 +2254,30 @@ void GrGLGpu::draw(const GrPrimitiveProcessor& primProc,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!this->flushGLState(primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshCount,
|
||||
hasPoints)) {
|
||||
if (!this->flushGLState(primProc, pipeline, fixedDynamicState, hasPoints)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool dynamicScissor = false;
|
||||
bool dynamicPrimProcTextures = false;
|
||||
if (dynamicStateArrays) {
|
||||
dynamicScissor = pipeline.isScissorEnabled() && dynamicStateArrays->fScissorRects;
|
||||
dynamicPrimProcTextures = dynamicStateArrays->fPrimitiveProcessorTextures;
|
||||
}
|
||||
for (int m = 0; m < meshCount; ++m) {
|
||||
bool dynamicScissor =
|
||||
pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
|
||||
for (int i = 0; i < meshCount; ++i) {
|
||||
if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) {
|
||||
this->xferBarrier(pipeline.renderTarget(), barrierType);
|
||||
}
|
||||
|
||||
if (dynamicScissor) {
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.renderTarget());
|
||||
this->flushScissor(GrScissorState(dynamicStateArrays->fScissorRects[m]),
|
||||
this->flushScissor(GrScissorState(dynamicStateArrays->fScissorRects[i]),
|
||||
glRT->getViewport(), pipeline.proxy()->origin());
|
||||
}
|
||||
if (dynamicPrimProcTextures) {
|
||||
auto texProxyArray = dynamicStateArrays->fPrimitiveProcessorTextures +
|
||||
m * primProc.numTextureSamplers();
|
||||
fHWProgram->updatePrimitiveProcessorTextureBindings(primProc, texProxyArray);
|
||||
}
|
||||
if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
|
||||
GrIsPrimTypeLines(meshes[m].primitiveType()) &&
|
||||
GrIsPrimTypeLines(meshes[i].primitiveType()) &&
|
||||
!GrIsPrimTypeLines(fLastPrimitiveType)) {
|
||||
GL_CALL(Enable(GR_GL_CULL_FACE));
|
||||
GL_CALL(Disable(GR_GL_CULL_FACE));
|
||||
}
|
||||
meshes[m].sendToGpu(this);
|
||||
fLastPrimitiveType = meshes[m].primitiveType();
|
||||
meshes[i].sendToGpu(this);
|
||||
fLastPrimitiveType = meshes[i].primitiveType();
|
||||
}
|
||||
|
||||
#if SWAP_PER_DRAW
|
||||
|
@ -250,22 +250,14 @@ private:
|
||||
|
||||
void setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]);
|
||||
|
||||
/**
|
||||
* primitiveProcessorTextures must contain GrPrimitiveProcessor::numTextureSamplers() *
|
||||
* numPrimitiveProcessorTextureSets entries.
|
||||
*/
|
||||
void resolveAndGenerateMipMapsForProcessorTextures(
|
||||
void generateMipmapsForProcessorTextures(
|
||||
const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrTextureProxy* const primitiveProcessorTextures[],
|
||||
int numPrimitiveProcessorTextureSets);
|
||||
const GrTextureProxy* const primitiveProcessorTextures[]);
|
||||
|
||||
// Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
|
||||
// willDrawPoints must be true if point primitives will be rendered after setting the GL state.
|
||||
// If DynamicStateArrays is not null then dynamicStateArraysLength is the number of dynamic
|
||||
// state entries in each array.
|
||||
bool flushGLState(const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrPipeline::FixedDynamicState*, const GrPipeline::DynamicStateArrays*,
|
||||
int dynamicStateArraysLength, bool willDrawPoints);
|
||||
const GrPipeline::FixedDynamicState*, bool willDrawPoints);
|
||||
|
||||
void flushProgram(sk_sp<GrGLProgram>);
|
||||
|
||||
|
@ -116,7 +116,7 @@ void GrGLPathRendering::onDrawPath(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline::FixedDynamicState& fixedDynamicState,
|
||||
const GrStencilSettings& stencilPassSettings,
|
||||
const GrPath* path) {
|
||||
if (!this->gpu()->flushGLState(primProc, pipeline, &fixedDynamicState, nullptr, 1, false)) {
|
||||
if (!this->gpu()->flushGLState(primProc, pipeline, &fixedDynamicState, false)) {
|
||||
return;
|
||||
}
|
||||
const GrGLPath* glPath = static_cast<const GrGLPath*>(path);
|
||||
|
@ -75,6 +75,7 @@ void GrGLProgram::abandon() {
|
||||
void GrGLProgram::updateUniformsAndTextureBindings(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrTextureProxy* const primProcTextures[]) {
|
||||
SkASSERT(primProcTextures || !primProc.numTextureSamplers());
|
||||
this->setRenderTargetState(primProc, pipeline.proxy());
|
||||
|
||||
// we set the textures, and uniforms for installed processors in a generic way, but subclasses
|
||||
@ -83,12 +84,13 @@ void GrGLProgram::updateUniformsAndTextureBindings(const GrPrimitiveProcessor& p
|
||||
// We must bind to texture units in the same order in which we set the uniforms in
|
||||
// GrGLProgramDataManager. That is, we bind textures for processors in this order:
|
||||
// primProc, fragProcs, XP.
|
||||
int nextTexSamplerIdx = 0;
|
||||
fPrimitiveProcessor->setData(fProgramDataManager, primProc,
|
||||
GrFragmentProcessor::CoordTransformIter(pipeline));
|
||||
if (primProcTextures) {
|
||||
this->updatePrimitiveProcessorTextureBindings(primProc, primProcTextures);
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
auto* tex = static_cast<GrGLTexture*>(primProcTextures[i]->peekTexture());
|
||||
fGpu->bindTexture(nextTexSamplerIdx++, primProc.textureSampler(i).samplerState(), tex);
|
||||
}
|
||||
int nextTexSamplerIdx = primProc.numTextureSamplers();
|
||||
|
||||
this->setFragmentData(pipeline, &nextTexSamplerIdx);
|
||||
|
||||
@ -104,14 +106,6 @@ void GrGLProgram::updateUniformsAndTextureBindings(const GrPrimitiveProcessor& p
|
||||
SkASSERT(nextTexSamplerIdx == fNumTextureSamplers);
|
||||
}
|
||||
|
||||
void GrGLProgram::updatePrimitiveProcessorTextureBindings(const GrPrimitiveProcessor& primProc,
|
||||
const GrTextureProxy* const proxies[]) {
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
auto* tex = static_cast<GrGLTexture*>(proxies[i]->peekTexture());
|
||||
fGpu->bindTexture(i, primProc.textureSampler(i).samplerState(), tex);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLProgram::setFragmentData(const GrPipeline& pipeline, int* nextTexSamplerIdx) {
|
||||
GrFragmentProcessor::Iter iter(pipeline);
|
||||
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
|
||||
|
@ -112,17 +112,13 @@ public:
|
||||
|
||||
/**
|
||||
* This function uploads uniforms, calls each GrGLSL*Processor's setData. It binds all fragment
|
||||
* processor textures. Primitive process textures can be bound using this function or by
|
||||
* calling updatePrimitiveProcessorTextureBindings.
|
||||
* processor textures. Primitive process textures are also bound here but are passed separately.
|
||||
*
|
||||
* It is the caller's responsibility to ensure the program is bound before calling.
|
||||
*/
|
||||
void updateUniformsAndTextureBindings(const GrPrimitiveProcessor&, const GrPipeline&,
|
||||
const GrTextureProxy* const primitiveProcessorTextures[]);
|
||||
|
||||
void updatePrimitiveProcessorTextureBindings(const GrPrimitiveProcessor&,
|
||||
const GrTextureProxy* const[]);
|
||||
|
||||
int vertexStride() const { return fVertexStride; }
|
||||
int instanceStride() const { return fInstanceStride; }
|
||||
|
||||
|
@ -938,7 +938,7 @@ private:
|
||||
firstIndex += draw.fIndexCnt;
|
||||
firstVertex += draw.fVertexCnt;
|
||||
}
|
||||
target->draw(quadProcessor, pipe.fPipeline, pipe.fFixedDynamicState, nullptr, meshes,
|
||||
target->draw(quadProcessor, pipe.fPipeline, pipe.fFixedDynamicState, meshes,
|
||||
draws.count());
|
||||
}
|
||||
}
|
||||
|
@ -73,29 +73,6 @@ GrMeshDrawOp::QuadHelper::QuadHelper(Target* target, size_t vertexStride, int qu
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrPipeline::FixedDynamicState* GrMeshDrawOp::Target::allocFixedDynamicState(
|
||||
const SkIRect& rect, int numPrimitiveProcessorTextures) {
|
||||
auto result = this->pipelineArena()->make<GrPipeline::FixedDynamicState>(rect);
|
||||
if (numPrimitiveProcessorTextures) {
|
||||
result->fPrimitiveProcessorTextures =
|
||||
this->allocPrimitiveProcessorTextureArray(numPrimitiveProcessorTextures);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
GrPipeline::DynamicStateArrays* GrMeshDrawOp::Target::allocDynamicStateArrays(
|
||||
int numMeshes, int numPrimitiveProcessorTextures, bool allocScissors) {
|
||||
auto result = this->pipelineArena()->make<GrPipeline::DynamicStateArrays>();
|
||||
if (allocScissors) {
|
||||
result->fScissorRects = this->pipelineArena()->makeArray<SkIRect>(numMeshes);
|
||||
}
|
||||
if (numPrimitiveProcessorTextures) {
|
||||
result->fPrimitiveProcessorTextures = this->allocPrimitiveProcessorTextureArray(
|
||||
numPrimitiveProcessorTextures * numMeshes);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
GrMeshDrawOp::Target::PipelineAndFixedDynamicState GrMeshDrawOp::Target::makePipeline(
|
||||
uint32_t pipelineFlags, GrProcessorSet&& processorSet, GrAppliedClip&& clip,
|
||||
int numPrimProcTextures) {
|
||||
|
@ -83,15 +83,15 @@ public:
|
||||
virtual void draw(sk_sp<const GrGeometryProcessor>,
|
||||
const GrPipeline*,
|
||||
const GrPipeline::FixedDynamicState*,
|
||||
const GrPipeline::DynamicStateArrays*,
|
||||
const GrMesh[],
|
||||
int meshCount) = 0;
|
||||
|
||||
/** Helper for drawing a single GrMesh. */
|
||||
void draw(sk_sp<const GrGeometryProcessor> gp,
|
||||
const GrPipeline* pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrMesh* mesh) {
|
||||
this->draw(std::move(gp), pipeline, fixedDynamicState, nullptr, mesh, 1);
|
||||
this->draw(std::move(gp), pipeline, fixedDynamicState, mesh, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,11 +152,14 @@ public:
|
||||
GrMesh* allocMeshes(int n) { return this->pipelineArena()->makeArray<GrMesh>(n); }
|
||||
|
||||
GrPipeline::FixedDynamicState* allocFixedDynamicState(const SkIRect& rect,
|
||||
int numPrimitiveProcessorTextures = 0);
|
||||
|
||||
GrPipeline::DynamicStateArrays* allocDynamicStateArrays(int numMeshes,
|
||||
int numPrimitiveProcessorTextures,
|
||||
bool allocScissors);
|
||||
int numPrimitiveProcessorTextures = 0) {
|
||||
auto result = this->pipelineArena()->make<GrPipeline::FixedDynamicState>(rect);
|
||||
if (numPrimitiveProcessorTextures) {
|
||||
result->fPrimitiveProcessorTextures =
|
||||
this->allocPrimitiveProcessorTextureArray(numPrimitiveProcessorTextures);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
GrTextureProxy** allocPrimitiveProcessorTextureArray(int n) {
|
||||
SkASSERT(n > 0);
|
||||
|
@ -611,7 +611,7 @@ private:
|
||||
}
|
||||
|
||||
template <typename Pos, Domain D, GrAA AA>
|
||||
void tess(void* v, const GrGeometryProcessor* gp) const {
|
||||
void tess(void* v, const GrGeometryProcessor* gp) {
|
||||
using Vertex = TextureGeometryProcessor::Vertex<Pos, D, AA>;
|
||||
SkASSERT(gp->debugOnly_vertexStride() == sizeof(Vertex));
|
||||
auto vertices = static_cast<Vertex*>(v);
|
||||
@ -628,25 +628,16 @@ private:
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target* target) override {
|
||||
bool hasPerspective = false;
|
||||
Domain domain = Domain::kNo;
|
||||
int numOps = 0;
|
||||
for (const auto& op : ChainRange<TextureOp>(this)) {
|
||||
++numOps;
|
||||
hasPerspective |= op.fPerspective;
|
||||
if (op.fDomain) {
|
||||
domain = Domain::kYes;
|
||||
}
|
||||
if (!op.fProxy->instantiate(target->resourceProvider())) {
|
||||
return;
|
||||
}
|
||||
if (!fProxy->instantiate(target->resourceProvider())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Domain domain = fDomain ? Domain::kYes : Domain::kNo;
|
||||
bool coverageAA = GrAAType::kCoverage == this->aaType();
|
||||
sk_sp<GrGeometryProcessor> gp = TextureGeometryProcessor::Make(
|
||||
fProxy->textureType(), fProxy->config(), fFilter,
|
||||
std::move(fTextureColorSpaceXform), std::move(fPaintColorSpaceXform), coverageAA,
|
||||
hasPerspective, domain, *target->caps().shaderCaps());
|
||||
fPerspective, domain, *target->caps().shaderCaps());
|
||||
GrPipeline::InitArgs args;
|
||||
args.fProxy = target->proxy();
|
||||
args.fCaps = &target->caps();
|
||||
@ -657,17 +648,8 @@ private:
|
||||
}
|
||||
|
||||
auto clip = target->detachAppliedClip();
|
||||
// We'll use a dynamic state array for the GP textures when there are multiple ops.
|
||||
// Otherwise, we use fixed dynamic state to specify the single op's proxy.
|
||||
GrPipeline::DynamicStateArrays* dynamicStateArrays = nullptr;
|
||||
GrPipeline::FixedDynamicState* fixedDynamicState;
|
||||
if (numOps > 1) {
|
||||
dynamicStateArrays = target->allocDynamicStateArrays(numOps, 1, false);
|
||||
fixedDynamicState = target->allocFixedDynamicState(clip.scissorState().rect(), 0);
|
||||
} else {
|
||||
fixedDynamicState = target->allocFixedDynamicState(clip.scissorState().rect(), 1);
|
||||
fixedDynamicState->fPrimitiveProcessorTextures[0] = fProxy;
|
||||
}
|
||||
auto* fixedDynamicState = target->allocFixedDynamicState(clip.scissorState().rect(), 1);
|
||||
fixedDynamicState->fPrimitiveProcessorTextures[0] = fProxy;
|
||||
const auto* pipeline =
|
||||
target->allocPipeline(args, GrProcessorSet::MakeEmptySet(), std::move(clip));
|
||||
using TessFn = decltype(&TextureOp::tess<SkPoint, Domain::kNo, GrAA::kNo>);
|
||||
@ -691,50 +673,42 @@ private:
|
||||
};
|
||||
#undef TESS_FN_AND_VERTEX_SIZE
|
||||
int tessFnIdx = 0;
|
||||
tessFnIdx |= coverageAA ? 0x1 : 0x0;
|
||||
tessFnIdx |= (domain == Domain::kYes) ? 0x2 : 0x0;
|
||||
tessFnIdx |= hasPerspective ? 0x4 : 0x0;
|
||||
tessFnIdx |= coverageAA ? 0x1 : 0x0;
|
||||
tessFnIdx |= fDomain ? 0x2 : 0x0;
|
||||
tessFnIdx |= fPerspective ? 0x4 : 0x0;
|
||||
|
||||
SkASSERT(kTessFnsAndVertexSizes[tessFnIdx].fVertexSize == gp->debugOnly_vertexStride());
|
||||
|
||||
GrMesh* meshes = target->allocMeshes(numOps);
|
||||
int i = 0;
|
||||
for (const auto& op : ChainRange<TextureOp>(this)) {
|
||||
int vstart;
|
||||
const GrBuffer* vbuffer;
|
||||
void* vdata = target->makeVertexSpace(kTessFnsAndVertexSizes[tessFnIdx].fVertexSize,
|
||||
4 * op.fDraws.count(), &vbuffer, &vstart);
|
||||
if (!vdata) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
int vstart;
|
||||
const GrBuffer* vbuffer;
|
||||
void* vdata = target->makeVertexSpace(kTessFnsAndVertexSizes[tessFnIdx].fVertexSize,
|
||||
4 * fDraws.count(), &vbuffer, &vstart);
|
||||
if (!vdata) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
}
|
||||
|
||||
(this->*(kTessFnsAndVertexSizes[tessFnIdx].fTessFn))(vdata, gp.get());
|
||||
|
||||
GrPrimitiveType primitiveType =
|
||||
fDraws.count() > 1 ? GrPrimitiveType::kTriangles : GrPrimitiveType::kTriangleStrip;
|
||||
GrMesh* mesh = target->allocMesh(primitiveType);
|
||||
if (fDraws.count() > 1) {
|
||||
sk_sp<const GrBuffer> ibuffer = target->resourceProvider()->refQuadIndexBuffer();
|
||||
if (!ibuffer) {
|
||||
SkDebugf("Could not allocate quad indices\n");
|
||||
return;
|
||||
}
|
||||
|
||||
(op.*(kTessFnsAndVertexSizes[tessFnIdx].fTessFn))(vdata, gp.get());
|
||||
|
||||
if (op.fDraws.count() > 1) {
|
||||
meshes[i].setPrimitiveType(GrPrimitiveType::kTriangles);
|
||||
sk_sp<const GrBuffer> ibuffer = target->resourceProvider()->refQuadIndexBuffer();
|
||||
if (!ibuffer) {
|
||||
SkDebugf("Could not allocate quad indices\n");
|
||||
return;
|
||||
}
|
||||
meshes[i].setIndexedPatterned(ibuffer.get(), 6, 4, op.fDraws.count(),
|
||||
GrResourceProvider::QuadCountOfQuadBuffer());
|
||||
} else {
|
||||
meshes[i].setPrimitiveType(GrPrimitiveType::kTriangleStrip);
|
||||
meshes[i].setNonIndexedNonInstanced(4);
|
||||
}
|
||||
meshes[i].setVertexData(vbuffer, vstart);
|
||||
if (dynamicStateArrays) {
|
||||
dynamicStateArrays->fPrimitiveProcessorTextures[i] = op.fProxy;
|
||||
}
|
||||
++i;
|
||||
mesh->setIndexedPatterned(ibuffer.get(), 6, 4, fDraws.count(),
|
||||
GrResourceProvider::QuadCountOfQuadBuffer());
|
||||
} else {
|
||||
mesh->setNonIndexedNonInstanced(4);
|
||||
}
|
||||
target->draw(std::move(gp), pipeline, fixedDynamicState, dynamicStateArrays, meshes,
|
||||
numOps);
|
||||
mesh->setVertexData(vbuffer, vstart);
|
||||
target->draw(std::move(gp), pipeline, fixedDynamicState, mesh);
|
||||
}
|
||||
|
||||
CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
|
||||
CombineResult onCombineIfPossible(GrOp* t, const GrCaps&) override {
|
||||
const auto* that = t->cast<TextureOp>();
|
||||
if (!GrColorSpaceXform::Equals(fTextureColorSpaceXform.get(),
|
||||
that->fTextureColorSpaceXform.get())) {
|
||||
@ -747,17 +721,7 @@ private:
|
||||
if (this->aaType() != that->aaType()) {
|
||||
return CombineResult::kCannotCombine;
|
||||
}
|
||||
if (fFilter != that->fFilter) {
|
||||
return CombineResult::kCannotCombine;
|
||||
}
|
||||
if (fProxy->uniqueID() != that->fProxy->uniqueID() || that->isChained()) {
|
||||
// We can't merge across different proxies (and we're disallowed from merging when
|
||||
// 'that' is chained. Check if we can be chained with 'that'.
|
||||
if (fProxy->config() == that->fProxy->config() &&
|
||||
fProxy->textureType() == that->fProxy->textureType() &&
|
||||
caps.dynamicStateArrayGeometryProcessorTextureSupport()) {
|
||||
return CombineResult::kMayChain;
|
||||
}
|
||||
if (fProxy->uniqueID() != that->fProxy->uniqueID() || fFilter != that->fFilter) {
|
||||
return CombineResult::kCannotCombine;
|
||||
}
|
||||
fDraws.push_back_n(that->fDraws.count(), that->fDraws.begin());
|
||||
|
@ -181,12 +181,10 @@ void GrVkPipelineState::setData(GrVkGpu* gpu,
|
||||
|
||||
fGeometryProcessor->setData(fDataManager, primProc,
|
||||
GrFragmentProcessor::CoordTransformIter(pipeline));
|
||||
if (primProcTextures) {
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
const auto& sampler = primProc.textureSampler(i);
|
||||
auto texture = static_cast<GrVkTexture*>(primProcTextures[i]->peekTexture());
|
||||
samplerBindings[currTextureBinding++] = {sampler.samplerState(), texture};
|
||||
}
|
||||
for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
|
||||
const auto& sampler = primProc.textureSampler(i);
|
||||
auto texture = static_cast<GrVkTexture*>(primProcTextures[i]->peekTexture());
|
||||
samplerBindings[currTextureBinding++] = {sampler.samplerState(), texture};
|
||||
}
|
||||
|
||||
GrFragmentProcessor::Iter iter(pipeline);
|
||||
|
Loading…
Reference in New Issue
Block a user