Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
PathRendererCacheTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
12#include "include/core/SkPath.h"
13#include "include/core/SkRect.h"
21#include "include/gpu/GrTypes.h"
23#include "src/core/SkPathPriv.h"
38#include "tests/Test.h"
39
40#include <functional>
41#include <memory>
42#include <utility>
43
44struct GrContextOptions;
45
47 SkPath path;
48 path.moveTo(100, 0);
49 path.lineTo(200, 200);
50 path.lineTo(100, 150);
51 path.lineTo(0, 200);
52 path.close();
53 return path;
54}
55
56static void draw_path(GrRecordingContext* rContext,
58 const SkPath& path,
60 GrAAType aaType,
61 const GrStyle& style,
62 float scaleX = 1.f) {
65
66 SkIRect clipConservativeBounds = SkIRect::MakeWH(sdc->width(),
67 sdc->height());
68 GrStyledShape shape(path, style);
69 if (shape.style().applies()) {
71 }
72 SkMatrix matrix = SkMatrix::I();
73 matrix.setScaleX(scaleX);
75 std::move(paint),
77 sdc,
78 nullptr,
79 &clipConservativeBounds,
80 &matrix,
81 &shape,
82 aaType,
83 false};
84 pr->drawPath(args);
85}
86
87static bool cache_non_scratch_resources_equals(GrResourceCache* cache, int expected) {
88#if GR_CACHE_STATS
89 GrResourceCache::Stats stats;
90 cache->getStats(&stats);
91 return (stats.fTotal - stats.fScratch) == expected;
92#else
93 return true;
94#endif
95}
96
97static void test_path(
99 const std::function<SkPath(void)>& createPath,
100 const std::function<skgpu::ganesh::PathRenderer*(GrRecordingContext*)>& makePathRenderer,
101 int expected,
102 bool checkListeners,
103 GrAAType aaType = GrAAType::kNone,
106 // The cache needs to be big enough that nothing gets flushed, or our expectations can be wrong
107 dContext->setResourceCacheLimit(8000000);
108 GrResourceCache* cache = dContext->priv().getResourceCache();
109
110 auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext.get(),
112 nullptr,
114 {800, 800},
116 /*label=*/{},
117 /* sampleCnt= */ 1,
118 skgpu::Mipmapped::kNo,
119 GrProtected::kNo,
121 if (!sdc) {
122 return;
123 }
124
125 sk_sp<skgpu::ganesh::PathRenderer> pathRenderer(makePathRenderer(dContext.get()));
126 SkPath path = createPath();
127
128 // Initially, cache only has the render target context
130
131 // Draw the path, check that new resource count matches expectations
132 draw_path(dContext.get(), sdc.get(), path, pathRenderer.get(), aaType, style);
133 dContext->flushAndSubmit();
135
136 // Nothing should be purgeable yet
137 cache->purgeAsNeeded();
139
140 // Reset the path to change the GenID, which should invalidate one resource in the cache.
141 // Some path renderers may leave other unique-keyed resources in the cache, though.
142 path.reset();
143 cache->purgeAsNeeded();
145
146 if (!checkListeners) {
147 return;
148 }
149
150 // Test that purging the cache of masks also removes listeners from the path.
151 path = createPath();
153 for (int i = 0; i < 20; ++i) {
154 float scaleX = 1 + ((float)i + 1)/20.f;
155 draw_path(dContext.get(), sdc.get(), path, pathRenderer.get(), aaType, style, scaleX);
156 }
157 dContext->flushAndSubmit();
159 cache->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources);
160 // The listeners don't actually purge until we try to add another one.
161 draw_path(dContext.get(), sdc.get(), path, pathRenderer.get(), aaType, style);
163}
164
165#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
166// Test that deleting the original path invalidates the VBs cached by the tessellating path renderer
167DEF_GANESH_TEST(TriangulatingPathRendererCacheTest,
168 reporter,
169 /* options */,
171 auto createPR = [](GrRecordingContext*) {
173 };
174
175 // Triangulating path renderer creates a single vertex buffer for non-AA paths. No other
176 // resources should be created.
177 const int kExpectedResources = 1;
178
179 test_path(reporter, create_concave_path, createPR, kExpectedResources, false);
180
181 // Test with a style that alters the path geometry. This needs to attach the invalidation logic
182 // to the original path, not the modified path produced by the style.
185 paint.setStrokeWidth(1);
186 GrStyle style(paint);
187 test_path(reporter, create_concave_path, createPR, kExpectedResources, false, GrAAType::kNone,
188 std::move(style));
189}
190#endif
191
192// Test that deleting the original path invalidates the textures cached by the SW path renderer
193DEF_GANESH_TEST(SoftwarePathRendererCacheTest,
194 reporter,
195 /* options */,
197 auto createPR = [](GrRecordingContext* rContext) {
198 return new skgpu::ganesh::SoftwarePathRenderer(rContext->priv().proxyProvider(), true);
199 };
200
201 // Software path renderer creates a mask texture and renders with a non-AA rect, but the flush
202 // only contains a single quad so FillRectOp doesn't need to use the shared index buffer.
203 const int kExpectedResources = 1;
204
205 test_path(reporter, create_concave_path, createPR, kExpectedResources, true,
207
208 // Test with a style that alters the path geometry. This needs to attach the invalidation logic
209 // to the original path, not the modified path produced by the style.
212 paint.setStrokeWidth(1);
213 GrStyle style(paint);
214 test_path(reporter, create_concave_path, createPR, kExpectedResources, true,
215 GrAAType::kCoverage, std::move(style));
216}
reporter
GrAAType
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
static SkPath create_concave_path()
static void test_path(skiatest::Reporter *reporter, const std::function< SkPath(void)> &createPath, const std::function< skgpu::ganesh::PathRenderer *(GrRecordingContext *)> &makePathRenderer, int expected, bool checkListeners, GrAAType aaType=GrAAType::kNone, GrStyle style=GrStyle(SkStrokeRec::kFill_InitStyle))
static bool cache_non_scratch_resources_equals(GrResourceCache *cache, int expected)
static void draw_path(GrRecordingContext *rContext, skgpu::ganesh::SurfaceDrawContext *sdc, const SkPath &path, skgpu::ganesh::PathRenderer *pr, GrAAType aaType, const GrStyle &style, float scaleX=1.f)
#define DEF_GANESH_TEST(name, reporter, options, ctsEnforcement)
Definition Test.h:393
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
static sk_sp< GrDirectContext > MakeMock(const GrMockOptions *, const GrContextOptions &)
static const GrXPFactory * Get(SkBlendMode blendMode)
bool applies() const
Definition GrStyle.h:143
const GrStyle & style() const
GrStyledShape applyStyle(GrStyle::Apply apply, SkScalar scale) const
static const SkMatrix & I()
@ kStroke_Style
set to stroke geometry
Definition SkPaint.h:194
static int GenIDChangeListenersCount(const SkPath &)
Definition SkPath.cpp:3920
T * get() const
Definition SkRefCnt.h:303
bool drawPath(const DrawPathArgs &args)
static std::unique_ptr< SurfaceDrawContext > Make(GrRecordingContext *, GrColorType, sk_sp< GrSurfaceProxy >, sk_sp< SkColorSpace >, GrSurfaceOrigin, const SkSurfaceProps &)
const Paint & paint
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const GrUserStencilSettings & kUnused
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition SkRect.h:56