xref: /aosp_15_r20/external/skia/tests/GrThreadSafeCacheTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2020 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkAlphaType.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlendMode.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSamplingOptions.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurfaceProps.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkMalloc.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrDeferredDisplayList.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrDeferredDisplayListRecorder.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrSurfaceCharacterization.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkMessageBus.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/GpuTypesPriv.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ResourceKey.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/SkBackingFit.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Swizzle.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrAppliedClip.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrBuffer.h"
47*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCanvas.h"
48*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
49*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrColorSpaceXform.h"
50*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDefaultGeoProcFactory.h"
51*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
52*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpu.h"
53*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpuBuffer.h"
54*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrOpFlushState.h"
55*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPaint.h"
56*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProcessorSet.h"
57*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProxyProvider.h"
58*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
59*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRenderTargetProxy.h"
60*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceCache.h"
61*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceProvider.h"
62*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSamplerState.h"
63*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrStyle.h"
64*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurface.h"
65*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxy.h"
66*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxyView.h"
67*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureProxy.h"
68*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrThreadSafeCache.h"
69*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SurfaceDrawContext.h"
70*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/GrDrawOp.h"
71*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/GrOp.h"
72*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
73*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
74*c8dee2aaSAndroid Build Coastguard Worker #include "tests/TestUtils.h"
75*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ProxyUtils.h"
76*c8dee2aaSAndroid Build Coastguard Worker 
77*c8dee2aaSAndroid Build Coastguard Worker #include <chrono>
78*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
79*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
80*c8dee2aaSAndroid Build Coastguard Worker #include <functional>
81*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
82*c8dee2aaSAndroid Build Coastguard Worker #include <thread>
83*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker class GrDstProxyView;
86*c8dee2aaSAndroid Build Coastguard Worker class GrProgramInfo;
87*c8dee2aaSAndroid Build Coastguard Worker class GrThreadSafeVertexTestOp;
88*c8dee2aaSAndroid Build Coastguard Worker class SkArenaAlloc;
89*c8dee2aaSAndroid Build Coastguard Worker enum class GrXferBarrierFlags;
90*c8dee2aaSAndroid Build Coastguard Worker struct GrContextOptions;
91*c8dee2aaSAndroid Build Coastguard Worker 
92*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kImageWH = 32;
93*c8dee2aaSAndroid Build Coastguard Worker static constexpr auto kImageOrigin = kBottomLeft_GrSurfaceOrigin;
94*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kNoID = -1;
95*c8dee2aaSAndroid Build Coastguard Worker 
default_ii(int wh)96*c8dee2aaSAndroid Build Coastguard Worker static SkImageInfo default_ii(int wh) {
97*c8dee2aaSAndroid Build Coastguard Worker     return SkImageInfo::Make(wh, wh, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
98*c8dee2aaSAndroid Build Coastguard Worker }
99*c8dee2aaSAndroid Build Coastguard Worker 
new_SDC(GrRecordingContext * rContext,int wh)100*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<skgpu::ganesh::SurfaceDrawContext> new_SDC(GrRecordingContext* rContext,
101*c8dee2aaSAndroid Build Coastguard Worker                                                                   int wh) {
102*c8dee2aaSAndroid Build Coastguard Worker     return skgpu::ganesh::SurfaceDrawContext::Make(rContext,
103*c8dee2aaSAndroid Build Coastguard Worker                                                    GrColorType::kRGBA_8888,
104*c8dee2aaSAndroid Build Coastguard Worker                                                    nullptr,
105*c8dee2aaSAndroid Build Coastguard Worker                                                    SkBackingFit::kExact,
106*c8dee2aaSAndroid Build Coastguard Worker                                                    {wh, wh},
107*c8dee2aaSAndroid Build Coastguard Worker                                                    SkSurfaceProps(),
108*c8dee2aaSAndroid Build Coastguard Worker                                                    /* label= */ {},
109*c8dee2aaSAndroid Build Coastguard Worker                                                    /* sampleCnt= */ 1,
110*c8dee2aaSAndroid Build Coastguard Worker                                                    skgpu::Mipmapped::kNo,
111*c8dee2aaSAndroid Build Coastguard Worker                                                    GrProtected::kNo,
112*c8dee2aaSAndroid Build Coastguard Worker                                                    kImageOrigin,
113*c8dee2aaSAndroid Build Coastguard Worker                                                    skgpu::Budgeted::kYes);
114*c8dee2aaSAndroid Build Coastguard Worker }
115*c8dee2aaSAndroid Build Coastguard Worker 
create_view_key(skgpu::UniqueKey * key,int wh,int id)116*c8dee2aaSAndroid Build Coastguard Worker static void create_view_key(skgpu::UniqueKey* key, int wh, int id) {
117*c8dee2aaSAndroid Build Coastguard Worker     static const skgpu::UniqueKey::Domain kViewDomain = skgpu::UniqueKey::GenerateDomain();
118*c8dee2aaSAndroid Build Coastguard Worker     skgpu::UniqueKey::Builder builder(key, kViewDomain, 1);
119*c8dee2aaSAndroid Build Coastguard Worker     builder[0] = wh;
120*c8dee2aaSAndroid Build Coastguard Worker     builder.finish();
121*c8dee2aaSAndroid Build Coastguard Worker 
122*c8dee2aaSAndroid Build Coastguard Worker     if (id != kNoID) {
123*c8dee2aaSAndroid Build Coastguard Worker         key->setCustomData(SkData::MakeWithCopy(&id, sizeof(id)));
124*c8dee2aaSAndroid Build Coastguard Worker     }
125*c8dee2aaSAndroid Build Coastguard Worker }
126*c8dee2aaSAndroid Build Coastguard Worker 
create_vert_key(skgpu::UniqueKey * key,int wh,int id)127*c8dee2aaSAndroid Build Coastguard Worker static void create_vert_key(skgpu::UniqueKey* key, int wh, int id) {
128*c8dee2aaSAndroid Build Coastguard Worker     static const skgpu::UniqueKey::Domain kVertDomain = skgpu::UniqueKey::GenerateDomain();
129*c8dee2aaSAndroid Build Coastguard Worker     skgpu::UniqueKey::Builder builder(key, kVertDomain, 1);
130*c8dee2aaSAndroid Build Coastguard Worker     builder[0] = wh;
131*c8dee2aaSAndroid Build Coastguard Worker     builder.finish();
132*c8dee2aaSAndroid Build Coastguard Worker 
133*c8dee2aaSAndroid Build Coastguard Worker     if (id != kNoID) {
134*c8dee2aaSAndroid Build Coastguard Worker         key->setCustomData(SkData::MakeWithCopy(&id, sizeof(id)));
135*c8dee2aaSAndroid Build Coastguard Worker     }
136*c8dee2aaSAndroid Build Coastguard Worker }
137*c8dee2aaSAndroid Build Coastguard Worker 
default_is_newer_better(SkData * incumbent,SkData * challenger)138*c8dee2aaSAndroid Build Coastguard Worker static bool default_is_newer_better(SkData* incumbent, SkData* challenger) {
139*c8dee2aaSAndroid Build Coastguard Worker     return false;
140*c8dee2aaSAndroid Build Coastguard Worker }
141*c8dee2aaSAndroid Build Coastguard Worker 
142*c8dee2aaSAndroid Build Coastguard Worker // When testing views we create a bitmap that covers the entire screen and has an inset blue rect
143*c8dee2aaSAndroid Build Coastguard Worker // atop a field of white.
144*c8dee2aaSAndroid Build Coastguard Worker // When testing verts we clear the background to white and simply draw an inset blur rect.
create_bitmap(int wh)145*c8dee2aaSAndroid Build Coastguard Worker static SkBitmap create_bitmap(int wh) {
146*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap bitmap;
147*c8dee2aaSAndroid Build Coastguard Worker 
148*c8dee2aaSAndroid Build Coastguard Worker     bitmap.allocPixels(default_ii(wh));
149*c8dee2aaSAndroid Build Coastguard Worker 
150*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas tmp(bitmap);
151*c8dee2aaSAndroid Build Coastguard Worker     tmp.clear(SK_ColorWHITE);
152*c8dee2aaSAndroid Build Coastguard Worker 
153*c8dee2aaSAndroid Build Coastguard Worker     SkPaint blue;
154*c8dee2aaSAndroid Build Coastguard Worker     blue.setColor(SK_ColorBLUE);
155*c8dee2aaSAndroid Build Coastguard Worker     blue.setAntiAlias(false);
156*c8dee2aaSAndroid Build Coastguard Worker 
157*c8dee2aaSAndroid Build Coastguard Worker     tmp.drawRect({10, 10, wh-10.0f, wh-10.0f}, blue);
158*c8dee2aaSAndroid Build Coastguard Worker 
159*c8dee2aaSAndroid Build Coastguard Worker     bitmap.setImmutable();
160*c8dee2aaSAndroid Build Coastguard Worker     return bitmap;
161*c8dee2aaSAndroid Build Coastguard Worker }
162*c8dee2aaSAndroid Build Coastguard Worker 
163*c8dee2aaSAndroid Build Coastguard Worker class TestHelper {
164*c8dee2aaSAndroid Build Coastguard Worker public:
165*c8dee2aaSAndroid Build Coastguard Worker     struct Stats {
166*c8dee2aaSAndroid Build Coastguard Worker         int fCacheHits = 0;
167*c8dee2aaSAndroid Build Coastguard Worker         int fCacheMisses = 0;
168*c8dee2aaSAndroid Build Coastguard Worker 
169*c8dee2aaSAndroid Build Coastguard Worker         int fNumSWCreations = 0;
170*c8dee2aaSAndroid Build Coastguard Worker         int fNumLazyCreations = 0;
171*c8dee2aaSAndroid Build Coastguard Worker         int fNumHWCreations = 0;
172*c8dee2aaSAndroid Build Coastguard Worker     };
173*c8dee2aaSAndroid Build Coastguard Worker 
TestHelper(GrDirectContext * dContext,GrThreadSafeCache::IsNewerBetter isNewerBetter=default_is_newer_better)174*c8dee2aaSAndroid Build Coastguard Worker     TestHelper(GrDirectContext* dContext,
175*c8dee2aaSAndroid Build Coastguard Worker                GrThreadSafeCache::IsNewerBetter isNewerBetter = default_is_newer_better)
176*c8dee2aaSAndroid Build Coastguard Worker             : fDContext(dContext)
177*c8dee2aaSAndroid Build Coastguard Worker             , fIsNewerBetter(isNewerBetter) {
178*c8dee2aaSAndroid Build Coastguard Worker         fDst = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kNo, default_ii(kImageWH));
179*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(fDst);
180*c8dee2aaSAndroid Build Coastguard Worker 
181*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization characterization;
182*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(fDst->characterize(&characterization));
183*c8dee2aaSAndroid Build Coastguard Worker 
184*c8dee2aaSAndroid Build Coastguard Worker         fRecorder1 = std::make_unique<GrDeferredDisplayListRecorder>(characterization);
185*c8dee2aaSAndroid Build Coastguard Worker         this->ddlCanvas1()->clear(SkColors::kWhite);
186*c8dee2aaSAndroid Build Coastguard Worker 
187*c8dee2aaSAndroid Build Coastguard Worker         fRecorder2 = std::make_unique<GrDeferredDisplayListRecorder>(characterization);
188*c8dee2aaSAndroid Build Coastguard Worker         this->ddlCanvas2()->clear(SkColors::kWhite);
189*c8dee2aaSAndroid Build Coastguard Worker 
190*c8dee2aaSAndroid Build Coastguard Worker         fDst->getCanvas()->clear(SkColors::kWhite);
191*c8dee2aaSAndroid Build Coastguard Worker     }
192*c8dee2aaSAndroid Build Coastguard Worker 
~TestHelper()193*c8dee2aaSAndroid Build Coastguard Worker     ~TestHelper() {
194*c8dee2aaSAndroid Build Coastguard Worker         fDContext->flush();
195*c8dee2aaSAndroid Build Coastguard Worker         fDContext->submit(GrSyncCpu::kYes);
196*c8dee2aaSAndroid Build Coastguard Worker     }
197*c8dee2aaSAndroid Build Coastguard Worker 
stats()198*c8dee2aaSAndroid Build Coastguard Worker     Stats* stats() { return &fStats; }
199*c8dee2aaSAndroid Build Coastguard Worker 
numCacheEntries() const200*c8dee2aaSAndroid Build Coastguard Worker     int numCacheEntries() const { return this->threadSafeCache()->numEntries(); }
201*c8dee2aaSAndroid Build Coastguard Worker 
dContext()202*c8dee2aaSAndroid Build Coastguard Worker     GrDirectContext* dContext() { return fDContext; }
203*c8dee2aaSAndroid Build Coastguard Worker 
liveCanvas()204*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas* liveCanvas() { return fDst ? fDst->getCanvas() : nullptr; }
ddlCanvas1()205*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas* ddlCanvas1() { return fRecorder1 ? fRecorder1->getCanvas() : nullptr; }
snap1()206*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> snap1() {
207*c8dee2aaSAndroid Build Coastguard Worker         if (fRecorder1) {
208*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<GrDeferredDisplayList> tmp = fRecorder1->detach();
209*c8dee2aaSAndroid Build Coastguard Worker             fRecorder1 = nullptr;
210*c8dee2aaSAndroid Build Coastguard Worker             return tmp;
211*c8dee2aaSAndroid Build Coastguard Worker         }
212*c8dee2aaSAndroid Build Coastguard Worker 
213*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
214*c8dee2aaSAndroid Build Coastguard Worker     }
ddlCanvas2()215*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas* ddlCanvas2() { return fRecorder2 ? fRecorder2->getCanvas() : nullptr; }
snap2()216*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> snap2() {
217*c8dee2aaSAndroid Build Coastguard Worker         if (fRecorder2) {
218*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<GrDeferredDisplayList> tmp = fRecorder2->detach();
219*c8dee2aaSAndroid Build Coastguard Worker             fRecorder2 = nullptr;
220*c8dee2aaSAndroid Build Coastguard Worker             return tmp;
221*c8dee2aaSAndroid Build Coastguard Worker         }
222*c8dee2aaSAndroid Build Coastguard Worker 
223*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
224*c8dee2aaSAndroid Build Coastguard Worker     }
225*c8dee2aaSAndroid Build Coastguard Worker 
threadSafeCache()226*c8dee2aaSAndroid Build Coastguard Worker     GrThreadSafeCache* threadSafeCache() { return fDContext->priv().threadSafeCache(); }
threadSafeCache() const227*c8dee2aaSAndroid Build Coastguard Worker     const GrThreadSafeCache* threadSafeCache() const { return fDContext->priv().threadSafeCache(); }
228*c8dee2aaSAndroid Build Coastguard Worker 
229*c8dee2aaSAndroid Build Coastguard Worker     typedef void (TestHelper::*addAccessFP)(SkCanvas*, int wh, int id,
230*c8dee2aaSAndroid Build Coastguard Worker                                             bool failLookUp, bool failFillingIn);
231*c8dee2aaSAndroid Build Coastguard Worker     typedef bool (TestHelper::*checkFP)(SkCanvas*, int wh,
232*c8dee2aaSAndroid Build Coastguard Worker                                         int expectedHits, int expectedMisses,
233*c8dee2aaSAndroid Build Coastguard Worker                                         int expectedNumRefs, int expectedID);
234*c8dee2aaSAndroid Build Coastguard Worker 
235*c8dee2aaSAndroid Build Coastguard Worker     // Add a draw on 'canvas' that will introduce a ref on the 'wh' view
addViewAccess(SkCanvas * canvas,int wh,int id=kNoID,bool failLookup=false,bool failFillingIn=false)236*c8dee2aaSAndroid Build Coastguard Worker     void addViewAccess(SkCanvas* canvas,
237*c8dee2aaSAndroid Build Coastguard Worker                        int wh,
238*c8dee2aaSAndroid Build Coastguard Worker                        int id = kNoID,
239*c8dee2aaSAndroid Build Coastguard Worker                        bool failLookup = false,
240*c8dee2aaSAndroid Build Coastguard Worker                        bool failFillingIn = false) {
241*c8dee2aaSAndroid Build Coastguard Worker         auto rContext = canvas->recordingContext();
242*c8dee2aaSAndroid Build Coastguard Worker 
243*c8dee2aaSAndroid Build Coastguard Worker         auto view = AccessCachedView(rContext, this->threadSafeCache(),
244*c8dee2aaSAndroid Build Coastguard Worker                                      wh, failLookup, failFillingIn, id, &fStats);
245*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(view);
246*c8dee2aaSAndroid Build Coastguard Worker 
247*c8dee2aaSAndroid Build Coastguard Worker         auto sdc = skgpu::ganesh::TopDeviceSurfaceDrawContext(canvas);
248*c8dee2aaSAndroid Build Coastguard Worker 
249*c8dee2aaSAndroid Build Coastguard Worker         sdc->drawTexture(nullptr,
250*c8dee2aaSAndroid Build Coastguard Worker                          view,
251*c8dee2aaSAndroid Build Coastguard Worker                          kPremul_SkAlphaType,
252*c8dee2aaSAndroid Build Coastguard Worker                          GrSamplerState::Filter::kNearest,
253*c8dee2aaSAndroid Build Coastguard Worker                          GrSamplerState::MipmapMode::kNone,
254*c8dee2aaSAndroid Build Coastguard Worker                          SkBlendMode::kSrcOver,
255*c8dee2aaSAndroid Build Coastguard Worker                          {1.0f, 1.0f, 1.0f, 1.0f},
256*c8dee2aaSAndroid Build Coastguard Worker                          SkRect::MakeWH(wh, wh),
257*c8dee2aaSAndroid Build Coastguard Worker                          SkRect::MakeWH(wh, wh),
258*c8dee2aaSAndroid Build Coastguard Worker                          GrQuadAAFlags::kNone,
259*c8dee2aaSAndroid Build Coastguard Worker                          SkCanvas::kFast_SrcRectConstraint,
260*c8dee2aaSAndroid Build Coastguard Worker                          SkMatrix::I(),
261*c8dee2aaSAndroid Build Coastguard Worker                          nullptr);
262*c8dee2aaSAndroid Build Coastguard Worker     }
263*c8dee2aaSAndroid Build Coastguard Worker 
264*c8dee2aaSAndroid Build Coastguard Worker     // Besides checking that the number of refs and cache hits and misses are as expected, this
265*c8dee2aaSAndroid Build Coastguard Worker     // method also validates that the unique key doesn't appear in any of the other caches.
checkView(SkCanvas * canvas,int wh,int expectedHits,int expectedMisses,int expectedNumRefs,int expectedID)266*c8dee2aaSAndroid Build Coastguard Worker     bool checkView(SkCanvas* canvas, int wh,
267*c8dee2aaSAndroid Build Coastguard Worker                    int expectedHits, int expectedMisses, int expectedNumRefs, int expectedID) {
268*c8dee2aaSAndroid Build Coastguard Worker         if (fStats.fCacheHits != expectedHits || fStats.fCacheMisses != expectedMisses) {
269*c8dee2aaSAndroid Build Coastguard Worker             SkDebugf("Hits E: %d A: %d --- Misses E: %d A: %d\n",
270*c8dee2aaSAndroid Build Coastguard Worker                      expectedHits, fStats.fCacheHits, expectedMisses, fStats.fCacheMisses);
271*c8dee2aaSAndroid Build Coastguard Worker             return false;
272*c8dee2aaSAndroid Build Coastguard Worker         }
273*c8dee2aaSAndroid Build Coastguard Worker 
274*c8dee2aaSAndroid Build Coastguard Worker         skgpu::UniqueKey key;
275*c8dee2aaSAndroid Build Coastguard Worker         create_view_key(&key, wh, kNoID);
276*c8dee2aaSAndroid Build Coastguard Worker 
277*c8dee2aaSAndroid Build Coastguard Worker         auto threadSafeCache = this->threadSafeCache();
278*c8dee2aaSAndroid Build Coastguard Worker 
279*c8dee2aaSAndroid Build Coastguard Worker         auto [view, xtraData] = threadSafeCache->findWithData(key);
280*c8dee2aaSAndroid Build Coastguard Worker         if (!view.proxy()) {
281*c8dee2aaSAndroid Build Coastguard Worker             return false;
282*c8dee2aaSAndroid Build Coastguard Worker         }
283*c8dee2aaSAndroid Build Coastguard Worker 
284*c8dee2aaSAndroid Build Coastguard Worker         if (expectedID < 0) {
285*c8dee2aaSAndroid Build Coastguard Worker             if (xtraData) {
286*c8dee2aaSAndroid Build Coastguard Worker                 return false;
287*c8dee2aaSAndroid Build Coastguard Worker             }
288*c8dee2aaSAndroid Build Coastguard Worker         } else {
289*c8dee2aaSAndroid Build Coastguard Worker             if (!xtraData) {
290*c8dee2aaSAndroid Build Coastguard Worker                 return false;
291*c8dee2aaSAndroid Build Coastguard Worker             }
292*c8dee2aaSAndroid Build Coastguard Worker 
293*c8dee2aaSAndroid Build Coastguard Worker             const int* cachedID = static_cast<const int*>(xtraData->data());
294*c8dee2aaSAndroid Build Coastguard Worker             if (*cachedID != expectedID) {
295*c8dee2aaSAndroid Build Coastguard Worker                 return false;
296*c8dee2aaSAndroid Build Coastguard Worker             }
297*c8dee2aaSAndroid Build Coastguard Worker         }
298*c8dee2aaSAndroid Build Coastguard Worker 
299*c8dee2aaSAndroid Build Coastguard Worker         if (!view.proxy()->refCntGreaterThan(expectedNumRefs+1) ||  // +1 for 'view's ref
300*c8dee2aaSAndroid Build Coastguard Worker             view.proxy()->refCntGreaterThan(expectedNumRefs+2)) {
301*c8dee2aaSAndroid Build Coastguard Worker             return false;
302*c8dee2aaSAndroid Build Coastguard Worker         }
303*c8dee2aaSAndroid Build Coastguard Worker 
304*c8dee2aaSAndroid Build Coastguard Worker         if (canvas) {
305*c8dee2aaSAndroid Build Coastguard Worker             GrRecordingContext* rContext = canvas->recordingContext();
306*c8dee2aaSAndroid Build Coastguard Worker             GrProxyProvider* recordingProxyProvider = rContext->priv().proxyProvider();
307*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<GrTextureProxy> result = recordingProxyProvider->findProxyByUniqueKey(key);
308*c8dee2aaSAndroid Build Coastguard Worker             if (result) {
309*c8dee2aaSAndroid Build Coastguard Worker                 // views in this cache should never appear in the recorder's cache
310*c8dee2aaSAndroid Build Coastguard Worker                 return false;
311*c8dee2aaSAndroid Build Coastguard Worker             }
312*c8dee2aaSAndroid Build Coastguard Worker         }
313*c8dee2aaSAndroid Build Coastguard Worker 
314*c8dee2aaSAndroid Build Coastguard Worker         {
315*c8dee2aaSAndroid Build Coastguard Worker             GrProxyProvider* directProxyProvider = fDContext->priv().proxyProvider();
316*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<GrTextureProxy> result = directProxyProvider->findProxyByUniqueKey(key);
317*c8dee2aaSAndroid Build Coastguard Worker             if (result) {
318*c8dee2aaSAndroid Build Coastguard Worker                 // views in this cache should never appear in the main proxy cache
319*c8dee2aaSAndroid Build Coastguard Worker                 return false;
320*c8dee2aaSAndroid Build Coastguard Worker             }
321*c8dee2aaSAndroid Build Coastguard Worker         }
322*c8dee2aaSAndroid Build Coastguard Worker 
323*c8dee2aaSAndroid Build Coastguard Worker         {
324*c8dee2aaSAndroid Build Coastguard Worker             auto resourceProvider = fDContext->priv().resourceProvider();
325*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<GrSurface> surf = resourceProvider->findByUniqueKey<GrSurface>(key);
326*c8dee2aaSAndroid Build Coastguard Worker             if (surf) {
327*c8dee2aaSAndroid Build Coastguard Worker                 // the textures backing the views in this cache should never be discoverable in the
328*c8dee2aaSAndroid Build Coastguard Worker                 // resource cache
329*c8dee2aaSAndroid Build Coastguard Worker                 return false;
330*c8dee2aaSAndroid Build Coastguard Worker             }
331*c8dee2aaSAndroid Build Coastguard Worker         }
332*c8dee2aaSAndroid Build Coastguard Worker 
333*c8dee2aaSAndroid Build Coastguard Worker         return true;
334*c8dee2aaSAndroid Build Coastguard Worker     }
335*c8dee2aaSAndroid Build Coastguard Worker 
336*c8dee2aaSAndroid Build Coastguard Worker     void addVertAccess(SkCanvas* canvas,
337*c8dee2aaSAndroid Build Coastguard Worker                        int wh,
338*c8dee2aaSAndroid Build Coastguard Worker                        int id,
339*c8dee2aaSAndroid Build Coastguard Worker                        bool failLookup,
340*c8dee2aaSAndroid Build Coastguard Worker                        bool failFillingIn,
341*c8dee2aaSAndroid Build Coastguard Worker                        GrThreadSafeVertexTestOp** createdOp);
342*c8dee2aaSAndroid Build Coastguard Worker 
343*c8dee2aaSAndroid Build Coastguard Worker     // Add a draw on 'canvas' that will introduce a ref on a 'wh' vertex data
addVertAccess(SkCanvas * canvas,int wh,int id=kNoID,bool failLookup=false,bool failFillingIn=false)344*c8dee2aaSAndroid Build Coastguard Worker     void addVertAccess(SkCanvas* canvas,
345*c8dee2aaSAndroid Build Coastguard Worker                        int wh,
346*c8dee2aaSAndroid Build Coastguard Worker                        int id = kNoID,
347*c8dee2aaSAndroid Build Coastguard Worker                        bool failLookup = false,
348*c8dee2aaSAndroid Build Coastguard Worker                        bool failFillingIn = false) {
349*c8dee2aaSAndroid Build Coastguard Worker         this->addVertAccess(canvas, wh, id, failLookup, failFillingIn, nullptr);
350*c8dee2aaSAndroid Build Coastguard Worker     }
351*c8dee2aaSAndroid Build Coastguard Worker 
checkVert(SkCanvas * canvas,int wh,int expectedHits,int expectedMisses,int expectedNumRefs,int expectedID)352*c8dee2aaSAndroid Build Coastguard Worker     bool checkVert(SkCanvas* canvas, int wh,
353*c8dee2aaSAndroid Build Coastguard Worker                    int expectedHits, int expectedMisses, int expectedNumRefs, int expectedID) {
354*c8dee2aaSAndroid Build Coastguard Worker         if (fStats.fCacheHits != expectedHits || fStats.fCacheMisses != expectedMisses) {
355*c8dee2aaSAndroid Build Coastguard Worker             SkDebugf("Hits E: %d A: %d --- Misses E: %d A: %d\n",
356*c8dee2aaSAndroid Build Coastguard Worker                      expectedHits, fStats.fCacheHits, expectedMisses, fStats.fCacheMisses);
357*c8dee2aaSAndroid Build Coastguard Worker             return false;
358*c8dee2aaSAndroid Build Coastguard Worker         }
359*c8dee2aaSAndroid Build Coastguard Worker 
360*c8dee2aaSAndroid Build Coastguard Worker         skgpu::UniqueKey key;
361*c8dee2aaSAndroid Build Coastguard Worker         create_vert_key(&key, wh, kNoID);
362*c8dee2aaSAndroid Build Coastguard Worker 
363*c8dee2aaSAndroid Build Coastguard Worker         auto threadSafeCache = this->threadSafeCache();
364*c8dee2aaSAndroid Build Coastguard Worker 
365*c8dee2aaSAndroid Build Coastguard Worker         auto [vertData, xtraData] = threadSafeCache->findVertsWithData(key);
366*c8dee2aaSAndroid Build Coastguard Worker         if (!vertData) {
367*c8dee2aaSAndroid Build Coastguard Worker             return false;
368*c8dee2aaSAndroid Build Coastguard Worker         }
369*c8dee2aaSAndroid Build Coastguard Worker 
370*c8dee2aaSAndroid Build Coastguard Worker         if (expectedID < 0) {
371*c8dee2aaSAndroid Build Coastguard Worker             if (xtraData) {
372*c8dee2aaSAndroid Build Coastguard Worker                 return false;
373*c8dee2aaSAndroid Build Coastguard Worker             }
374*c8dee2aaSAndroid Build Coastguard Worker         } else {
375*c8dee2aaSAndroid Build Coastguard Worker             if (!xtraData) {
376*c8dee2aaSAndroid Build Coastguard Worker                 return false;
377*c8dee2aaSAndroid Build Coastguard Worker             }
378*c8dee2aaSAndroid Build Coastguard Worker 
379*c8dee2aaSAndroid Build Coastguard Worker             const int* cachedID = static_cast<const int*>(xtraData->data());
380*c8dee2aaSAndroid Build Coastguard Worker             if (*cachedID != expectedID) {
381*c8dee2aaSAndroid Build Coastguard Worker                 return false;
382*c8dee2aaSAndroid Build Coastguard Worker             }
383*c8dee2aaSAndroid Build Coastguard Worker         }
384*c8dee2aaSAndroid Build Coastguard Worker 
385*c8dee2aaSAndroid Build Coastguard Worker         if (!vertData->refCntGreaterThan(expectedNumRefs+1) ||  // +1 for 'vertData's ref
386*c8dee2aaSAndroid Build Coastguard Worker             vertData->refCntGreaterThan(expectedNumRefs+2)) {
387*c8dee2aaSAndroid Build Coastguard Worker             return false;
388*c8dee2aaSAndroid Build Coastguard Worker         }
389*c8dee2aaSAndroid Build Coastguard Worker 
390*c8dee2aaSAndroid Build Coastguard Worker         {
391*c8dee2aaSAndroid Build Coastguard Worker             auto resourceProvider = fDContext->priv().resourceProvider();
392*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<GrGpuBuffer> buffer = resourceProvider->findByUniqueKey<GrGpuBuffer>(key);
393*c8dee2aaSAndroid Build Coastguard Worker             if (buffer) {
394*c8dee2aaSAndroid Build Coastguard Worker                 // the buffer holding the vertex data in this cache should never be discoverable
395*c8dee2aaSAndroid Build Coastguard Worker                 // in the resource cache
396*c8dee2aaSAndroid Build Coastguard Worker                 return false;
397*c8dee2aaSAndroid Build Coastguard Worker             }
398*c8dee2aaSAndroid Build Coastguard Worker         }
399*c8dee2aaSAndroid Build Coastguard Worker 
400*c8dee2aaSAndroid Build Coastguard Worker         return true;
401*c8dee2aaSAndroid Build Coastguard Worker     }
402*c8dee2aaSAndroid Build Coastguard Worker 
checkImage(skiatest::Reporter * reporter,const sk_sp<SkSurface> & s)403*c8dee2aaSAndroid Build Coastguard Worker     bool checkImage(skiatest::Reporter* reporter, const sk_sp<SkSurface>& s) {
404*c8dee2aaSAndroid Build Coastguard Worker         SkBitmap actual;
405*c8dee2aaSAndroid Build Coastguard Worker 
406*c8dee2aaSAndroid Build Coastguard Worker         actual.allocPixels(default_ii(kImageWH));
407*c8dee2aaSAndroid Build Coastguard Worker 
408*c8dee2aaSAndroid Build Coastguard Worker         if (!s->readPixels(actual, 0, 0)) {
409*c8dee2aaSAndroid Build Coastguard Worker             return false;
410*c8dee2aaSAndroid Build Coastguard Worker         }
411*c8dee2aaSAndroid Build Coastguard Worker 
412*c8dee2aaSAndroid Build Coastguard Worker         SkBitmap expected = create_bitmap(kImageWH);
413*c8dee2aaSAndroid Build Coastguard Worker 
414*c8dee2aaSAndroid Build Coastguard Worker         const float tols[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
415*c8dee2aaSAndroid Build Coastguard Worker 
416*c8dee2aaSAndroid Build Coastguard Worker         auto error = std::function<ComparePixmapsErrorReporter>(
417*c8dee2aaSAndroid Build Coastguard Worker             [reporter](int x, int y, const float diffs[4]) {
418*c8dee2aaSAndroid Build Coastguard Worker                 SkASSERT(x >= 0 && y >= 0);
419*c8dee2aaSAndroid Build Coastguard Worker                 ERRORF(reporter, "mismatch at %d, %d (%f, %f, %f %f)",
420*c8dee2aaSAndroid Build Coastguard Worker                        x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
421*c8dee2aaSAndroid Build Coastguard Worker             });
422*c8dee2aaSAndroid Build Coastguard Worker 
423*c8dee2aaSAndroid Build Coastguard Worker         return ComparePixels(expected.pixmap(), actual.pixmap(), tols, error);
424*c8dee2aaSAndroid Build Coastguard Worker     }
425*c8dee2aaSAndroid Build Coastguard Worker 
checkImage(skiatest::Reporter * reporter)426*c8dee2aaSAndroid Build Coastguard Worker     bool checkImage(skiatest::Reporter* reporter) {
427*c8dee2aaSAndroid Build Coastguard Worker         return this->checkImage(reporter, fDst);
428*c8dee2aaSAndroid Build Coastguard Worker     }
429*c8dee2aaSAndroid Build Coastguard Worker 
checkImage(skiatest::Reporter * reporter,sk_sp<GrDeferredDisplayList> ddl)430*c8dee2aaSAndroid Build Coastguard Worker     bool checkImage(skiatest::Reporter* reporter, sk_sp<GrDeferredDisplayList> ddl) {
431*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> tmp =
432*c8dee2aaSAndroid Build Coastguard Worker                 SkSurfaces::RenderTarget(fDContext, skgpu::Budgeted::kNo, default_ii(kImageWH));
433*c8dee2aaSAndroid Build Coastguard Worker         if (!tmp) {
434*c8dee2aaSAndroid Build Coastguard Worker             return false;
435*c8dee2aaSAndroid Build Coastguard Worker         }
436*c8dee2aaSAndroid Build Coastguard Worker 
437*c8dee2aaSAndroid Build Coastguard Worker         if (!skgpu::ganesh::DrawDDL(tmp, std::move(ddl))) {
438*c8dee2aaSAndroid Build Coastguard Worker             return false;
439*c8dee2aaSAndroid Build Coastguard Worker         }
440*c8dee2aaSAndroid Build Coastguard Worker 
441*c8dee2aaSAndroid Build Coastguard Worker         return this->checkImage(reporter, std::move(tmp));
442*c8dee2aaSAndroid Build Coastguard Worker     }
443*c8dee2aaSAndroid Build Coastguard Worker 
gpuSize(int wh) const444*c8dee2aaSAndroid Build Coastguard Worker     size_t gpuSize(int wh) const {
445*c8dee2aaSAndroid Build Coastguard Worker         GrBackendFormat format = fDContext->defaultBackendFormat(kRGBA_8888_SkColorType,
446*c8dee2aaSAndroid Build Coastguard Worker                                                                  GrRenderable::kNo);
447*c8dee2aaSAndroid Build Coastguard Worker 
448*c8dee2aaSAndroid Build Coastguard Worker         return GrSurface::ComputeSize(format,
449*c8dee2aaSAndroid Build Coastguard Worker                                       {wh, wh},
450*c8dee2aaSAndroid Build Coastguard Worker                                       /*colorSamplesPerPixel=*/1,
451*c8dee2aaSAndroid Build Coastguard Worker                                       skgpu::Mipmapped::kNo,
452*c8dee2aaSAndroid Build Coastguard Worker                                       /*binSize=*/false);
453*c8dee2aaSAndroid Build Coastguard Worker     }
454*c8dee2aaSAndroid Build Coastguard Worker 
455*c8dee2aaSAndroid Build Coastguard Worker private:
456*c8dee2aaSAndroid Build Coastguard Worker     static GrSurfaceProxyView AccessCachedView(GrRecordingContext*,
457*c8dee2aaSAndroid Build Coastguard Worker                                                GrThreadSafeCache*,
458*c8dee2aaSAndroid Build Coastguard Worker                                                int wh,
459*c8dee2aaSAndroid Build Coastguard Worker                                                bool failLookup, bool failFillingIn, int id,
460*c8dee2aaSAndroid Build Coastguard Worker                                                Stats*);
461*c8dee2aaSAndroid Build Coastguard Worker     static GrSurfaceProxyView CreateViewOnCpu(GrRecordingContext*, int wh, Stats*);
462*c8dee2aaSAndroid Build Coastguard Worker     static bool FillInViewOnGpu(GrDirectContext*, int wh, Stats*,
463*c8dee2aaSAndroid Build Coastguard Worker                                 const GrSurfaceProxyView& lazyView,
464*c8dee2aaSAndroid Build Coastguard Worker                                 sk_sp<GrThreadSafeCache::Trampoline>);
465*c8dee2aaSAndroid Build Coastguard Worker 
466*c8dee2aaSAndroid Build Coastguard Worker     Stats fStats;
467*c8dee2aaSAndroid Build Coastguard Worker     GrDirectContext* fDContext = nullptr;
468*c8dee2aaSAndroid Build Coastguard Worker     GrThreadSafeCache::IsNewerBetter fIsNewerBetter;
469*c8dee2aaSAndroid Build Coastguard Worker 
470*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> fDst;
471*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<GrDeferredDisplayListRecorder> fRecorder1;
472*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<GrDeferredDisplayListRecorder> fRecorder2;
473*c8dee2aaSAndroid Build Coastguard Worker };
474*c8dee2aaSAndroid Build Coastguard Worker 
475*c8dee2aaSAndroid Build Coastguard Worker class GrThreadSafeVertexTestOp : public GrDrawOp {
476*c8dee2aaSAndroid Build Coastguard Worker public:
477*c8dee2aaSAndroid Build Coastguard Worker     DEFINE_OP_CLASS_ID
478*c8dee2aaSAndroid Build Coastguard Worker 
Make(GrRecordingContext * rContext,TestHelper::Stats * stats,int wh,int id,bool failLookup,bool failFillingIn,GrThreadSafeCache::IsNewerBetter isNewerBetter)479*c8dee2aaSAndroid Build Coastguard Worker     static GrOp::Owner Make(GrRecordingContext* rContext, TestHelper::Stats* stats,
480*c8dee2aaSAndroid Build Coastguard Worker                             int wh, int id, bool failLookup, bool failFillingIn,
481*c8dee2aaSAndroid Build Coastguard Worker                             GrThreadSafeCache::IsNewerBetter isNewerBetter) {
482*c8dee2aaSAndroid Build Coastguard Worker 
483*c8dee2aaSAndroid Build Coastguard Worker         return GrOp::Make<GrThreadSafeVertexTestOp>(
484*c8dee2aaSAndroid Build Coastguard Worker                 rContext, rContext, stats, wh, id, failLookup, failFillingIn, isNewerBetter);
485*c8dee2aaSAndroid Build Coastguard Worker     }
486*c8dee2aaSAndroid Build Coastguard Worker 
vertexData() const487*c8dee2aaSAndroid Build Coastguard Worker     const GrThreadSafeCache::VertexData* vertexData() const { return fVertexData.get(); }
488*c8dee2aaSAndroid Build Coastguard Worker 
489*c8dee2aaSAndroid Build Coastguard Worker private:
490*c8dee2aaSAndroid Build Coastguard Worker     friend class GrOp; // for ctor
491*c8dee2aaSAndroid Build Coastguard Worker 
GrThreadSafeVertexTestOp(GrRecordingContext * rContext,TestHelper::Stats * stats,int wh,int id,bool failLookup,bool failFillingIn,GrThreadSafeCache::IsNewerBetter isNewerBetter)492*c8dee2aaSAndroid Build Coastguard Worker     GrThreadSafeVertexTestOp(GrRecordingContext* rContext, TestHelper::Stats* stats, int wh, int id,
493*c8dee2aaSAndroid Build Coastguard Worker                              bool failLookup, bool failFillingIn,
494*c8dee2aaSAndroid Build Coastguard Worker                              GrThreadSafeCache::IsNewerBetter isNewerBetter)
495*c8dee2aaSAndroid Build Coastguard Worker             : INHERITED(ClassID())
496*c8dee2aaSAndroid Build Coastguard Worker             , fStats(stats)
497*c8dee2aaSAndroid Build Coastguard Worker             , fWH(wh)
498*c8dee2aaSAndroid Build Coastguard Worker             , fID(id)
499*c8dee2aaSAndroid Build Coastguard Worker             , fFailFillingIn(failFillingIn)
500*c8dee2aaSAndroid Build Coastguard Worker             , fIsNewerBetter(isNewerBetter) {
501*c8dee2aaSAndroid Build Coastguard Worker         this->setBounds(SkRect::MakeIWH(fWH, fWH), HasAABloat::kNo, IsHairline::kNo);
502*c8dee2aaSAndroid Build Coastguard Worker 
503*c8dee2aaSAndroid Build Coastguard Worker         // Normally we wouldn't add a ref to the vertex data at this point. However, it is
504*c8dee2aaSAndroid Build Coastguard Worker         // needed in this unit test to get the ref counts on the uniquely keyed resources
505*c8dee2aaSAndroid Build Coastguard Worker         // to be as expected.
506*c8dee2aaSAndroid Build Coastguard Worker         this->findOrCreateVertices(rContext, failLookup, fFailFillingIn);
507*c8dee2aaSAndroid Build Coastguard Worker     }
508*c8dee2aaSAndroid Build Coastguard Worker 
name() const509*c8dee2aaSAndroid Build Coastguard Worker     const char* name() const override { return "GrThreadSafeVertexTestOp"; }
fixedFunctionFlags() const510*c8dee2aaSAndroid Build Coastguard Worker     FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
finalize(const GrCaps &,const GrAppliedClip *,GrClampType)511*c8dee2aaSAndroid Build Coastguard Worker     GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override {
512*c8dee2aaSAndroid Build Coastguard Worker         return GrProcessorSet::EmptySetAnalysis();
513*c8dee2aaSAndroid Build Coastguard Worker     }
514*c8dee2aaSAndroid Build Coastguard Worker 
createProgramInfo(const GrCaps * caps,SkArenaAlloc * arena,const GrSurfaceProxyView & writeView,bool usesMSAASurface,GrAppliedClip && appliedClip,const GrDstProxyView & dstProxyView,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp) const515*c8dee2aaSAndroid Build Coastguard Worker     GrProgramInfo* createProgramInfo(const GrCaps* caps,
516*c8dee2aaSAndroid Build Coastguard Worker                                      SkArenaAlloc* arena,
517*c8dee2aaSAndroid Build Coastguard Worker                                      const GrSurfaceProxyView& writeView,
518*c8dee2aaSAndroid Build Coastguard Worker                                      bool usesMSAASurface,
519*c8dee2aaSAndroid Build Coastguard Worker                                      GrAppliedClip&& appliedClip,
520*c8dee2aaSAndroid Build Coastguard Worker                                      const GrDstProxyView& dstProxyView,
521*c8dee2aaSAndroid Build Coastguard Worker                                      GrXferBarrierFlags renderPassXferBarriers,
522*c8dee2aaSAndroid Build Coastguard Worker                                      GrLoadOp colorLoadOp) const {
523*c8dee2aaSAndroid Build Coastguard Worker         using namespace GrDefaultGeoProcFactory;
524*c8dee2aaSAndroid Build Coastguard Worker 
525*c8dee2aaSAndroid Build Coastguard Worker         Color color({ 0.0f, 0.0f, 1.0f, 1.0f });
526*c8dee2aaSAndroid Build Coastguard Worker 
527*c8dee2aaSAndroid Build Coastguard Worker         auto gp = MakeForDeviceSpace(arena, color,
528*c8dee2aaSAndroid Build Coastguard Worker                                      Coverage::kSolid_Type,
529*c8dee2aaSAndroid Build Coastguard Worker                                      LocalCoords::kUnused_Type,
530*c8dee2aaSAndroid Build Coastguard Worker                                      SkMatrix::I());
531*c8dee2aaSAndroid Build Coastguard Worker 
532*c8dee2aaSAndroid Build Coastguard Worker         return sk_gpu_test::CreateProgramInfo(caps, arena, writeView, usesMSAASurface,
533*c8dee2aaSAndroid Build Coastguard Worker                                               std::move(appliedClip), dstProxyView,
534*c8dee2aaSAndroid Build Coastguard Worker                                               gp, SkBlendMode::kSrcOver,
535*c8dee2aaSAndroid Build Coastguard Worker                                               GrPrimitiveType::kTriangleStrip,
536*c8dee2aaSAndroid Build Coastguard Worker                                               renderPassXferBarriers, colorLoadOp);
537*c8dee2aaSAndroid Build Coastguard Worker     }
538*c8dee2aaSAndroid Build Coastguard Worker 
createProgramInfo(GrOpFlushState * flushState) const539*c8dee2aaSAndroid Build Coastguard Worker     GrProgramInfo* createProgramInfo(GrOpFlushState* flushState) const {
540*c8dee2aaSAndroid Build Coastguard Worker         return this->createProgramInfo(&flushState->caps(),
541*c8dee2aaSAndroid Build Coastguard Worker                                        flushState->allocator(),
542*c8dee2aaSAndroid Build Coastguard Worker                                        flushState->writeView(),
543*c8dee2aaSAndroid Build Coastguard Worker                                        flushState->usesMSAASurface(),
544*c8dee2aaSAndroid Build Coastguard Worker                                        flushState->detachAppliedClip(),
545*c8dee2aaSAndroid Build Coastguard Worker                                        flushState->dstProxyView(),
546*c8dee2aaSAndroid Build Coastguard Worker                                        flushState->renderPassBarriers(),
547*c8dee2aaSAndroid Build Coastguard Worker                                        flushState->colorLoadOp());
548*c8dee2aaSAndroid Build Coastguard Worker     }
549*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateVertices(GrRecordingContext * rContext,bool failLookup,bool failFillingIn)550*c8dee2aaSAndroid Build Coastguard Worker     void findOrCreateVertices(GrRecordingContext* rContext, bool failLookup, bool failFillingIn) {
551*c8dee2aaSAndroid Build Coastguard Worker 
552*c8dee2aaSAndroid Build Coastguard Worker         if (!fVertexData) {
553*c8dee2aaSAndroid Build Coastguard Worker             auto threadSafeViewCache = rContext->priv().threadSafeCache();
554*c8dee2aaSAndroid Build Coastguard Worker 
555*c8dee2aaSAndroid Build Coastguard Worker             if (rContext->asDirectContext()) {
556*c8dee2aaSAndroid Build Coastguard Worker                 // The vertex variant doesn't have a correlate to lazyProxies but increment this
557*c8dee2aaSAndroid Build Coastguard Worker                 // here to make the unit tests happy.
558*c8dee2aaSAndroid Build Coastguard Worker                 ++fStats->fNumLazyCreations;
559*c8dee2aaSAndroid Build Coastguard Worker             }
560*c8dee2aaSAndroid Build Coastguard Worker 
561*c8dee2aaSAndroid Build Coastguard Worker             skgpu::UniqueKey key;
562*c8dee2aaSAndroid Build Coastguard Worker             create_vert_key(&key, fWH, fID);
563*c8dee2aaSAndroid Build Coastguard Worker 
564*c8dee2aaSAndroid Build Coastguard Worker             // We can "fail the lookup" to simulate a threaded race condition
565*c8dee2aaSAndroid Build Coastguard Worker             auto [cachedVerts, data] = threadSafeViewCache->findVertsWithData(key);
566*c8dee2aaSAndroid Build Coastguard Worker             if (cachedVerts && !failLookup) {
567*c8dee2aaSAndroid Build Coastguard Worker                 fVertexData = cachedVerts;
568*c8dee2aaSAndroid Build Coastguard Worker                 ++fStats->fCacheHits;
569*c8dee2aaSAndroid Build Coastguard Worker                 return;
570*c8dee2aaSAndroid Build Coastguard Worker             }
571*c8dee2aaSAndroid Build Coastguard Worker 
572*c8dee2aaSAndroid Build Coastguard Worker             ++fStats->fCacheMisses;
573*c8dee2aaSAndroid Build Coastguard Worker             if (!rContext->asDirectContext()) {
574*c8dee2aaSAndroid Build Coastguard Worker                 ++fStats->fNumSWCreations;
575*c8dee2aaSAndroid Build Coastguard Worker             }
576*c8dee2aaSAndroid Build Coastguard Worker 
577*c8dee2aaSAndroid Build Coastguard Worker             constexpr size_t kVertSize = sizeof(SkPoint);
578*c8dee2aaSAndroid Build Coastguard Worker             SkPoint* verts = static_cast<SkPoint*>(sk_malloc_throw(4 * kVertSize));
579*c8dee2aaSAndroid Build Coastguard Worker 
580*c8dee2aaSAndroid Build Coastguard Worker             verts[0].set(10.0f, 10.0f);
581*c8dee2aaSAndroid Build Coastguard Worker             verts[1].set(fWH-10.0f, 10.0f);
582*c8dee2aaSAndroid Build Coastguard Worker             verts[2].set(10.0f, fWH-10.0f);
583*c8dee2aaSAndroid Build Coastguard Worker             verts[3].set(fWH-10.0f, fWH-10.0f);
584*c8dee2aaSAndroid Build Coastguard Worker 
585*c8dee2aaSAndroid Build Coastguard Worker             fVertexData = GrThreadSafeCache::MakeVertexData(verts, 4, kVertSize);
586*c8dee2aaSAndroid Build Coastguard Worker 
587*c8dee2aaSAndroid Build Coastguard Worker             auto [tmpV, tmpD] = threadSafeViewCache->addVertsWithData(key, fVertexData,
588*c8dee2aaSAndroid Build Coastguard Worker                                                                       fIsNewerBetter);
589*c8dee2aaSAndroid Build Coastguard Worker             if (tmpV != fVertexData) {
590*c8dee2aaSAndroid Build Coastguard Worker                 // Someone beat us to creating the vertex data. Use that version.
591*c8dee2aaSAndroid Build Coastguard Worker                 fVertexData = tmpV;
592*c8dee2aaSAndroid Build Coastguard Worker             }
593*c8dee2aaSAndroid Build Coastguard Worker         }
594*c8dee2aaSAndroid Build Coastguard Worker 
595*c8dee2aaSAndroid Build Coastguard Worker         if (auto dContext = rContext->asDirectContext(); dContext && !fVertexData->gpuBuffer()) {
596*c8dee2aaSAndroid Build Coastguard Worker             auto rp = dContext->priv().resourceProvider();
597*c8dee2aaSAndroid Build Coastguard Worker 
598*c8dee2aaSAndroid Build Coastguard Worker             if (!failFillingIn) {
599*c8dee2aaSAndroid Build Coastguard Worker                 ++fStats->fNumHWCreations;
600*c8dee2aaSAndroid Build Coastguard Worker 
601*c8dee2aaSAndroid Build Coastguard Worker                 sk_sp<GrGpuBuffer> tmp = rp->createBuffer(fVertexData->vertices(),
602*c8dee2aaSAndroid Build Coastguard Worker                                                           fVertexData->size(),
603*c8dee2aaSAndroid Build Coastguard Worker                                                           GrGpuBufferType::kVertex,
604*c8dee2aaSAndroid Build Coastguard Worker                                                           kStatic_GrAccessPattern);
605*c8dee2aaSAndroid Build Coastguard Worker                 fVertexData->setGpuBuffer(std::move(tmp));
606*c8dee2aaSAndroid Build Coastguard Worker             }
607*c8dee2aaSAndroid Build Coastguard Worker         }
608*c8dee2aaSAndroid Build Coastguard Worker     }
609*c8dee2aaSAndroid Build Coastguard Worker 
onPrePrepare(GrRecordingContext * rContext,const GrSurfaceProxyView & writeView,GrAppliedClip * clip,const GrDstProxyView & dstProxyView,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp)610*c8dee2aaSAndroid Build Coastguard Worker     void onPrePrepare(GrRecordingContext* rContext,
611*c8dee2aaSAndroid Build Coastguard Worker                       const GrSurfaceProxyView& writeView,
612*c8dee2aaSAndroid Build Coastguard Worker                       GrAppliedClip* clip,
613*c8dee2aaSAndroid Build Coastguard Worker                       const GrDstProxyView& dstProxyView,
614*c8dee2aaSAndroid Build Coastguard Worker                       GrXferBarrierFlags renderPassXferBarriers,
615*c8dee2aaSAndroid Build Coastguard Worker                       GrLoadOp colorLoadOp) override {
616*c8dee2aaSAndroid Build Coastguard Worker         SkArenaAlloc* arena = rContext->priv().recordTimeAllocator();
617*c8dee2aaSAndroid Build Coastguard Worker 
618*c8dee2aaSAndroid Build Coastguard Worker         // DMSAA is not supported on DDL.
619*c8dee2aaSAndroid Build Coastguard Worker         bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
620*c8dee2aaSAndroid Build Coastguard Worker 
621*c8dee2aaSAndroid Build Coastguard Worker         // This is equivalent to a GrOpFlushState::detachAppliedClip
622*c8dee2aaSAndroid Build Coastguard Worker         GrAppliedClip appliedClip = clip ? std::move(*clip) : GrAppliedClip::Disabled();
623*c8dee2aaSAndroid Build Coastguard Worker 
624*c8dee2aaSAndroid Build Coastguard Worker         fProgramInfo = this->createProgramInfo(rContext->priv().caps(), arena, writeView,
625*c8dee2aaSAndroid Build Coastguard Worker                                                usesMSAASurface, std::move(appliedClip),
626*c8dee2aaSAndroid Build Coastguard Worker                                                dstProxyView, renderPassXferBarriers, colorLoadOp);
627*c8dee2aaSAndroid Build Coastguard Worker 
628*c8dee2aaSAndroid Build Coastguard Worker         rContext->priv().recordProgramInfo(fProgramInfo);
629*c8dee2aaSAndroid Build Coastguard Worker 
630*c8dee2aaSAndroid Build Coastguard Worker         // This is now a noop (bc it is always called in the ctor) but is where we would normally
631*c8dee2aaSAndroid Build Coastguard Worker         // create the vertices.
632*c8dee2aaSAndroid Build Coastguard Worker         this->findOrCreateVertices(rContext, false, fFailFillingIn);
633*c8dee2aaSAndroid Build Coastguard Worker     }
634*c8dee2aaSAndroid Build Coastguard Worker 
onPrepare(GrOpFlushState * flushState)635*c8dee2aaSAndroid Build Coastguard Worker     void onPrepare(GrOpFlushState* flushState) override {
636*c8dee2aaSAndroid Build Coastguard Worker         auto dContext = flushState->gpu()->getContext();
637*c8dee2aaSAndroid Build Coastguard Worker 
638*c8dee2aaSAndroid Build Coastguard Worker         // This call site is not a noop bc this op could've been created on with DDL context
639*c8dee2aaSAndroid Build Coastguard Worker         // and, therefore, could be lacking a gpu-side buffer
640*c8dee2aaSAndroid Build Coastguard Worker         this->findOrCreateVertices(dContext, false, fFailFillingIn);
641*c8dee2aaSAndroid Build Coastguard Worker     }
642*c8dee2aaSAndroid Build Coastguard Worker 
onExecute(GrOpFlushState * flushState,const SkRect & chainBounds)643*c8dee2aaSAndroid Build Coastguard Worker     void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
644*c8dee2aaSAndroid Build Coastguard Worker         if (!fVertexData || !fVertexData->gpuBuffer()) {
645*c8dee2aaSAndroid Build Coastguard Worker             return;
646*c8dee2aaSAndroid Build Coastguard Worker         }
647*c8dee2aaSAndroid Build Coastguard Worker 
648*c8dee2aaSAndroid Build Coastguard Worker         if (!fProgramInfo) {
649*c8dee2aaSAndroid Build Coastguard Worker             fProgramInfo = this->createProgramInfo(flushState);
650*c8dee2aaSAndroid Build Coastguard Worker         }
651*c8dee2aaSAndroid Build Coastguard Worker 
652*c8dee2aaSAndroid Build Coastguard Worker         flushState->bindPipeline(*fProgramInfo, SkRect::MakeIWH(fWH, fWH));
653*c8dee2aaSAndroid Build Coastguard Worker         flushState->bindBuffers(nullptr, nullptr, fVertexData->refGpuBuffer());
654*c8dee2aaSAndroid Build Coastguard Worker         flushState->draw(4, 0);
655*c8dee2aaSAndroid Build Coastguard Worker     }
656*c8dee2aaSAndroid Build Coastguard Worker 
657*c8dee2aaSAndroid Build Coastguard Worker     TestHelper::Stats*               fStats;
658*c8dee2aaSAndroid Build Coastguard Worker     int                              fWH;
659*c8dee2aaSAndroid Build Coastguard Worker     int                              fID;
660*c8dee2aaSAndroid Build Coastguard Worker     bool                             fFailFillingIn;
661*c8dee2aaSAndroid Build Coastguard Worker     GrThreadSafeCache::IsNewerBetter fIsNewerBetter;
662*c8dee2aaSAndroid Build Coastguard Worker 
663*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrThreadSafeCache::VertexData> fVertexData;
664*c8dee2aaSAndroid Build Coastguard Worker     GrProgramInfo*                   fProgramInfo = nullptr;
665*c8dee2aaSAndroid Build Coastguard Worker 
666*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = GrDrawOp;
667*c8dee2aaSAndroid Build Coastguard Worker };
668*c8dee2aaSAndroid Build Coastguard Worker 
addVertAccess(SkCanvas * canvas,int wh,int id,bool failLookup,bool failFillingIn,GrThreadSafeVertexTestOp ** createdOp)669*c8dee2aaSAndroid Build Coastguard Worker void TestHelper::addVertAccess(SkCanvas* canvas,
670*c8dee2aaSAndroid Build Coastguard Worker                                int wh, int id,
671*c8dee2aaSAndroid Build Coastguard Worker                                bool failLookup, bool failFillingIn,
672*c8dee2aaSAndroid Build Coastguard Worker                                GrThreadSafeVertexTestOp** createdOp) {
673*c8dee2aaSAndroid Build Coastguard Worker     auto rContext = canvas->recordingContext();
674*c8dee2aaSAndroid Build Coastguard Worker     auto sdc = skgpu::ganesh::TopDeviceSurfaceDrawContext(canvas);
675*c8dee2aaSAndroid Build Coastguard Worker 
676*c8dee2aaSAndroid Build Coastguard Worker     GrOp::Owner op = GrThreadSafeVertexTestOp::Make(rContext, &fStats,
677*c8dee2aaSAndroid Build Coastguard Worker                                                     wh, id,
678*c8dee2aaSAndroid Build Coastguard Worker                                                     failLookup, failFillingIn,
679*c8dee2aaSAndroid Build Coastguard Worker                                                     fIsNewerBetter);
680*c8dee2aaSAndroid Build Coastguard Worker     if (createdOp) {
681*c8dee2aaSAndroid Build Coastguard Worker         *createdOp = (GrThreadSafeVertexTestOp*) op.get();
682*c8dee2aaSAndroid Build Coastguard Worker     }
683*c8dee2aaSAndroid Build Coastguard Worker 
684*c8dee2aaSAndroid Build Coastguard Worker     sdc->addDrawOp(std::move(op));
685*c8dee2aaSAndroid Build Coastguard Worker }
686*c8dee2aaSAndroid Build Coastguard Worker 
CreateViewOnCpu(GrRecordingContext * rContext,int wh,Stats * stats)687*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceProxyView TestHelper::CreateViewOnCpu(GrRecordingContext* rContext,
688*c8dee2aaSAndroid Build Coastguard Worker                                                int wh,
689*c8dee2aaSAndroid Build Coastguard Worker                                                Stats* stats) {
690*c8dee2aaSAndroid Build Coastguard Worker     GrProxyProvider* proxyProvider = rContext->priv().proxyProvider();
691*c8dee2aaSAndroid Build Coastguard Worker 
692*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrTextureProxy> proxy = proxyProvider->createProxyFromBitmap(
693*c8dee2aaSAndroid Build Coastguard Worker             create_bitmap(wh), skgpu::Mipmapped::kNo, SkBackingFit::kExact, skgpu::Budgeted::kYes);
694*c8dee2aaSAndroid Build Coastguard Worker     if (!proxy) {
695*c8dee2aaSAndroid Build Coastguard Worker         return {};
696*c8dee2aaSAndroid Build Coastguard Worker     }
697*c8dee2aaSAndroid Build Coastguard Worker 
698*c8dee2aaSAndroid Build Coastguard Worker     skgpu::Swizzle swizzle = rContext->priv().caps()->getReadSwizzle(proxy->backendFormat(),
699*c8dee2aaSAndroid Build Coastguard Worker                                                                      GrColorType::kRGBA_8888);
700*c8dee2aaSAndroid Build Coastguard Worker     ++stats->fNumSWCreations;
701*c8dee2aaSAndroid Build Coastguard Worker     return {std::move(proxy), kImageOrigin, swizzle};
702*c8dee2aaSAndroid Build Coastguard Worker }
703*c8dee2aaSAndroid Build Coastguard Worker 
FillInViewOnGpu(GrDirectContext * dContext,int wh,Stats * stats,const GrSurfaceProxyView & lazyView,sk_sp<GrThreadSafeCache::Trampoline> trampoline)704*c8dee2aaSAndroid Build Coastguard Worker bool TestHelper::FillInViewOnGpu(GrDirectContext* dContext, int wh, Stats* stats,
705*c8dee2aaSAndroid Build Coastguard Worker                                  const GrSurfaceProxyView& lazyView,
706*c8dee2aaSAndroid Build Coastguard Worker                                  sk_sp<GrThreadSafeCache::Trampoline> trampoline) {
707*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<skgpu::ganesh::SurfaceDrawContext> sdc = new_SDC(dContext, wh);
708*c8dee2aaSAndroid Build Coastguard Worker 
709*c8dee2aaSAndroid Build Coastguard Worker     GrPaint paint;
710*c8dee2aaSAndroid Build Coastguard Worker     paint.setColor4f({0.0f, 0.0f, 1.0f, 1.0f});
711*c8dee2aaSAndroid Build Coastguard Worker 
712*c8dee2aaSAndroid Build Coastguard Worker     sdc->clear(SkPMColor4f{1.0f, 1.0f, 1.0f, 1.0f});
713*c8dee2aaSAndroid Build Coastguard Worker     sdc->drawRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
714*c8dee2aaSAndroid Build Coastguard Worker                   { 10, 10, wh-10.0f, wh-10.0f }, &GrStyle::SimpleFill());
715*c8dee2aaSAndroid Build Coastguard Worker 
716*c8dee2aaSAndroid Build Coastguard Worker     ++stats->fNumHWCreations;
717*c8dee2aaSAndroid Build Coastguard Worker     auto view = sdc->readSurfaceView();
718*c8dee2aaSAndroid Build Coastguard Worker 
719*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(view.swizzle() == lazyView.swizzle());
720*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(view.origin() == lazyView.origin());
721*c8dee2aaSAndroid Build Coastguard Worker     trampoline->fProxy = view.asTextureProxyRef();
722*c8dee2aaSAndroid Build Coastguard Worker 
723*c8dee2aaSAndroid Build Coastguard Worker     return true;
724*c8dee2aaSAndroid Build Coastguard Worker }
725*c8dee2aaSAndroid Build Coastguard Worker 
AccessCachedView(GrRecordingContext * rContext,GrThreadSafeCache * threadSafeCache,int wh,bool failLookup,bool failFillingIn,int id,Stats * stats)726*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceProxyView TestHelper::AccessCachedView(GrRecordingContext* rContext,
727*c8dee2aaSAndroid Build Coastguard Worker                                                 GrThreadSafeCache* threadSafeCache,
728*c8dee2aaSAndroid Build Coastguard Worker                                                 int wh,
729*c8dee2aaSAndroid Build Coastguard Worker                                                 bool failLookup, bool failFillingIn, int id,
730*c8dee2aaSAndroid Build Coastguard Worker                                                 Stats* stats) {
731*c8dee2aaSAndroid Build Coastguard Worker     skgpu::UniqueKey key;
732*c8dee2aaSAndroid Build Coastguard Worker     create_view_key(&key, wh, id);
733*c8dee2aaSAndroid Build Coastguard Worker 
734*c8dee2aaSAndroid Build Coastguard Worker     if (GrDirectContext* dContext = rContext->asDirectContext()) {
735*c8dee2aaSAndroid Build Coastguard Worker         // The gpu thread gets priority over the recording threads. If the gpu thread is first,
736*c8dee2aaSAndroid Build Coastguard Worker         // it crams a lazy proxy into the cache and then fills it in later.
737*c8dee2aaSAndroid Build Coastguard Worker         auto [lazyView, trampoline] = GrThreadSafeCache::CreateLazyView(
738*c8dee2aaSAndroid Build Coastguard Worker             dContext, GrColorType::kRGBA_8888, {wh, wh}, kImageOrigin, SkBackingFit::kExact);
739*c8dee2aaSAndroid Build Coastguard Worker         ++stats->fNumLazyCreations;
740*c8dee2aaSAndroid Build Coastguard Worker 
741*c8dee2aaSAndroid Build Coastguard Worker         auto [view, data] = threadSafeCache->findOrAddWithData(key, lazyView);
742*c8dee2aaSAndroid Build Coastguard Worker         if (view != lazyView) {
743*c8dee2aaSAndroid Build Coastguard Worker             ++stats->fCacheHits;
744*c8dee2aaSAndroid Build Coastguard Worker             return view;
745*c8dee2aaSAndroid Build Coastguard Worker         } else if (id != kNoID) {
746*c8dee2aaSAndroid Build Coastguard Worker             // Make sure, in this case, that the customData stuck
747*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(data);
748*c8dee2aaSAndroid Build Coastguard Worker             SkDEBUGCODE(const int* cachedID = static_cast<const int*>(data->data());)
749*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(*cachedID == id);
750*c8dee2aaSAndroid Build Coastguard Worker         }
751*c8dee2aaSAndroid Build Coastguard Worker 
752*c8dee2aaSAndroid Build Coastguard Worker         ++stats->fCacheMisses;
753*c8dee2aaSAndroid Build Coastguard Worker 
754*c8dee2aaSAndroid Build Coastguard Worker         if (failFillingIn) {
755*c8dee2aaSAndroid Build Coastguard Worker             // Simulate something going horribly wrong at flush-time so no GrTexture is
756*c8dee2aaSAndroid Build Coastguard Worker             // available to fulfill the lazy proxy.
757*c8dee2aaSAndroid Build Coastguard Worker             return view;
758*c8dee2aaSAndroid Build Coastguard Worker         }
759*c8dee2aaSAndroid Build Coastguard Worker 
760*c8dee2aaSAndroid Build Coastguard Worker         if (!FillInViewOnGpu(dContext, wh, stats, lazyView, std::move(trampoline))) {
761*c8dee2aaSAndroid Build Coastguard Worker             // In this case something has gone disastrously wrong so set up to drop the draw
762*c8dee2aaSAndroid Build Coastguard Worker             // that needed this resource and reduce future pollution of the cache.
763*c8dee2aaSAndroid Build Coastguard Worker             threadSafeCache->remove(key);
764*c8dee2aaSAndroid Build Coastguard Worker             return {};
765*c8dee2aaSAndroid Build Coastguard Worker         }
766*c8dee2aaSAndroid Build Coastguard Worker 
767*c8dee2aaSAndroid Build Coastguard Worker         return view;
768*c8dee2aaSAndroid Build Coastguard Worker     } else {
769*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceProxyView view;
770*c8dee2aaSAndroid Build Coastguard Worker 
771*c8dee2aaSAndroid Build Coastguard Worker         // We can "fail the lookup" to simulate a threaded race condition
772*c8dee2aaSAndroid Build Coastguard Worker         if (view = threadSafeCache->find(key); !failLookup && view) {
773*c8dee2aaSAndroid Build Coastguard Worker             ++stats->fCacheHits;
774*c8dee2aaSAndroid Build Coastguard Worker             return view;
775*c8dee2aaSAndroid Build Coastguard Worker         }
776*c8dee2aaSAndroid Build Coastguard Worker 
777*c8dee2aaSAndroid Build Coastguard Worker         ++stats->fCacheMisses;
778*c8dee2aaSAndroid Build Coastguard Worker 
779*c8dee2aaSAndroid Build Coastguard Worker         view = CreateViewOnCpu(rContext, wh, stats);
780*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(view);
781*c8dee2aaSAndroid Build Coastguard Worker 
782*c8dee2aaSAndroid Build Coastguard Worker         auto [newView, data] = threadSafeCache->addWithData(key, view);
783*c8dee2aaSAndroid Build Coastguard Worker         if (view == newView && id != kNoID) {
784*c8dee2aaSAndroid Build Coastguard Worker             // Make sure, in this case, that the customData stuck
785*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(data);
786*c8dee2aaSAndroid Build Coastguard Worker             SkDEBUGCODE(const int* cachedID = static_cast<const int*>(data->data());)
787*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(*cachedID == id);
788*c8dee2aaSAndroid Build Coastguard Worker         }
789*c8dee2aaSAndroid Build Coastguard Worker         return newView;
790*c8dee2aaSAndroid Build Coastguard Worker     }
791*c8dee2aaSAndroid Build Coastguard Worker }
792*c8dee2aaSAndroid Build Coastguard Worker 
793*c8dee2aaSAndroid Build Coastguard Worker // Case 1: ensure two DDL recorders share the view/vertexData
test_1(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)794*c8dee2aaSAndroid Build Coastguard Worker static void test_1(GrDirectContext* dContext, skiatest::Reporter* reporter,
795*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::addAccessFP addAccess,
796*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::checkFP check) {
797*c8dee2aaSAndroid Build Coastguard Worker 
798*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
799*c8dee2aaSAndroid Build Coastguard Worker 
800*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, 1, false, false);
801*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
802*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, /*id*/ 1));
803*c8dee2aaSAndroid Build Coastguard Worker 
804*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas2(), kImageWH, 2, false, false);
805*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas2(), kImageWH,
806*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 2, /*id*/ 1));
807*c8dee2aaSAndroid Build Coastguard Worker 
808*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
809*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumLazyCreations == 0);
810*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumHWCreations == 0);
811*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumSWCreations == 1);
812*c8dee2aaSAndroid Build Coastguard Worker 
813*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, helper.snap1());
814*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, helper.snap2());
815*c8dee2aaSAndroid Build Coastguard Worker }
816*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache1View,reporter,ctxInfo,CtsEnforcement::kNever)817*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache1View,
818*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
819*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
820*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
821*c8dee2aaSAndroid Build Coastguard Worker     test_1(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
822*c8dee2aaSAndroid Build Coastguard Worker }
823*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache1Verts,reporter,ctxInfo,CtsEnforcement::kNever)824*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache1Verts,
825*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
826*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
827*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
828*c8dee2aaSAndroid Build Coastguard Worker     test_1(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
829*c8dee2aaSAndroid Build Coastguard Worker }
830*c8dee2aaSAndroid Build Coastguard Worker 
831*c8dee2aaSAndroid Build Coastguard Worker // Case 2: ensure that, if the direct context version wins, its result is reused by the
832*c8dee2aaSAndroid Build Coastguard Worker //         DDL recorders
test_2(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)833*c8dee2aaSAndroid Build Coastguard Worker static void test_2(GrDirectContext* dContext, skiatest::Reporter* reporter,
834*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::addAccessFP addAccess,
835*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::checkFP check) {
836*c8dee2aaSAndroid Build Coastguard Worker 
837*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
838*c8dee2aaSAndroid Build Coastguard Worker 
839*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), kImageWH, 1, false, false);
840*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
841*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, /*id*/ 1));
842*c8dee2aaSAndroid Build Coastguard Worker 
843*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, 2, false, false);
844*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
845*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 2, /*id*/ 1));
846*c8dee2aaSAndroid Build Coastguard Worker 
847*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas2(), kImageWH, 3, false, false);
848*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas2(), kImageWH,
849*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 2, /*misses*/ 1, /*refs*/ 3, /*id*/ 1));
850*c8dee2aaSAndroid Build Coastguard Worker 
851*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
852*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumLazyCreations == 1);
853*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumHWCreations == 1);
854*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumSWCreations == 0);
855*c8dee2aaSAndroid Build Coastguard Worker 
856*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter);
857*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, helper.snap1());
858*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, helper.snap2());
859*c8dee2aaSAndroid Build Coastguard Worker }
860*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache2View,reporter,ctxInfo,CtsEnforcement::kNever)861*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache2View,
862*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
863*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
864*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
865*c8dee2aaSAndroid Build Coastguard Worker     test_2(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
866*c8dee2aaSAndroid Build Coastguard Worker }
867*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache2Verts,reporter,ctxInfo,CtsEnforcement::kNever)868*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache2Verts,
869*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
870*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
871*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
872*c8dee2aaSAndroid Build Coastguard Worker     test_2(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
873*c8dee2aaSAndroid Build Coastguard Worker }
874*c8dee2aaSAndroid Build Coastguard Worker 
875*c8dee2aaSAndroid Build Coastguard Worker // Case 3: ensure that, if the cpu-version wins, its result is reused by the direct context
test_3(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)876*c8dee2aaSAndroid Build Coastguard Worker static void test_3(GrDirectContext* dContext, skiatest::Reporter* reporter,
877*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::addAccessFP addAccess,
878*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::checkFP check) {
879*c8dee2aaSAndroid Build Coastguard Worker 
880*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
881*c8dee2aaSAndroid Build Coastguard Worker 
882*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, 1, false, false);
883*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
884*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, /*id*/ 1));
885*c8dee2aaSAndroid Build Coastguard Worker 
886*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), kImageWH, 2, false, false);
887*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
888*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 2, /*id*/ 1));
889*c8dee2aaSAndroid Build Coastguard Worker 
890*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
891*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumLazyCreations == 1);
892*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumHWCreations == 0);
893*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumSWCreations == 1);
894*c8dee2aaSAndroid Build Coastguard Worker 
895*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter);
896*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, helper.snap1());
897*c8dee2aaSAndroid Build Coastguard Worker }
898*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache3View,reporter,ctxInfo,CtsEnforcement::kNever)899*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache3View,
900*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
901*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
902*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
903*c8dee2aaSAndroid Build Coastguard Worker     test_3(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
904*c8dee2aaSAndroid Build Coastguard Worker }
905*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache3Verts,reporter,ctxInfo,CtsEnforcement::kNever)906*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache3Verts,
907*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
908*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
909*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
910*c8dee2aaSAndroid Build Coastguard Worker     test_3(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
911*c8dee2aaSAndroid Build Coastguard Worker }
912*c8dee2aaSAndroid Build Coastguard Worker 
913*c8dee2aaSAndroid Build Coastguard Worker // Case 4: ensure that, if two DDL recorders get in a race, they still end up sharing a single
914*c8dee2aaSAndroid Build Coastguard Worker //         view/vertexData
test_4(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)915*c8dee2aaSAndroid Build Coastguard Worker static void test_4(GrDirectContext* dContext, skiatest::Reporter* reporter,
916*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::addAccessFP addAccess,
917*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::checkFP check) {
918*c8dee2aaSAndroid Build Coastguard Worker 
919*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
920*c8dee2aaSAndroid Build Coastguard Worker 
921*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, 1, false, false);
922*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
923*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, /*id*/ 1));
924*c8dee2aaSAndroid Build Coastguard Worker 
925*c8dee2aaSAndroid Build Coastguard Worker     static const bool kFailLookup = true;
926*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas2(), kImageWH, 2, kFailLookup, false);
927*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas2(), kImageWH,
928*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 2, /*refs*/ 2, /*id*/ 1));
929*c8dee2aaSAndroid Build Coastguard Worker 
930*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
931*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumLazyCreations == 0);
932*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumHWCreations == 0);
933*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumSWCreations == 2);
934*c8dee2aaSAndroid Build Coastguard Worker 
935*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, helper.snap1());
936*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, helper.snap2());
937*c8dee2aaSAndroid Build Coastguard Worker }
938*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4View,reporter,ctxInfo,CtsEnforcement::kNever)939*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4View,
940*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
941*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
942*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
943*c8dee2aaSAndroid Build Coastguard Worker     test_4(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
944*c8dee2aaSAndroid Build Coastguard Worker }
945*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4Verts,reporter,ctxInfo,CtsEnforcement::kNever)946*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4Verts,
947*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
948*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
949*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
950*c8dee2aaSAndroid Build Coastguard Worker     test_4(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
951*c8dee2aaSAndroid Build Coastguard Worker }
952*c8dee2aaSAndroid Build Coastguard Worker 
953*c8dee2aaSAndroid Build Coastguard Worker // Case 4.5: check that, if a live rendering and a DDL recording get into a race, the live
954*c8dee2aaSAndroid Build Coastguard Worker //           rendering takes precedence.
test_4_5(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)955*c8dee2aaSAndroid Build Coastguard Worker static void test_4_5(GrDirectContext* dContext, skiatest::Reporter* reporter,
956*c8dee2aaSAndroid Build Coastguard Worker                      TestHelper::addAccessFP addAccess,
957*c8dee2aaSAndroid Build Coastguard Worker                      TestHelper::checkFP check) {
958*c8dee2aaSAndroid Build Coastguard Worker 
959*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
960*c8dee2aaSAndroid Build Coastguard Worker 
961*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), kImageWH, 1, false, false);
962*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
963*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, /*id*/ 1));
964*c8dee2aaSAndroid Build Coastguard Worker 
965*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
966*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumLazyCreations == 1);
967*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumHWCreations == 1);
968*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumSWCreations == 0);
969*c8dee2aaSAndroid Build Coastguard Worker 
970*c8dee2aaSAndroid Build Coastguard Worker     static const bool kFailLookup = true;
971*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, 2, kFailLookup, false);
972*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
973*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 2, /*refs*/ 2, /*id*/ 1));
974*c8dee2aaSAndroid Build Coastguard Worker 
975*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
976*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumLazyCreations == 1);
977*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumHWCreations == 1);
978*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumSWCreations == 1);
979*c8dee2aaSAndroid Build Coastguard Worker 
980*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter);
981*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, helper.snap1());
982*c8dee2aaSAndroid Build Coastguard Worker }
983*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4_5View,reporter,ctxInfo,CtsEnforcement::kNever)984*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4_5View,
985*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
986*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
987*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
988*c8dee2aaSAndroid Build Coastguard Worker     test_4_5(ctxInfo.directContext(), reporter,
989*c8dee2aaSAndroid Build Coastguard Worker              &TestHelper::addViewAccess, &TestHelper::checkView);
990*c8dee2aaSAndroid Build Coastguard Worker }
991*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4_5Verts,reporter,ctxInfo,CtsEnforcement::kNever)992*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4_5Verts,
993*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
994*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
995*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
996*c8dee2aaSAndroid Build Coastguard Worker     test_4_5(ctxInfo.directContext(), reporter,
997*c8dee2aaSAndroid Build Coastguard Worker              &TestHelper::addVertAccess, &TestHelper::checkVert);
998*c8dee2aaSAndroid Build Coastguard Worker }
999*c8dee2aaSAndroid Build Coastguard Worker 
1000*c8dee2aaSAndroid Build Coastguard Worker // Case 4.75: check that, if a live rendering fails to generate the content needed to instantiate
1001*c8dee2aaSAndroid Build Coastguard Worker //            its lazy proxy, life goes on
test_4_75(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)1002*c8dee2aaSAndroid Build Coastguard Worker static void test_4_75(GrDirectContext* dContext, skiatest::Reporter* reporter,
1003*c8dee2aaSAndroid Build Coastguard Worker                       TestHelper::addAccessFP addAccess,
1004*c8dee2aaSAndroid Build Coastguard Worker                       TestHelper::checkFP check) {
1005*c8dee2aaSAndroid Build Coastguard Worker 
1006*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1007*c8dee2aaSAndroid Build Coastguard Worker 
1008*c8dee2aaSAndroid Build Coastguard Worker     static const bool kFailFillingIn = true;
1009*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), kImageWH, kNoID, false, kFailFillingIn);
1010*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
1011*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1012*c8dee2aaSAndroid Build Coastguard Worker 
1013*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1014*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumLazyCreations == 1);
1015*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumHWCreations == 0);
1016*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumSWCreations == 0);
1017*c8dee2aaSAndroid Build Coastguard Worker 
1018*c8dee2aaSAndroid Build Coastguard Worker     dContext->flush();
1019*c8dee2aaSAndroid Build Coastguard Worker     dContext->submit(GrSyncCpu::kYes);
1020*c8dee2aaSAndroid Build Coastguard Worker 
1021*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
1022*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 0, kNoID));
1023*c8dee2aaSAndroid Build Coastguard Worker 
1024*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1025*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumLazyCreations == 1);
1026*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumHWCreations == 0);
1027*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumSWCreations == 0);
1028*c8dee2aaSAndroid Build Coastguard Worker }
1029*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4_75View,reporter,ctxInfo,CtsEnforcement::kNever)1030*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4_75View,
1031*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1032*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1033*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1034*c8dee2aaSAndroid Build Coastguard Worker     test_4_75(ctxInfo.directContext(), reporter,
1035*c8dee2aaSAndroid Build Coastguard Worker               &TestHelper::addViewAccess, &TestHelper::checkView);
1036*c8dee2aaSAndroid Build Coastguard Worker }
1037*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4_75Verts,reporter,ctxInfo,CtsEnforcement::kNever)1038*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache4_75Verts,
1039*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1040*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1041*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1042*c8dee2aaSAndroid Build Coastguard Worker     test_4_75(ctxInfo.directContext(), reporter,
1043*c8dee2aaSAndroid Build Coastguard Worker               &TestHelper::addVertAccess, &TestHelper::checkVert);
1044*c8dee2aaSAndroid Build Coastguard Worker }
1045*c8dee2aaSAndroid Build Coastguard Worker 
1046*c8dee2aaSAndroid Build Coastguard Worker // Case 5: ensure that expanding the map works (esp. wrt custom data)
test_5(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)1047*c8dee2aaSAndroid Build Coastguard Worker static void test_5(GrDirectContext* dContext, skiatest::Reporter* reporter,
1048*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::addAccessFP addAccess,
1049*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::checkFP check) {
1050*c8dee2aaSAndroid Build Coastguard Worker 
1051*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1052*c8dee2aaSAndroid Build Coastguard Worker 
1053*c8dee2aaSAndroid Build Coastguard Worker     auto threadSafeCache = helper.threadSafeCache();
1054*c8dee2aaSAndroid Build Coastguard Worker 
1055*c8dee2aaSAndroid Build Coastguard Worker     int size = 16;
1056*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), size, /*id*/ size, false, false);
1057*c8dee2aaSAndroid Build Coastguard Worker 
1058*c8dee2aaSAndroid Build Coastguard Worker     size_t initialSize = threadSafeCache->approxBytesUsedForHash();
1059*c8dee2aaSAndroid Build Coastguard Worker 
1060*c8dee2aaSAndroid Build Coastguard Worker     while (initialSize == threadSafeCache->approxBytesUsedForHash()) {
1061*c8dee2aaSAndroid Build Coastguard Worker         size *= 2;
1062*c8dee2aaSAndroid Build Coastguard Worker         (helper.*addAccess)(helper.ddlCanvas1(), size, /*id*/ size, false, false);
1063*c8dee2aaSAndroid Build Coastguard Worker     }
1064*c8dee2aaSAndroid Build Coastguard Worker 
1065*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 16; i <= size; i *= 2) {
1066*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(),
1067*c8dee2aaSAndroid Build Coastguard Worker                                                   /*wh*/ i,
1068*c8dee2aaSAndroid Build Coastguard Worker                                                   /*hits*/ 0,
1069*c8dee2aaSAndroid Build Coastguard Worker                                                   /*misses*/ threadSafeCache->numEntries(),
1070*c8dee2aaSAndroid Build Coastguard Worker                                                   /*refs*/ 1,
1071*c8dee2aaSAndroid Build Coastguard Worker                                                   /*id*/ i));
1072*c8dee2aaSAndroid Build Coastguard Worker     }
1073*c8dee2aaSAndroid Build Coastguard Worker }
1074*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache5View,reporter,ctxInfo,CtsEnforcement::kNever)1075*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache5View,
1076*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1077*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1078*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1079*c8dee2aaSAndroid Build Coastguard Worker     test_5(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
1080*c8dee2aaSAndroid Build Coastguard Worker }
1081*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache5Verts,reporter,ctxInfo,CtsEnforcement::kNever)1082*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache5Verts,
1083*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1084*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1085*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1086*c8dee2aaSAndroid Build Coastguard Worker     test_5(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
1087*c8dee2aaSAndroid Build Coastguard Worker }
1088*c8dee2aaSAndroid Build Coastguard Worker 
1089*c8dee2aaSAndroid Build Coastguard Worker // Case 6: Check on dropping refs. In particular, that the cache has its own ref to keep
1090*c8dee2aaSAndroid Build Coastguard Worker //         the backing resource alive and locked.
test_6(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)1091*c8dee2aaSAndroid Build Coastguard Worker static void test_6(GrDirectContext* dContext, skiatest::Reporter* reporter,
1092*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::addAccessFP addAccess,
1093*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::checkFP check) {
1094*c8dee2aaSAndroid Build Coastguard Worker 
1095*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1096*c8dee2aaSAndroid Build Coastguard Worker 
1097*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, kNoID, false, false);
1098*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl1 = helper.snap1();
1099*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(nullptr, kImageWH,
1100*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1101*c8dee2aaSAndroid Build Coastguard Worker 
1102*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas2(), kImageWH, kNoID, false, false);
1103*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl2 = helper.snap2();
1104*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(nullptr, kImageWH,
1105*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 2, kNoID));
1106*c8dee2aaSAndroid Build Coastguard Worker 
1107*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1108*c8dee2aaSAndroid Build Coastguard Worker 
1109*c8dee2aaSAndroid Build Coastguard Worker     ddl1 = nullptr;
1110*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(nullptr, kImageWH,
1111*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 1, kNoID));
1112*c8dee2aaSAndroid Build Coastguard Worker 
1113*c8dee2aaSAndroid Build Coastguard Worker     ddl2 = nullptr;
1114*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(nullptr, kImageWH,
1115*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 0, kNoID));
1116*c8dee2aaSAndroid Build Coastguard Worker 
1117*c8dee2aaSAndroid Build Coastguard Worker     // The cache still has its ref
1118*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1119*c8dee2aaSAndroid Build Coastguard Worker 
1120*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(nullptr, kImageWH,
1121*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 0, kNoID));
1122*c8dee2aaSAndroid Build Coastguard Worker }
1123*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache6View,reporter,ctxInfo,CtsEnforcement::kNever)1124*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache6View,
1125*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1126*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1127*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1128*c8dee2aaSAndroid Build Coastguard Worker     test_6(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
1129*c8dee2aaSAndroid Build Coastguard Worker }
1130*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache6Verts,reporter,ctxInfo,CtsEnforcement::kNever)1131*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache6Verts,
1132*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1133*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1134*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1135*c8dee2aaSAndroid Build Coastguard Worker     test_6(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
1136*c8dee2aaSAndroid Build Coastguard Worker }
1137*c8dee2aaSAndroid Build Coastguard Worker 
1138*c8dee2aaSAndroid Build Coastguard Worker // Case 7: Check that invoking dropAllRefs and dropUniqueRefs directly works as expected; i.e.,
1139*c8dee2aaSAndroid Build Coastguard Worker //         dropAllRefs removes everything while dropUniqueRefs is more measured.
test_7(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)1140*c8dee2aaSAndroid Build Coastguard Worker static void test_7(GrDirectContext* dContext, skiatest::Reporter* reporter,
1141*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::addAccessFP addAccess,
1142*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::checkFP check) {
1143*c8dee2aaSAndroid Build Coastguard Worker 
1144*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1145*c8dee2aaSAndroid Build Coastguard Worker 
1146*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, kNoID, false, false);
1147*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl1 = helper.snap1();
1148*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(nullptr, kImageWH,
1149*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1150*c8dee2aaSAndroid Build Coastguard Worker 
1151*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas2(), 2*kImageWH, kNoID, false, false);
1152*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl2 = helper.snap2();
1153*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(nullptr, 2*kImageWH,
1154*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 2, /*refs*/ 1, kNoID));
1155*c8dee2aaSAndroid Build Coastguard Worker 
1156*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 2);
1157*c8dee2aaSAndroid Build Coastguard Worker 
1158*c8dee2aaSAndroid Build Coastguard Worker     helper.threadSafeCache()->dropUniqueRefs(nullptr);
1159*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 2);
1160*c8dee2aaSAndroid Build Coastguard Worker 
1161*c8dee2aaSAndroid Build Coastguard Worker     ddl1 = nullptr;
1162*c8dee2aaSAndroid Build Coastguard Worker 
1163*c8dee2aaSAndroid Build Coastguard Worker     helper.threadSafeCache()->dropUniqueRefs(nullptr);
1164*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1165*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(nullptr, 2*kImageWH,
1166*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 2, /*refs*/ 1, kNoID));
1167*c8dee2aaSAndroid Build Coastguard Worker 
1168*c8dee2aaSAndroid Build Coastguard Worker     helper.threadSafeCache()->dropAllRefs();
1169*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 0);
1170*c8dee2aaSAndroid Build Coastguard Worker 
1171*c8dee2aaSAndroid Build Coastguard Worker     ddl2 = nullptr;
1172*c8dee2aaSAndroid Build Coastguard Worker }
1173*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache7View,reporter,ctxInfo,CtsEnforcement::kNever)1174*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache7View,
1175*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1176*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1177*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1178*c8dee2aaSAndroid Build Coastguard Worker     test_7(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
1179*c8dee2aaSAndroid Build Coastguard Worker }
1180*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache7Verts,reporter,ctxInfo,CtsEnforcement::kNever)1181*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache7Verts,
1182*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1183*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1184*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1185*c8dee2aaSAndroid Build Coastguard Worker     test_7(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
1186*c8dee2aaSAndroid Build Coastguard Worker }
1187*c8dee2aaSAndroid Build Coastguard Worker 
1188*c8dee2aaSAndroid Build Coastguard Worker // Case 8: This checks that GrContext::abandonContext works as expected wrt the thread
1189*c8dee2aaSAndroid Build Coastguard Worker //         safe cache. This simulates the case where we have one DDL that has finished
1190*c8dee2aaSAndroid Build Coastguard Worker //         recording but one still recording when the abandonContext fires.
test_8(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)1191*c8dee2aaSAndroid Build Coastguard Worker static void test_8(GrDirectContext* dContext, skiatest::Reporter* reporter,
1192*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::addAccessFP addAccess,
1193*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::checkFP check) {
1194*c8dee2aaSAndroid Build Coastguard Worker 
1195*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1196*c8dee2aaSAndroid Build Coastguard Worker 
1197*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), kImageWH, kNoID, false, false);
1198*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
1199*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1200*c8dee2aaSAndroid Build Coastguard Worker 
1201*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, kNoID, false, false);
1202*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl1 = helper.snap1();
1203*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
1204*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 2, kNoID));
1205*c8dee2aaSAndroid Build Coastguard Worker 
1206*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas2(), kImageWH, kNoID, false, false);
1207*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas2(), kImageWH,
1208*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 2, /*misses*/ 1, /*refs*/ 3, kNoID));
1209*c8dee2aaSAndroid Build Coastguard Worker 
1210*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1211*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumLazyCreations == 1);
1212*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumHWCreations == 1);
1213*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumSWCreations == 0);
1214*c8dee2aaSAndroid Build Coastguard Worker 
1215*c8dee2aaSAndroid Build Coastguard Worker     dContext->abandonContext(); // This should exercise dropAllRefs
1216*c8dee2aaSAndroid Build Coastguard Worker 
1217*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl2 = helper.snap2();
1218*c8dee2aaSAndroid Build Coastguard Worker 
1219*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 0);
1220*c8dee2aaSAndroid Build Coastguard Worker 
1221*c8dee2aaSAndroid Build Coastguard Worker     ddl1 = nullptr;
1222*c8dee2aaSAndroid Build Coastguard Worker     ddl2 = nullptr;
1223*c8dee2aaSAndroid Build Coastguard Worker }
1224*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache8View,reporter,ctxInfo,CtsEnforcement::kNever)1225*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache8View,
1226*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1227*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1228*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1229*c8dee2aaSAndroid Build Coastguard Worker     test_8(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
1230*c8dee2aaSAndroid Build Coastguard Worker }
1231*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache8Verts,reporter,ctxInfo,CtsEnforcement::kNever)1232*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache8Verts,
1233*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1234*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1235*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1236*c8dee2aaSAndroid Build Coastguard Worker     test_8(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
1237*c8dee2aaSAndroid Build Coastguard Worker }
1238*c8dee2aaSAndroid Build Coastguard Worker 
1239*c8dee2aaSAndroid Build Coastguard Worker // Case 9: This checks that GrContext::releaseResourcesAndAbandonContext works as expected wrt
1240*c8dee2aaSAndroid Build Coastguard Worker //         the thread safe cache. This simulates the case where we have one DDL that has finished
1241*c8dee2aaSAndroid Build Coastguard Worker //         recording but one still recording when the releaseResourcesAndAbandonContext fires.
test_9(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)1242*c8dee2aaSAndroid Build Coastguard Worker static void test_9(GrDirectContext* dContext, skiatest::Reporter* reporter,
1243*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::addAccessFP addAccess,
1244*c8dee2aaSAndroid Build Coastguard Worker                    TestHelper::checkFP check) {
1245*c8dee2aaSAndroid Build Coastguard Worker 
1246*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1247*c8dee2aaSAndroid Build Coastguard Worker 
1248*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), kImageWH, kNoID, false, false);
1249*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
1250*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1251*c8dee2aaSAndroid Build Coastguard Worker 
1252*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, kNoID, false, false);
1253*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl1 = helper.snap1();
1254*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
1255*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 2, kNoID));
1256*c8dee2aaSAndroid Build Coastguard Worker 
1257*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas2(), kImageWH, kNoID, false, false);
1258*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas2(), kImageWH,
1259*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 2, /*misses*/ 1, /*refs*/ 3, kNoID));
1260*c8dee2aaSAndroid Build Coastguard Worker 
1261*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1262*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumLazyCreations == 1);
1263*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumHWCreations == 1);
1264*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.stats()->fNumSWCreations == 0);
1265*c8dee2aaSAndroid Build Coastguard Worker 
1266*c8dee2aaSAndroid Build Coastguard Worker     dContext->releaseResourcesAndAbandonContext(); // This should hit dropAllRefs
1267*c8dee2aaSAndroid Build Coastguard Worker 
1268*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl2 = helper.snap2();
1269*c8dee2aaSAndroid Build Coastguard Worker 
1270*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 0);
1271*c8dee2aaSAndroid Build Coastguard Worker 
1272*c8dee2aaSAndroid Build Coastguard Worker     ddl1 = nullptr;
1273*c8dee2aaSAndroid Build Coastguard Worker     ddl2 = nullptr;
1274*c8dee2aaSAndroid Build Coastguard Worker }
1275*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache9View,reporter,ctxInfo,CtsEnforcement::kNever)1276*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache9View,
1277*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1278*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1279*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1280*c8dee2aaSAndroid Build Coastguard Worker     test_9(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
1281*c8dee2aaSAndroid Build Coastguard Worker }
1282*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache9Verts,reporter,ctxInfo,CtsEnforcement::kNever)1283*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache9Verts,
1284*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1285*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1286*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1287*c8dee2aaSAndroid Build Coastguard Worker     test_9(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
1288*c8dee2aaSAndroid Build Coastguard Worker }
1289*c8dee2aaSAndroid Build Coastguard Worker 
1290*c8dee2aaSAndroid Build Coastguard Worker // Case 10: This checks that the GrContext::purgeUnlockedResources(size_t) variant works as
1291*c8dee2aaSAndroid Build Coastguard Worker //          expected wrt the thread safe cache. It, in particular, tests out the MRU behavior
1292*c8dee2aaSAndroid Build Coastguard Worker //          of the shared cache.
test_10(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)1293*c8dee2aaSAndroid Build Coastguard Worker static void test_10(GrDirectContext* dContext, skiatest::Reporter* reporter,
1294*c8dee2aaSAndroid Build Coastguard Worker                     TestHelper::addAccessFP addAccess,
1295*c8dee2aaSAndroid Build Coastguard Worker                     TestHelper::checkFP check) {
1296*c8dee2aaSAndroid Build Coastguard Worker 
1297*c8dee2aaSAndroid Build Coastguard Worker     if (GrBackendApi::kOpenGL != dContext->backend()) {
1298*c8dee2aaSAndroid Build Coastguard Worker         // The lower-level backends have too much going on for the following simple purging
1299*c8dee2aaSAndroid Build Coastguard Worker         // test to work
1300*c8dee2aaSAndroid Build Coastguard Worker         return;
1301*c8dee2aaSAndroid Build Coastguard Worker     }
1302*c8dee2aaSAndroid Build Coastguard Worker 
1303*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1304*c8dee2aaSAndroid Build Coastguard Worker 
1305*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), kImageWH, kNoID, false, false);
1306*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
1307*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1308*c8dee2aaSAndroid Build Coastguard Worker 
1309*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, kNoID, false, false);
1310*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl1 = helper.snap1();
1311*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
1312*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 2, kNoID));
1313*c8dee2aaSAndroid Build Coastguard Worker 
1314*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), 2*kImageWH, kNoID, false, false);
1315*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), 2*kImageWH,
1316*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 2, /*refs*/ 1, kNoID));
1317*c8dee2aaSAndroid Build Coastguard Worker 
1318*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas2(), 2*kImageWH, kNoID, false, false);
1319*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl2 = helper.snap2();
1320*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas2(), 2*kImageWH,
1321*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 2, /*misses*/ 2, /*refs*/ 2, kNoID));
1322*c8dee2aaSAndroid Build Coastguard Worker 
1323*c8dee2aaSAndroid Build Coastguard Worker     dContext->flush();
1324*c8dee2aaSAndroid Build Coastguard Worker     dContext->submit(GrSyncCpu::kYes);
1325*c8dee2aaSAndroid Build Coastguard Worker 
1326*c8dee2aaSAndroid Build Coastguard Worker     // This should clear out everything but the textures locked in the thread-safe cache
1327*c8dee2aaSAndroid Build Coastguard Worker     dContext->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources);
1328*c8dee2aaSAndroid Build Coastguard Worker 
1329*c8dee2aaSAndroid Build Coastguard Worker     ddl1 = nullptr;
1330*c8dee2aaSAndroid Build Coastguard Worker     ddl2 = nullptr;
1331*c8dee2aaSAndroid Build Coastguard Worker 
1332*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 2);
1333*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
1334*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 2, /*misses*/ 2, /*refs*/ 0, kNoID));
1335*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), 2*kImageWH,
1336*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 2, /*misses*/ 2, /*refs*/ 0, kNoID));
1337*c8dee2aaSAndroid Build Coastguard Worker 
1338*c8dee2aaSAndroid Build Coastguard Worker     // Regardless of which image is MRU, this should force the other out
1339*c8dee2aaSAndroid Build Coastguard Worker     size_t desiredBytes = helper.gpuSize(2*kImageWH) + helper.gpuSize(kImageWH)/2;
1340*c8dee2aaSAndroid Build Coastguard Worker 
1341*c8dee2aaSAndroid Build Coastguard Worker     auto cache = dContext->priv().getResourceCache();
1342*c8dee2aaSAndroid Build Coastguard Worker     size_t currentBytes = cache->getResourceBytes();
1343*c8dee2aaSAndroid Build Coastguard Worker 
1344*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(currentBytes >= desiredBytes);
1345*c8dee2aaSAndroid Build Coastguard Worker     size_t amountToPurge = currentBytes - desiredBytes;
1346*c8dee2aaSAndroid Build Coastguard Worker 
1347*c8dee2aaSAndroid Build Coastguard Worker     // The 2*kImageWH texture should be MRU.
1348*c8dee2aaSAndroid Build Coastguard Worker     dContext->purgeUnlockedResources(amountToPurge, true);
1349*c8dee2aaSAndroid Build Coastguard Worker 
1350*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1351*c8dee2aaSAndroid Build Coastguard Worker 
1352*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), 2*kImageWH,
1353*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 2, /*misses*/ 2, /*refs*/ 0, kNoID));
1354*c8dee2aaSAndroid Build Coastguard Worker }
1355*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache10View,reporter,ctxInfo,CtsEnforcement::kNever)1356*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache10View,
1357*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1358*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1359*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1360*c8dee2aaSAndroid Build Coastguard Worker     test_10(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
1361*c8dee2aaSAndroid Build Coastguard Worker }
1362*c8dee2aaSAndroid Build Coastguard Worker 
1363*c8dee2aaSAndroid Build Coastguard Worker // To enable test_10 with verts would require a bit more work, namely:
1364*c8dee2aaSAndroid Build Coastguard Worker //    have a different # of verts based on size
1365*c8dee2aaSAndroid Build Coastguard Worker //    also pass in a gpuSize function to 'test_10'
1366*c8dee2aaSAndroid Build Coastguard Worker // DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache10Verts, reporter, ctxInfo) {
1367*c8dee2aaSAndroid Build Coastguard Worker //    test_10(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess,
1368*c8dee2aaSAndroid Build Coastguard Worker //    &TestHelper::checkVert);
1369*c8dee2aaSAndroid Build Coastguard Worker //}
1370*c8dee2aaSAndroid Build Coastguard Worker 
1371*c8dee2aaSAndroid Build Coastguard Worker // Case 11: This checks that scratch-only variant of GrContext::purgeUnlockedResources works as
1372*c8dee2aaSAndroid Build Coastguard Worker //          expected wrt the thread safe cache. In particular, that when 'scratchResourcesOnly'
1373*c8dee2aaSAndroid Build Coastguard Worker //          is true, the call has no effect on the cache.
test_11(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)1374*c8dee2aaSAndroid Build Coastguard Worker static void test_11(GrDirectContext* dContext, skiatest::Reporter* reporter,
1375*c8dee2aaSAndroid Build Coastguard Worker                     TestHelper::addAccessFP addAccess,
1376*c8dee2aaSAndroid Build Coastguard Worker                     TestHelper::checkFP check) {
1377*c8dee2aaSAndroid Build Coastguard Worker 
1378*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1379*c8dee2aaSAndroid Build Coastguard Worker 
1380*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), kImageWH, kNoID, false, false);
1381*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
1382*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1383*c8dee2aaSAndroid Build Coastguard Worker 
1384*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), 2*kImageWH, kNoID, false, false);
1385*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), 2*kImageWH,
1386*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 2, /*refs*/ 1, kNoID));
1387*c8dee2aaSAndroid Build Coastguard Worker 
1388*c8dee2aaSAndroid Build Coastguard Worker     dContext->flush();
1389*c8dee2aaSAndroid Build Coastguard Worker     dContext->submit(GrSyncCpu::kYes);
1390*c8dee2aaSAndroid Build Coastguard Worker 
1391*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 2);
1392*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
1393*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 2, /*refs*/ 0, kNoID));
1394*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), 2*kImageWH,
1395*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 2, /*refs*/ 0, kNoID));
1396*c8dee2aaSAndroid Build Coastguard Worker 
1397*c8dee2aaSAndroid Build Coastguard Worker     // This shouldn't remove anything from the cache
1398*c8dee2aaSAndroid Build Coastguard Worker     dContext->purgeUnlockedResources(GrPurgeResourceOptions::kScratchResourcesOnly);
1399*c8dee2aaSAndroid Build Coastguard Worker 
1400*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 2);
1401*c8dee2aaSAndroid Build Coastguard Worker 
1402*c8dee2aaSAndroid Build Coastguard Worker     dContext->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources);
1403*c8dee2aaSAndroid Build Coastguard Worker 
1404*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 0);
1405*c8dee2aaSAndroid Build Coastguard Worker }
1406*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache11View,reporter,ctxInfo,CtsEnforcement::kNever)1407*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache11View,
1408*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1409*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1410*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1411*c8dee2aaSAndroid Build Coastguard Worker     test_11(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
1412*c8dee2aaSAndroid Build Coastguard Worker }
1413*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache11Verts,reporter,ctxInfo,CtsEnforcement::kNever)1414*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache11Verts,
1415*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1416*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1417*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1418*c8dee2aaSAndroid Build Coastguard Worker     test_11(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
1419*c8dee2aaSAndroid Build Coastguard Worker }
1420*c8dee2aaSAndroid Build Coastguard Worker 
1421*c8dee2aaSAndroid Build Coastguard Worker // Case 12: Test out purges caused by resetting the cache budget to 0. Note that, due to
1422*c8dee2aaSAndroid Build Coastguard Worker //          the how the cache operates (i.e., not directly driven by ref/unrefs) there
1423*c8dee2aaSAndroid Build Coastguard Worker //          needs to be an explicit kick to purge the cache.
test_12(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)1424*c8dee2aaSAndroid Build Coastguard Worker static void test_12(GrDirectContext* dContext, skiatest::Reporter* reporter,
1425*c8dee2aaSAndroid Build Coastguard Worker                     TestHelper::addAccessFP addAccess,
1426*c8dee2aaSAndroid Build Coastguard Worker                     TestHelper::checkFP check) {
1427*c8dee2aaSAndroid Build Coastguard Worker 
1428*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1429*c8dee2aaSAndroid Build Coastguard Worker 
1430*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), kImageWH, kNoID, false, false);
1431*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
1432*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1433*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, kNoID, false, false);
1434*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl1 = helper.snap1();
1435*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
1436*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 1, /*refs*/ 2, kNoID));
1437*c8dee2aaSAndroid Build Coastguard Worker 
1438*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.liveCanvas(), 2*kImageWH, kNoID, false, false);
1439*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), 2*kImageWH,
1440*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 2, /*refs*/ 1, kNoID));
1441*c8dee2aaSAndroid Build Coastguard Worker 
1442*c8dee2aaSAndroid Build Coastguard Worker     dContext->flush();
1443*c8dee2aaSAndroid Build Coastguard Worker     dContext->submit(GrSyncCpu::kYes);
1444*c8dee2aaSAndroid Build Coastguard Worker 
1445*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 2);
1446*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), kImageWH,
1447*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 2, /*refs*/ 1, kNoID));
1448*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), 2*kImageWH,
1449*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 1, /*misses*/ 2, /*refs*/ 0, kNoID));
1450*c8dee2aaSAndroid Build Coastguard Worker 
1451*c8dee2aaSAndroid Build Coastguard Worker     dContext->setResourceCacheLimit(0);
1452*c8dee2aaSAndroid Build Coastguard Worker 
1453*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1454*c8dee2aaSAndroid Build Coastguard Worker 
1455*c8dee2aaSAndroid Build Coastguard Worker     ddl1 = nullptr;
1456*c8dee2aaSAndroid Build Coastguard Worker 
1457*c8dee2aaSAndroid Build Coastguard Worker     // Explicitly kick off the purge - it won't happen automatically on unref
1458*c8dee2aaSAndroid Build Coastguard Worker     dContext->performDeferredCleanup(std::chrono::milliseconds(0));
1459*c8dee2aaSAndroid Build Coastguard Worker 
1460*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 0);
1461*c8dee2aaSAndroid Build Coastguard Worker }
1462*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache12View,reporter,ctxInfo,CtsEnforcement::kNever)1463*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache12View,
1464*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1465*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1466*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1467*c8dee2aaSAndroid Build Coastguard Worker     test_12(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
1468*c8dee2aaSAndroid Build Coastguard Worker }
1469*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache12Verts,reporter,ctxInfo,CtsEnforcement::kNever)1470*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache12Verts,
1471*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1472*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1473*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1474*c8dee2aaSAndroid Build Coastguard Worker     test_12(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
1475*c8dee2aaSAndroid Build Coastguard Worker }
1476*c8dee2aaSAndroid Build Coastguard Worker 
1477*c8dee2aaSAndroid Build Coastguard Worker // Case 13: Test out the 'msNotUsed' parameter to GrContext::performDeferredCleanup.
test_13(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check)1478*c8dee2aaSAndroid Build Coastguard Worker static void test_13(GrDirectContext* dContext, skiatest::Reporter* reporter,
1479*c8dee2aaSAndroid Build Coastguard Worker                     TestHelper::addAccessFP addAccess,
1480*c8dee2aaSAndroid Build Coastguard Worker                     TestHelper::checkFP check) {
1481*c8dee2aaSAndroid Build Coastguard Worker 
1482*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1483*c8dee2aaSAndroid Build Coastguard Worker 
1484*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, kNoID, false, false);
1485*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
1486*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1487*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl1 = helper.snap1();
1488*c8dee2aaSAndroid Build Coastguard Worker 
1489*c8dee2aaSAndroid Build Coastguard Worker     std::this_thread::sleep_for(std::chrono::milliseconds(5));
1490*c8dee2aaSAndroid Build Coastguard Worker     auto firstTime = skgpu::StdSteadyClock::now();
1491*c8dee2aaSAndroid Build Coastguard Worker     std::this_thread::sleep_for(std::chrono::milliseconds(5));
1492*c8dee2aaSAndroid Build Coastguard Worker 
1493*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas2(), 2*kImageWH, kNoID, false, false);
1494*c8dee2aaSAndroid Build Coastguard Worker 
1495*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas2(), 2*kImageWH,
1496*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 2, /*refs*/ 1, kNoID));
1497*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl2 = helper.snap2();
1498*c8dee2aaSAndroid Build Coastguard Worker 
1499*c8dee2aaSAndroid Build Coastguard Worker     ddl1 = nullptr;
1500*c8dee2aaSAndroid Build Coastguard Worker     ddl2 = nullptr;
1501*c8dee2aaSAndroid Build Coastguard Worker 
1502*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 2);
1503*c8dee2aaSAndroid Build Coastguard Worker 
1504*c8dee2aaSAndroid Build Coastguard Worker     auto secondTime = skgpu::StdSteadyClock::now();
1505*c8dee2aaSAndroid Build Coastguard Worker 
1506*c8dee2aaSAndroid Build Coastguard Worker     auto msecs = std::chrono::duration_cast<std::chrono::milliseconds>(secondTime - firstTime);
1507*c8dee2aaSAndroid Build Coastguard Worker     dContext->performDeferredCleanup(msecs);
1508*c8dee2aaSAndroid Build Coastguard Worker 
1509*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1510*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.liveCanvas(), 2*kImageWH,
1511*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 2, /*refs*/ 0, kNoID));
1512*c8dee2aaSAndroid Build Coastguard Worker }
1513*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache13View,reporter,ctxInfo,CtsEnforcement::kNever)1514*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache13View,
1515*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1516*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1517*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1518*c8dee2aaSAndroid Build Coastguard Worker     test_13(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView);
1519*c8dee2aaSAndroid Build Coastguard Worker }
1520*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache13Verts,reporter,ctxInfo,CtsEnforcement::kNever)1521*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache13Verts,
1522*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1523*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1524*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1525*c8dee2aaSAndroid Build Coastguard Worker     test_13(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert);
1526*c8dee2aaSAndroid Build Coastguard Worker }
1527*c8dee2aaSAndroid Build Coastguard Worker 
1528*c8dee2aaSAndroid Build Coastguard Worker // Case 14: Test out mixing & matching view & vertex data w/ recycling of the cache entries to
1529*c8dee2aaSAndroid Build Coastguard Worker //          wring out the anonymous union code. This is mainly for the MSAN bot's consumption.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache14,reporter,ctxInfo,CtsEnforcement::kNever)1530*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache14,
1531*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1532*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1533*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1534*c8dee2aaSAndroid Build Coastguard Worker     constexpr int kBestPrimeNumber = 73; // palindromic in binary
1535*c8dee2aaSAndroid Build Coastguard Worker     SkRandom rand(kBestPrimeNumber);
1536*c8dee2aaSAndroid Build Coastguard Worker 
1537*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(ctxInfo.directContext());
1538*c8dee2aaSAndroid Build Coastguard Worker 
1539*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < 2; ++i) {
1540*c8dee2aaSAndroid Build Coastguard Worker         SkCanvas* ddlCanvas = (!i) ? helper.ddlCanvas1() : helper.ddlCanvas2();
1541*c8dee2aaSAndroid Build Coastguard Worker 
1542*c8dee2aaSAndroid Build Coastguard Worker         for (int j = 0; j < 10; ++j) {
1543*c8dee2aaSAndroid Build Coastguard Worker             int numResources = 10*i + j + 1;
1544*c8dee2aaSAndroid Build Coastguard Worker             int wh = numResources;
1545*c8dee2aaSAndroid Build Coastguard Worker 
1546*c8dee2aaSAndroid Build Coastguard Worker             if (rand.nextBool()) {
1547*c8dee2aaSAndroid Build Coastguard Worker                 helper.addViewAccess(ddlCanvas, wh, kNoID, false, false);
1548*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, helper.checkView(ddlCanvas, wh,
1549*c8dee2aaSAndroid Build Coastguard Worker                                                            /*hits*/ 0, /*misses*/ numResources,
1550*c8dee2aaSAndroid Build Coastguard Worker                                                            /*refs*/ 1, kNoID));
1551*c8dee2aaSAndroid Build Coastguard Worker             } else {
1552*c8dee2aaSAndroid Build Coastguard Worker                 helper.addVertAccess(ddlCanvas, wh, kNoID, false, false);
1553*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, helper.checkVert(ddlCanvas, wh,
1554*c8dee2aaSAndroid Build Coastguard Worker                                                            /*hits*/ 0, /*misses*/ numResources,
1555*c8dee2aaSAndroid Build Coastguard Worker                                                            /*refs*/ 1, kNoID));
1556*c8dee2aaSAndroid Build Coastguard Worker             }
1557*c8dee2aaSAndroid Build Coastguard Worker         }
1558*c8dee2aaSAndroid Build Coastguard Worker 
1559*c8dee2aaSAndroid Build Coastguard Worker         if (!i) {
1560*c8dee2aaSAndroid Build Coastguard Worker             // Drop all the accumulated resources from the thread-safe cache
1561*c8dee2aaSAndroid Build Coastguard Worker             helper.snap1();
1562*c8dee2aaSAndroid Build Coastguard Worker             ctxInfo.directContext()->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources);
1563*c8dee2aaSAndroid Build Coastguard Worker         }
1564*c8dee2aaSAndroid Build Coastguard Worker     }
1565*c8dee2aaSAndroid Build Coastguard Worker }
1566*c8dee2aaSAndroid Build Coastguard Worker 
1567*c8dee2aaSAndroid Build Coastguard Worker // Case 15: Test out posting invalidation messages that involve the thread safe cache
test_15(GrDirectContext * dContext,skiatest::Reporter * reporter,TestHelper::addAccessFP addAccess,TestHelper::checkFP check,void (* create_key)(skgpu::UniqueKey *,int wh,int id))1568*c8dee2aaSAndroid Build Coastguard Worker static void test_15(GrDirectContext* dContext, skiatest::Reporter* reporter,
1569*c8dee2aaSAndroid Build Coastguard Worker                     TestHelper::addAccessFP addAccess,
1570*c8dee2aaSAndroid Build Coastguard Worker                     TestHelper::checkFP check,
1571*c8dee2aaSAndroid Build Coastguard Worker                     void (*create_key)(skgpu::UniqueKey*, int wh, int id)) {
1572*c8dee2aaSAndroid Build Coastguard Worker 
1573*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(dContext);
1574*c8dee2aaSAndroid Build Coastguard Worker 
1575*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas1(), kImageWH, kNoID, false, false);
1576*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas1(), kImageWH,
1577*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1578*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl1 = helper.snap1();
1579*c8dee2aaSAndroid Build Coastguard Worker 
1580*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1581*c8dee2aaSAndroid Build Coastguard Worker 
1582*c8dee2aaSAndroid Build Coastguard Worker     skgpu::UniqueKey key;
1583*c8dee2aaSAndroid Build Coastguard Worker     (*create_key)(&key, kImageWH, kNoID);
1584*c8dee2aaSAndroid Build Coastguard Worker 
1585*c8dee2aaSAndroid Build Coastguard Worker     skgpu::UniqueKeyInvalidatedMessage msg(key, dContext->priv().contextID(),
1586*c8dee2aaSAndroid Build Coastguard Worker                                       /* inThreadSafeCache */ true);
1587*c8dee2aaSAndroid Build Coastguard Worker 
1588*c8dee2aaSAndroid Build Coastguard Worker     SkMessageBus<skgpu::UniqueKeyInvalidatedMessage, uint32_t>::Post(msg);
1589*c8dee2aaSAndroid Build Coastguard Worker 
1590*c8dee2aaSAndroid Build Coastguard Worker     // This purge call is needed to process the invalidation messages
1591*c8dee2aaSAndroid Build Coastguard Worker     dContext->purgeUnlockedResources(GrPurgeResourceOptions::kScratchResourcesOnly);
1592*c8dee2aaSAndroid Build Coastguard Worker 
1593*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 0);
1594*c8dee2aaSAndroid Build Coastguard Worker 
1595*c8dee2aaSAndroid Build Coastguard Worker     (helper.*addAccess)(helper.ddlCanvas2(), kImageWH, kNoID, false, false);
1596*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, (helper.*check)(helper.ddlCanvas2(), kImageWH,
1597*c8dee2aaSAndroid Build Coastguard Worker                                               /*hits*/ 0, /*misses*/ 2, /*refs*/ 1, kNoID));
1598*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl2 = helper.snap2();
1599*c8dee2aaSAndroid Build Coastguard Worker 
1600*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1601*c8dee2aaSAndroid Build Coastguard Worker 
1602*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, std::move(ddl1));
1603*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, std::move(ddl2));
1604*c8dee2aaSAndroid Build Coastguard Worker }
1605*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache15View,reporter,ctxInfo,CtsEnforcement::kNever)1606*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache15View,
1607*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1608*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1609*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1610*c8dee2aaSAndroid Build Coastguard Worker     test_15(ctxInfo.directContext(), reporter, &TestHelper::addViewAccess, &TestHelper::checkView,
1611*c8dee2aaSAndroid Build Coastguard Worker             create_view_key);
1612*c8dee2aaSAndroid Build Coastguard Worker }
1613*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache15Verts,reporter,ctxInfo,CtsEnforcement::kNever)1614*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache15Verts,
1615*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1616*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1617*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1618*c8dee2aaSAndroid Build Coastguard Worker     test_15(ctxInfo.directContext(), reporter, &TestHelper::addVertAccess, &TestHelper::checkVert,
1619*c8dee2aaSAndroid Build Coastguard Worker             create_vert_key);
1620*c8dee2aaSAndroid Build Coastguard Worker }
1621*c8dee2aaSAndroid Build Coastguard Worker 
1622*c8dee2aaSAndroid Build Coastguard Worker // Case 16: Test out pre-emption of an existing vertex-data cache entry. This test simulates
1623*c8dee2aaSAndroid Build Coastguard Worker //          the case where there is a race to create vertex data. However, the second one
1624*c8dee2aaSAndroid Build Coastguard Worker //          to finish is better and usurps the first's position in the cache.
1625*c8dee2aaSAndroid Build Coastguard Worker //
1626*c8dee2aaSAndroid Build Coastguard Worker //          This capability isn't available for views.
1627*c8dee2aaSAndroid Build Coastguard Worker 
newer_is_always_better(SkData *,SkData *)1628*c8dee2aaSAndroid Build Coastguard Worker static bool newer_is_always_better(SkData* /* incumbent */, SkData* /* challenger */) {
1629*c8dee2aaSAndroid Build Coastguard Worker     return true;
1630*c8dee2aaSAndroid Build Coastguard Worker }
1631*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache16Verts,reporter,ctxInfo,CtsEnforcement::kNever)1632*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrThreadSafeCache16Verts,
1633*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
1634*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
1635*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kNever) {
1636*c8dee2aaSAndroid Build Coastguard Worker     skgpu::UniqueKey key;
1637*c8dee2aaSAndroid Build Coastguard Worker     create_vert_key(&key, kImageWH, kNoID);
1638*c8dee2aaSAndroid Build Coastguard Worker 
1639*c8dee2aaSAndroid Build Coastguard Worker     TestHelper helper(ctxInfo.directContext(), newer_is_always_better);
1640*c8dee2aaSAndroid Build Coastguard Worker 
1641*c8dee2aaSAndroid Build Coastguard Worker     GrThreadSafeVertexTestOp* op1 = nullptr, *op2 = nullptr;
1642*c8dee2aaSAndroid Build Coastguard Worker 
1643*c8dee2aaSAndroid Build Coastguard Worker     helper.addVertAccess(helper.ddlCanvas1(), kImageWH, kNoID, false, false, &op1);
1644*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.checkVert(helper.ddlCanvas1(), kImageWH,
1645*c8dee2aaSAndroid Build Coastguard Worker                                                /*hits*/ 0, /*misses*/ 1, /*refs*/ 1, kNoID));
1646*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl1 = helper.snap1();
1647*c8dee2aaSAndroid Build Coastguard Worker 
1648*c8dee2aaSAndroid Build Coastguard Worker     {
1649*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1650*c8dee2aaSAndroid Build Coastguard Worker         auto [vertexData, xtraData] = helper.threadSafeCache()->findVertsWithData(key);
1651*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, vertexData.get() == op1->vertexData());
1652*c8dee2aaSAndroid Build Coastguard Worker     }
1653*c8dee2aaSAndroid Build Coastguard Worker 
1654*c8dee2aaSAndroid Build Coastguard Worker     helper.addVertAccess(helper.ddlCanvas2(), kImageWH, kNoID, /* failLookup */ true, false, &op2);
1655*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, helper.checkVert(helper.ddlCanvas2(), kImageWH,
1656*c8dee2aaSAndroid Build Coastguard Worker                                                /*hits*/ 0, /*misses*/ 2, /*refs*/ 1, kNoID));
1657*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList> ddl2 = helper.snap2();
1658*c8dee2aaSAndroid Build Coastguard Worker 
1659*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, op1->vertexData() != op2->vertexData());
1660*c8dee2aaSAndroid Build Coastguard Worker 
1661*c8dee2aaSAndroid Build Coastguard Worker     {
1662*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, helper.numCacheEntries() == 1);
1663*c8dee2aaSAndroid Build Coastguard Worker         auto [vertexData, xtraData] = helper.threadSafeCache()->findVertsWithData(key);
1664*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, vertexData.get() == op2->vertexData());
1665*c8dee2aaSAndroid Build Coastguard Worker     }
1666*c8dee2aaSAndroid Build Coastguard Worker 
1667*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, std::move(ddl1));
1668*c8dee2aaSAndroid Build Coastguard Worker     helper.checkImage(reporter, std::move(ddl2));
1669*c8dee2aaSAndroid Build Coastguard Worker }
1670