Add helper to determine the index buffer that will be used

This CL doesn't use the new VertexSpec member variable but should clarify the path forward (i.e., we will determine the index buffer option at characterize time and enforce that decision at onPrepare time for all the meshes).

This also refactors the GrTextureOp::characterize call.

Change-Id: I7010385abf5a462c12fd47e314aad893bca85fb9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/251002
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Robert Phillips 2019-10-28 11:43:55 -04:00 committed by Skia Commit-Bot
parent 659b21d480
commit c554dcf4b5
5 changed files with 58 additions and 15 deletions

View File

@ -409,7 +409,7 @@ private:
static const GrQuadPerEdgeAA::VertexSpec kSpec =
{GrQuad::Type::kGeneral, GrQuadPerEdgeAA::ColorType::kNone,
GrQuad::Type::kAxisAligned, false, GrQuadPerEdgeAA::Domain::kNo,
GrAAType::kCoverage, false};
GrAAType::kCoverage, false, GrQuadPerEdgeAA::IndexBufferOption::kPictureFramed};
static const GrQuad kIgnored(SkRect::MakeEmpty());
GrQuadAAFlags flags = GrQuadAAFlags::kNone;

View File

@ -192,9 +192,12 @@ private:
using Domain = GrQuadPerEdgeAA::Domain;
static constexpr SkRect kEmptyDomain = SkRect::MakeEmpty();
auto indexBufferOption = GrQuadPerEdgeAA::CalcIndexBufferOption(fHelper.aaType(),
fQuads.count());
VertexSpec vertexSpec(fQuads.deviceQuadType(), fColorType, fQuads.localQuadType(),
fHelper.usesLocalCoords(), Domain::kNo, fHelper.aaType(),
fHelper.compatibleWithCoverageAsAlpha());
fHelper.compatibleWithCoverageAsAlpha(), indexBufferOption);
// Make sure that if the op thought it was a solid color, the vertex spec does not use
// local coords.
SkASSERT(!fHelper.isTrivial() || !fHelper.usesLocalCoords());

View File

