Use clipped bounds for tessellation heuristic
The heuristic estimates the fill cost of the path based on its bounds. The goal is to use the inner triangulator for large paths with a low vertex count so that filling is simpler (no stencil), but triangulation cost is manageable. Considering the unclipped bounds means that very large path coordinates can mislead the heuristic into thinking there is substantial fill cost, when in fact that's always bounded by the clip dimensions. Bug: skia:12764 Change-Id: I9d14bbdd2b35df121b6a55d4a278656bf16ae8eb Reviewed-on: https://skia-review.googlesource.com/c/skia/+/488528 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
parent
c1bc0205d9
commit
bd05d877db
@ -30,6 +30,7 @@ GrOp::Owner make_non_convex_fill_op(GrRecordingContext* rContext,
|
||||
skgpu::v1::FillPathFlags fillPathFlags,
|
||||
GrAAType aaType,
|
||||
const SkRect& drawBounds,
|
||||
const SkIRect& clipBounds,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkPath& path,
|
||||
GrPaint&& paint) {
|
||||
@ -40,19 +41,22 @@ GrOp::Owner make_non_convex_fill_op(GrRecordingContext* rContext,
|
||||
// on the CPU. This is our fastest approach. It allows us to stencil only the curves,
|
||||
// and then fill the inner fan directly to the final render target, thus drawing the
|
||||
// majority of pixels in a single render pass.
|
||||
float gpuFragmentWork = drawBounds.height() * drawBounds.width();
|
||||
float cpuTessellationWork = numVerbs * SkNextLog2(numVerbs); // N log N.
|
||||
constexpr static float kCpuWeight = 512;
|
||||
constexpr static float kMinNumPixelsToTriangulate = 256 * 256;
|
||||
if (cpuTessellationWork * kCpuWeight + kMinNumPixelsToTriangulate < gpuFragmentWork) {
|
||||
return GrOp::Make<skgpu::v1::PathInnerTriangulateOp>(rContext,
|
||||
viewMatrix,
|
||||
path,
|
||||
std::move(paint),
|
||||
aaType,
|
||||
fillPathFlags,
|
||||
drawBounds);
|
||||
}
|
||||
SkRect clippedDrawBounds = SkRect::Make(clipBounds);
|
||||
if (clippedDrawBounds.intersect(drawBounds)) {
|
||||
float gpuFragmentWork = clippedDrawBounds.height() * clippedDrawBounds.width();
|
||||
float cpuTessellationWork = numVerbs * SkNextLog2(numVerbs); // N log N.
|
||||
constexpr static float kCpuWeight = 512;
|
||||
constexpr static float kMinNumPixelsToTriangulate = 256 * 256;
|
||||
if (cpuTessellationWork * kCpuWeight + kMinNumPixelsToTriangulate < gpuFragmentWork) {
|
||||
return GrOp::Make<skgpu::v1::PathInnerTriangulateOp>(rContext,
|
||||
viewMatrix,
|
||||
path,
|
||||
std::move(paint),
|
||||
aaType,
|
||||
fillPathFlags,
|
||||
drawBounds);
|
||||
}
|
||||
} // we should be clipped out when the GrClip is analyzed, so just return the default op
|
||||
}
|
||||
return GrOp::Make<skgpu::v1::PathStencilCoverOp>(rContext,
|
||||
arena,
|
||||
@ -196,6 +200,7 @@ bool TessellationPathRenderer::onDrawPath(const DrawPathArgs& args) {
|
||||
FillPathFlags::kNone,
|
||||
args.fAAType,
|
||||
drawBounds,
|
||||
*args.fClipConservativeBounds,
|
||||
*args.fViewMatrix,
|
||||
path,
|
||||
std::move(args.fPaint));
|
||||
@ -254,6 +259,7 @@ void TessellationPathRenderer::onStencilPath(const StencilPathArgs& args) {
|
||||
FillPathFlags::kStencilOnly,
|
||||
aaType,
|
||||
pathDevBounds,
|
||||
*args.fClipConservativeBounds,
|
||||
*args.fViewMatrix,
|
||||
path,
|
||||
GrPaint());
|
||||
|
Loading…
Reference in New Issue
Block a user