Revert "Try to avoid vertex colors in Texture/FillRect ops when possible."

This reverts commit e0b989e5e3.

Reason for revert: gms

Original change's description:
> Try to avoid vertex colors in Texture/FillRect ops when possible.
> 
> Avoids unnecessary fragment shader color multiplication.
> 
> Change-Id: I353d3ca91824ce20c9e9af1c5c84ab9953ddd8ab
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/201004
> Commit-Queue: Brian Salomon <bsalomon@google.com>
> Reviewed-by: Michael Ludwig <michaelludwig@google.com>

TBR=bsalomon@google.com,michaelludwig@google.com

Change-Id: I42b37e50c1c0185d8f8a52984c9350464004880e
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/201081
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2019-03-14 00:26:15 +00:00 committed by Skia Commit-Bot
parent a4bbe1431a
commit 368ea4f99e
4 changed files with 27 additions and 38 deletions

View File

@ -79,7 +79,7 @@ public:
const GrPerspQuad& localQuad, GrQuadType localQuadType)
: INHERITED(ClassID())
, fHelper(args, aaType, stencil)
, fColorType(GrQuadPerEdgeAA::MinColorType(paintColor)) {
, fWideColor(!SkPMColor4fFitsInBytes(paintColor)) {
// The color stored with the quad is the clear color if a scissor-clear is decided upon
// when executing the op.
fDeviceQuads.push_back(deviceQuad, deviceQuadType, { paintColor, edgeFlags });
@ -178,9 +178,10 @@ private:
using Domain = GrQuadPerEdgeAA::Domain;
static constexpr SkRect kEmptyDomain = SkRect::MakeEmpty();
VertexSpec vertexSpec(fDeviceQuads.quadType(), fColorType, fLocalQuads.quadType(),
fHelper.usesLocalCoords(), Domain::kNo, fHelper.aaType(),
fHelper.compatibleWithAlphaAsCoverage());
VertexSpec vertexSpec(fDeviceQuads.quadType(),
fWideColor ? ColorType::kHalf : ColorType::kByte,
fLocalQuads.quadType(), fHelper.usesLocalCoords(), Domain::kNo,
fHelper.aaType(), fHelper.compatibleWithAlphaAsCoverage());
// 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());
@ -257,7 +258,7 @@ private:
// If the processor sets are compatible, the two ops are always compatible; it just needs to
// adjust the state of the op to be the more general quad and aa types of the two ops and
// then concatenate the per-quad data.
fColorType = SkTMax(fColorType, that->fColorType);
fWideColor |= that->fWideColor;
// The helper stores the aa type, but isCompatible(with true arg) allows the two ops' aa
// types to be none and coverage, in which case this op's aa type must be lifted to coverage
@ -296,8 +297,8 @@ private:
}
// clear compatible won't need to be updated, since device quad type and paint is the same,
// but this quad has a new color, so maybe update color type
fColorType = SkTMax(fColorType, GrQuadPerEdgeAA::MinColorType(color));
// but this quad has a new color, so maybe update wide color
fWideColor |= !SkPMColor4fFitsInBytes(color);
// Update the bounds and add the quad to this op's storage
SkRect newBounds = this->bounds();
@ -327,7 +328,7 @@ private:
// No metadata attached to the local quads; this list is empty when local coords are not needed.
GrQuadList fLocalQuads;
ColorType fColorType;
unsigned fWideColor: 1;
typedef GrMeshDrawOp INHERITED;
};

View File