@ -526,7 +526,7 @@ static sk_sp<const GrGpuBuffer> get_index_buffer(GrResourceProvider* resourcePro
GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
// clang-format off
static const uint16_t gFillAARectIdx[] = {
static const uint16_t gFillAARectIdx[kIndicesPerAAFillRect] = {
0, 1, 2, 1, 3, 2,
0, 4, 1, 4, 5, 1,
0, 6, 4, 0, 2, 6,
@ -545,6 +545,16 @@ static sk_sp<const GrGpuBuffer> get_index_buffer(GrResourceProvider* resourcePro
namespace GrQuadPerEdgeAA {
IndexBufferOption CalcIndexBufferOption(GrAAType aa, int numQuads) {
if (aa == GrAAType::kCoverage) {
return IndexBufferOption::kPictureFramed;
} else if (numQuads > 1) {
return IndexBufferOption::kIndexedRects;
} else {
return IndexBufferOption::kTriStrips;
}
}
// This is a more elaborate version of SkPMColor4fNeedsWideColor that allows "no color" for white
ColorType MinColorType(SkPMColor4f color, GrClampType clampType, const GrCaps& caps) {
if (color == SK_PMColor4fWHITE) {
@ -625,6 +635,8 @@ void* Tessellate(void* vertices, const VertexSpec& spec, const GrQuad& deviceQua
bool ConfigureMeshIndices(GrMeshDrawOp::Target* target, GrMesh* mesh, const VertexSpec& spec,
int quadCount) {
if (spec.usesCoverageAA()) {
SkASSERT(spec.indexBufferOption() == IndexBufferOption::kPictureFramed);
// AA quads use 8 vertices, basically nested rectangles
sk_sp<const GrGpuBuffer> ibuffer = get_index_buffer(target->resourceProvider());
if (!ibuffer) {
@ -637,6 +649,8 @@ bool ConfigureMeshIndices(GrMeshDrawOp::Target* target, GrMesh* mesh, const Vert
} else {
// Non-AA quads use 4 vertices, and regular triangle strip layout
if (quadCount > 1) {
SkASSERT(spec.indexBufferOption() == IndexBufferOption::kIndexedRects);
sk_sp<const GrGpuBuffer> ibuffer = target->resourceProvider()->refQuadIndexBuffer();
if (!ibuffer) {
return false;
@ -646,6 +660,8 @@ bool ConfigureMeshIndices(GrMeshDrawOp::Target* target, GrMesh* mesh, const Vert
mesh->setIndexedPatterned(std::move(ibuffer), 6, 4, quadCount,
GrResourceProvider::QuadCountOfQuadBuffer());
} else {
SkASSERT(spec.indexBufferOption() != IndexBufferOption::kPictureFramed);
mesh->setPrimitiveType(GrPrimitiveType::kTriangleStrip);
mesh->setNonIndexedNonInstanced(4);
}

View File

@ -30,6 +30,16 @@ namespace GrQuadPerEdgeAA {
enum class ColorType { kNone, kByte, kHalf, kLast = kHalf };
static const int kColorTypeCount = static_cast<int>(ColorType::kLast) + 1;
enum class IndexBufferOption {
kPictureFramed, // geometrically AA'd -> 8 verts/quad + an index buffer
kIndexedRects, // non-AA'd but indexed -> 4 verts/quad + an index buffer
kTriStrips, // non-AA'd -> 4 verts/quad but no index buffer
kLast = kTriStrips
};
static const int kIndexBufferOptionCount = static_cast<int>(IndexBufferOption::kLast) + 1;
IndexBufferOption CalcIndexBufferOption(GrAAType aa, int numQuads);
// Gets the minimum ColorType that can represent a color.
ColorType MinColorType(SkPMColor4f, GrClampType, const GrCaps&);
@ -42,17 +52,20 @@ namespace GrQuadPerEdgeAA {
VertexSpec()
: fDeviceQuadType(0) // kAxisAligned
, fLocalQuadType(0) // kAxisAligned
, fIndexBufferOption(0) // kPictureFramed
, fHasLocalCoords(false)
, fColorType(0) // kNone
, fHasDomain(false)
, fUsesCoverageAA(false)
, fCompatibleWithCoverageAsAlpha(false)
, fRequiresGeometryDomain(false) { }
, fRequiresGeometryDomain(false) {}
VertexSpec(GrQuad::Type deviceQuadType, ColorType colorType, GrQuad::Type localQuadType,
bool hasLocalCoords, Domain domain, GrAAType aa, bool coverageAsAlpha)
bool hasLocalCoords, Domain domain, GrAAType aa, bool coverageAsAlpha,
IndexBufferOption indexBufferOption)
: fDeviceQuadType(static_cast<unsigned>(deviceQuadType))
, fLocalQuadType(static_cast<unsigned>(localQuadType))
, fIndexBufferOption(static_cast<unsigned>(indexBufferOption))
, fHasLocalCoords(hasLocalCoords)
, fColorType(static_cast<unsigned>(colorType))
, fHasDomain(static_cast<unsigned>(domain))
@ -63,6 +76,9 @@ namespace GrQuadPerEdgeAA {
GrQuad::Type deviceQuadType() const { return static_cast<GrQuad::Type>(fDeviceQuadType); }
GrQuad::Type localQuadType() const { return static_cast<GrQuad::Type>(fLocalQuadType); }
IndexBufferOption indexBufferOption() const {
return static_cast<IndexBufferOption>(fIndexBufferOption);
}
bool hasLocalCoords() const { return fHasLocalCoords; }
ColorType colorType() const { return static_cast<ColorType>(fColorType); }
bool hasVertexColors() const { return ColorType::kNone != this->colorType(); }
@ -83,9 +99,11 @@ namespace GrQuadPerEdgeAA {
private:
static_assert(GrQuad::kTypeCount <= 4, "GrQuad::Type doesn't fit in 2 bits");
static_assert(kColorTypeCount <= 4, "Color doesn't fit in 2 bits");
static_assert(kIndexBufferOptionCount <= 4, "IndexBufferOption doesn't fit in 2 bits");
unsigned fDeviceQuadType: 2;
unsigned fLocalQuadType: 2;
unsigned fIndexBufferOption: 2;
unsigned fHasLocalCoords: 1;
unsigned fColorType : 2;
unsigned fHasDomain: 1;

View File

@ -531,8 +531,8 @@ private:
fPrePreparedDesc = arena->make<PrePreparedDesc>();
fPrePreparedDesc->fVertexSpec = this->characterize(&fPrePreparedDesc->fNumProxies,
&fPrePreparedDesc->fNumTotalQuads);
this->characterize(fPrePreparedDesc);
fPrePreparedDesc->allocateCommon(arena, clip);
fPrePreparedDesc->allocatePrePrepareOnly(arena);
@ -605,15 +605,16 @@ private:
}
#endif
VertexSpec characterize(int* numProxies, int* numTotalQuads) const {
void characterize(PrePreparedDesc* desc) const {
GrQuad::Type quadType = GrQuad::Type::kAxisAligned;
ColorType colorType = ColorType::kNone;
GrQuad::Type srcQuadType = GrQuad::Type::kAxisAligned;
Domain domain = Domain::kNo;
GrAAType overallAAType = this->aaType();
*numProxies = 0;
*numTotalQuads = 0;
desc->fNumProxies = 0;
desc->fNumTotalQuads = 0;
int maxQuadsPerMesh = 0;
for (const auto& op : ChainRange<TextureOp>(this)) {
if (op.fQuads.deviceQuadType() > quadType) {
@ -626,17 +627,22 @@ private:
domain = Domain::kYes;
}
colorType = SkTMax(colorType, static_cast<ColorType>(op.fColorType));
*numProxies += op.fProxyCnt;
desc->fNumProxies += op.fProxyCnt;
for (unsigned p = 0; p < op.fProxyCnt; ++p) {
*numTotalQuads += op.fProxyCountPairs[p].fQuadCnt;
desc->fNumTotalQuads += op.fProxyCountPairs[p].fQuadCnt;
maxQuadsPerMesh = SkTMax(op.fProxyCountPairs[p].fQuadCnt, maxQuadsPerMesh);
}
if (op.aaType() == GrAAType::kCoverage) {
overallAAType = GrAAType::kCoverage;
}
}
return VertexSpec(quadType, colorType, srcQuadType, /* hasLocal */ true, domain,
overallAAType, /* alpha as coverage */ true);
auto indexBufferOption = GrQuadPerEdgeAA::CalcIndexBufferOption(overallAAType,
maxQuadsPerMesh);
desc->fVertexSpec = VertexSpec(quadType, colorType, srcQuadType, /* hasLocal */ true,
domain, overallAAType, /* alpha as coverage */ true,
indexBufferOption);
}
// onPrePrepareDraws may or may not have been called at this point
@ -652,7 +658,7 @@ private:
} else {
SkArenaAlloc* arena = target->allocator();
desc.fVertexSpec = this->characterize(&desc.fNumProxies, &desc.fNumTotalQuads);
this->characterize(&desc);
desc.allocateCommon(arena, target->appliedClip());
SkASSERT(!desc.fVertexOffsets && !desc.fVertices);