Batch across view matrix changes in linearizing convex path renderer

Bug: chromium:1066338

Change-Id: Ibcb2aed1331e3069521e4b9d34fd9a1c5a1018c4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/282845
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2020-04-10 09:16:04 -04:00 committed by Skia Commit-Bot
parent 801ba0d606
commit a3762ee8bf

View File

@ -34,8 +34,7 @@ static const int DEFAULT_BUFFER_SIZE = 100;
// the time being, we simply drop back to software rendering above this stroke width. // the time being, we simply drop back to software rendering above this stroke width.
static const SkScalar kMaxStrokeWidth = 20.0; static const SkScalar kMaxStrokeWidth = 20.0;
GrAALinearizingConvexPathRenderer::GrAALinearizingConvexPathRenderer() { GrAALinearizingConvexPathRenderer::GrAALinearizingConvexPathRenderer() = default;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -78,18 +77,30 @@ GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) co
if (stroke.getStyle() != SkStrokeRec::kFill_Style) { if (stroke.getStyle() != SkStrokeRec::kFill_Style) {
return CanDrawPath::kNo; return CanDrawPath::kNo;
} }
// This can almost handle perspective. It would need to use 3 component explicit local coords
// when there are FPs that require them. This is difficult to test because AAConvexPathRenderer
// takes almost all filled paths that could get here. So just avoid perspective fills.
if (args.fViewMatrix->hasPerspective()) {
return CanDrawPath::kNo;
}
return CanDrawPath::kYes; return CanDrawPath::kYes;
} }
// extract the result vertices and indices from the GrAAConvexTessellator // extract the result vertices and indices from the GrAAConvexTessellator
static void extract_verts(const GrAAConvexTessellator& tess, static void extract_verts(const GrAAConvexTessellator& tess,
const SkMatrix* localCoordsMatrix,
void* vertData, void* vertData,
const GrVertexColor& color, const GrVertexColor& color,
uint16_t firstIndex, uint16_t firstIndex,
uint16_t* idxs) { uint16_t* idxs) {
GrVertexWriter verts{vertData}; GrVertexWriter verts{vertData};
for (int i = 0; i < tess.numPts(); ++i) { for (int i = 0; i < tess.numPts(); ++i) {
verts.write(tess.point(i), color, tess.coverage(i)); SkPoint lc;
if (localCoordsMatrix) {
localCoordsMatrix->mapPoints(&lc, &tess.point(i), 1);
}
verts.write(tess.point(i), GrVertexWriter::If(localCoordsMatrix, lc), color,
tess.coverage(i));
} }
for (int i = 0; i < tess.numIndices(); ++i) { for (int i = 0; i < tess.numIndices(); ++i) {
@ -99,7 +110,6 @@ static void extract_verts(const GrAAConvexTessellator& tess,
static GrGeometryProcessor* create_lines_only_gp(SkArenaAlloc* arena, static GrGeometryProcessor* create_lines_only_gp(SkArenaAlloc* arena,
bool tweakAlphaForCoverage, bool tweakAlphaForCoverage,
const SkMatrix& viewMatrix,
bool usesLocalCoords, bool usesLocalCoords,
bool wideColor) { bool wideColor) {
using namespace GrDefaultGeoProcFactory; using namespace GrDefaultGeoProcFactory;
@ -107,11 +117,11 @@ static GrGeometryProcessor* create_lines_only_gp(SkArenaAlloc* arena,
Coverage::Type coverageType = Coverage::Type coverageType =
tweakAlphaForCoverage ? Coverage::kAttributeTweakAlpha_Type : Coverage::kAttribute_Type; tweakAlphaForCoverage ? Coverage::kAttributeTweakAlpha_Type : Coverage::kAttribute_Type;
LocalCoords::Type localCoordsType = LocalCoords::Type localCoordsType =
usesLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type; usesLocalCoords ? LocalCoords::kHasExplicit_Type : LocalCoords::kUnused_Type;
Color::Type colorType = Color::Type colorType =
wideColor ? Color::kPremulWideColorAttribute_Type : Color::kPremulGrColorAttribute_Type; wideColor ? Color::kPremulWideColorAttribute_Type : Color::kPremulGrColorAttribute_Type;
return MakeForDeviceSpace(arena, colorType, coverageType, localCoordsType, viewMatrix); return Make(arena, colorType, coverageType, localCoordsType, SkMatrix::I());
} }
namespace { namespace {
@ -146,10 +156,9 @@ public:
SkPaint::Join join, SkPaint::Join join,
SkScalar miterLimit, SkScalar miterLimit,
const GrUserStencilSettings* stencilSettings) const GrUserStencilSettings* stencilSettings)
: INHERITED(ClassID()) : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage, stencilSettings) {
, fHelper(helperArgs, GrAAType::kCoverage, stencilSettings) fPaths.emplace_back(
, fViewMatrix(viewMatrix) { PathData{viewMatrix, path, color, strokeWidth, miterLimit, style, join});
fPaths.emplace_back(PathData{color, path, strokeWidth, style, join, miterLimit});
// compute bounds // compute bounds
SkRect bounds = path.getBounds(); SkRect bounds = path.getBounds();
@ -213,7 +222,6 @@ private:
const GrXferProcessor::DstProxyView& dstProxyView) override { const GrXferProcessor::DstProxyView& dstProxyView) override {
GrGeometryProcessor* gp = create_lines_only_gp(arena, GrGeometryProcessor* gp = create_lines_only_gp(arena,
fHelper.compatibleWithCoverageAsAlpha(), fHelper.compatibleWithCoverageAsAlpha(),
fViewMatrix,
fHelper.usesLocalCoords(), fHelper.usesLocalCoords(),
fWideColor); fWideColor);
if (!gp) { if (!gp) {
@ -278,7 +286,7 @@ private:
GrAAConvexTessellator tess(args.fStyle, args.fStrokeWidth, GrAAConvexTessellator tess(args.fStyle, args.fStrokeWidth,
args.fJoin, args.fMiterLimit); args.fJoin, args.fMiterLimit);
if (!tess.tessellate(fViewMatrix, args.fPath)) { if (!tess.tessellate(args.fViewMatrix, args.fPath)) {
continue; continue;
} }
@ -310,7 +318,16 @@ private:
indices = (uint16_t*) sk_realloc_throw(indices, maxIndices * sizeof(uint16_t)); indices = (uint16_t*) sk_realloc_throw(indices, maxIndices * sizeof(uint16_t));
} }
extract_verts(tess, vertices + vertexStride * vertexCount, const SkMatrix* localCoordsMatrix = nullptr;
SkMatrix ivm;
if (fHelper.usesLocalCoords()) {
if (!args.fViewMatrix.invert(&ivm)) {
ivm = SkMatrix::I();
}
localCoordsMatrix = &ivm;
}
extract_verts(tess, localCoordsMatrix, vertices + vertexStride * vertexCount,
GrVertexColor(args.fColor, fWideColor), vertexCount, GrVertexColor(args.fColor, fWideColor), vertexCount,
indices + indexCount); indices + indexCount);
vertexCount += currentVertices; vertexCount += currentVertices;
@ -341,9 +358,6 @@ private:
if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) { if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
return CombineResult::kCannotCombine; return CombineResult::kCannotCombine;
} }
if (fViewMatrix != that->fViewMatrix) {
return CombineResult::kCannotCombine;
}
fPaths.push_back_n(that->fPaths.count(), that->fPaths.begin()); fPaths.push_back_n(that->fPaths.count(), that->fPaths.begin());
fWideColor |= that->fWideColor; fWideColor |= that->fWideColor;
@ -352,17 +366,17 @@ private:
struct PathData { struct PathData {
SkPMColor4f fColor; SkMatrix fViewMatrix;
SkPath fPath; SkPath fPath;
SkPMColor4f fColor;
SkScalar fStrokeWidth; SkScalar fStrokeWidth;
SkScalar fMiterLimit;
SkStrokeRec::Style fStyle; SkStrokeRec::Style fStyle;
SkPaint::Join fJoin; SkPaint::Join fJoin;
SkScalar fMiterLimit;
}; };
SkSTArray<1, PathData, true> fPaths; SkSTArray<1, PathData, true> fPaths;
Helper fHelper; Helper fHelper;
SkMatrix fViewMatrix;
bool fWideColor; bool fWideColor;
SkTDArray<GrSimpleMesh*> fMeshes; SkTDArray<GrSimpleMesh*> fMeshes;