@ -624,7 +624,9 @@ static CoverageMode get_mode_for_spec(const GrQuadPerEdgeAA::VertexSpec& spec) {
// Writes four vertices in triangle strip order, including the additional data for local
// coordinates, domain, color, and coverage as needed to satisfy the vertex spec.
static void write_quad(GrVertexWriter* vb, const GrQuadPerEdgeAA::VertexSpec& spec,
CoverageMode mode, Sk4f coverage, SkPMColor4f color4f, const SkRect& domain,
CoverageMode mode, Sk4f coverage,
SkPMColor4f color4f, bool wideColor,
const SkRect& domain,
const Vertices& quad) {
static constexpr auto If = GrVertexWriter::If<float>;
@ -637,9 +639,8 @@ static void write_quad(GrVertexWriter* vb, const GrQuadPerEdgeAA::VertexSpec& sp
// save color
if (spec.hasVertexColors()) {
bool wide = spec.colorType() == GrQuadPerEdgeAA::ColorType::kHalf;
vb->write(GrVertexColor(
color4f * (mode == CoverageMode::kWithColor ? coverage[i] : 1.f), wide));
color4f * (mode == CoverageMode::kWithColor ? coverage[i] : 1.f), wideColor));
}
// save local position
@ -683,21 +684,12 @@ static sk_sp<const GrGpuBuffer> get_index_buffer(GrResourceProvider* resourcePro
namespace GrQuadPerEdgeAA {
ColorType MinColorType(SkPMColor4f color) {
if (color == SK_PMColor4fWHITE) {
return ColorType::kNone;
} else if (color.fitsInBytes()) {
return ColorType::kByte;
} else {
return ColorType::kHalf;
}
}
////////////////// Tessellate Implementation
void* Tessellate(void* vertices, const VertexSpec& spec, const GrPerspQuad& deviceQuad,
const SkPMColor4f& color4f, const GrPerspQuad& localQuad, const SkRect& domain,
GrQuadAAFlags aaFlags) {
bool wideColor = GrQuadPerEdgeAA::ColorType::kHalf == spec.colorType();
CoverageMode mode = get_mode_for_spec(spec);
// Load position data into Sk4fs (always x, y, and load w to avoid branching down the road)
@ -740,12 +732,12 @@ void* Tessellate(void* vertices, const VertexSpec& spec, const GrPerspQuad& devi
// applied a mirror, etc. The current 2D case is already adequately fast.
// Write two quads for inner and outer, inner will use the
write_quad(&vb, spec, mode, maxCoverage, color4f, domain, inner);
write_quad(&vb, spec, mode, 0.f, color4f, domain, outer);
write_quad(&vb, spec, mode, maxCoverage, color4f, wideColor, domain, inner);
write_quad(&vb, spec, mode, 0.f, color4f, wideColor, domain, outer);
} else {
// No outsetting needed, just write a single quad with full coverage
SkASSERT(mode == CoverageMode::kNone);
write_quad(&vb, spec, mode, 1.f, color4f, domain, outer);
write_quad(&vb, spec, mode, 1.f, color4f, wideColor, domain, outer);
}
return vb.fPtr;

View File

@ -26,9 +26,6 @@ namespace GrQuadPerEdgeAA {
enum class ColorType { kNone, kByte, kHalf, kLast = kHalf };
static const int kColorTypeCount = static_cast<int>(ColorType::kLast) + 1;
// Gets the minimum ColorType that can represent a color.
ColorType MinColorType(SkPMColor4f);
// Specifies the vertex configuration for an op that renders per-edge AA quads. The vertex
// order (when enabled) is device position, color, local position, domain, aa edge equations.
// This order matches the constructor argument order of VertexSpec and is the order that

View File

@ -291,7 +291,7 @@ private:
auto bounds = dstQuad.bounds(dstQuadType);
this->setBounds(bounds, HasAABloat(aaType == GrAAType::kCoverage), IsZeroArea::kNo);
fDomain = static_cast<unsigned>(domain);
fColorType = static_cast<unsigned>(GrQuadPerEdgeAA::MinColorType(color));
fWideColor = !SkPMColor4fFitsInBytes(color);
fCanSkipAllocatorGather =
static_cast<unsigned>(fProxies[0].fProxy->canSkipResourceAllocator());
}
@ -311,7 +311,7 @@ private:
// identical, unless an entry provides a dstClip or additional transform that changes it.
// The quad list will automatically adapt to that.
fQuads.reserve(cnt, GrQuadTypeForTransformedRect(viewMatrix));
bool allOpaque = true;
for (unsigned p = 0; p < fProxyCnt; ++p) {
fProxies[p].fProxy = SkRef(set[p].fProxy.get());
fProxies[p].fQuadCnt = 1;
@ -351,7 +351,6 @@ private:
set[p].fDstRect);
}
float alpha = SkTPin(set[p].fAlpha, 0.f, 1.f);
allOpaque &= (1.f == alpha);
SkPMColor4f color{alpha, alpha, alpha, alpha};
int srcQuadIndex = -1;
if (set[p].fDstClipQuad) {
@ -372,7 +371,7 @@ private:
}
this->setBounds(bounds, HasAABloat(this->aaType() == GrAAType::kCoverage), IsZeroArea::kNo);
fDomain = static_cast<unsigned>(false);
fColorType = static_cast<unsigned>(allOpaque ? ColorType::kNone : ColorType::kByte);
fWideColor = static_cast<unsigned>(false);
}
void tess(void* v, const VertexSpec& spec, const GrTextureProxy* proxy, int start,
@ -409,7 +408,7 @@ private:
GrQuadType quadType = GrQuadType::kRect;
GrQuadType srcQuadType = GrQuadType::kRect;
Domain domain = Domain::kNo;
ColorType colorType = ColorType::kNone;
bool wideColor = false;
int numProxies = 0;
int numTotalQuads = 0;
auto textureType = fProxies[0].fProxy->textureType();
@ -427,7 +426,7 @@ private:
if (op.fDomain) {
domain = Domain::kYes;
}
colorType = SkTMax(colorType, static_cast<ColorType>(op.fColorType));
wideColor |= op.fWideColor;
numProxies += op.fProxyCnt;
for (unsigned p = 0; p < op.fProxyCnt; ++p) {
numTotalQuads += op.fProxies[p].fQuadCnt;
@ -444,7 +443,8 @@ private:
}
}
VertexSpec vertexSpec(quadType, colorType, srcQuadType, /* hasLocal */ true, domain, aaType,
VertexSpec vertexSpec(quadType, wideColor ? ColorType::kHalf : ColorType::kByte,
srcQuadType, /* hasLocal */ true, domain, aaType,
/* alpha as coverage */ true);
GrSamplerState samplerState = GrSamplerState(GrSamplerState::WrapMode::kClamp,
@ -562,7 +562,7 @@ private:
}
fDomain |= that->fDomain;
fColorType = SkTMax(fColorType, that->fColorType);
fWideColor |= that->fWideColor;
if (upgradeToCoverageAAOnMerge) {
fAAType = static_cast<unsigned>(GrAAType::kCoverage);
}
@ -644,12 +644,11 @@ private:
unsigned fFilter : 2;
unsigned fAAType : 2;
unsigned fDomain : 1;
unsigned fColorType : 2;
GR_STATIC_ASSERT(GrQuadPerEdgeAA::kColorTypeCount <= 4);
unsigned fWideColor : 1;
// Used to track whether fProxy is ref'ed or has a pending IO after finalize() is called.
unsigned fFinalized : 1;
unsigned fCanSkipAllocatorGather : 1;
unsigned fProxyCnt : 32 - 9;
unsigned fProxyCnt : 32 - 8;
Proxy fProxies[1];
static_assert(kGrQuadTypeCount <= 4, "GrQuadType does not fit in 2 bits");