Flutter Engine
The Flutter Engine
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
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 }
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
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,
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);
109
110 auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext.get(),
112 nullptr,
114 {800, 800},
116 /*label=*/{},
117 /* sampleCnt= */ 1,
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
Definition: FontMgrTest.cpp:39
GrAAType
Definition: GrTypesPriv.h:200
@ 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)
DEF_GANESH_TEST(TriangulatingPathRendererCacheTest, reporter,, CtsEnforcement::kNever)
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
GrResourceCache * getResourceCache()
static sk_sp< GrDirectContext > MakeMock(const GrMockOptions *, const GrContextOptions &)
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
GrDirectContextPriv priv()
void setResourceCacheLimit(size_t maxResourceBytes)
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()
Definition: SkMatrix.cpp:1544
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
static int GenIDChangeListenersCount(const SkPath &)
Definition: SkPath.cpp:3988
Definition: SkPath.h:59
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
Definition: color_source.cc:38
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Dart_NativeFunction function
Definition: fuchsia.cc:51
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
Definition: switches.h:191
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
dictionary stats
Definition: malisc.py:20
static const GrUserStencilSettings & kUnused
Definition: SkRect.h:32
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56