xref: /aosp_15_r20/external/skia/tests/GrMipMappedTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2017 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/SkImage.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/SkRect.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSamplingOptions.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurfaceProps.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrContextOptions.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkImageGanesh.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/mock/GrMockTypes.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTextureGenerator.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/SkBackingFit.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Swizzle.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/Device.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrBackendTextureImageGenerator.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrColorSpaceXform.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDrawingManager.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProxyProvider.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSamplerState.h"
47*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSemaphore.h"
48*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxy.h"
49*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxyPriv.h"
50*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxyView.h"
51*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTexture.h"
52*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureProxy.h"
53*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SkGr.h"
54*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SurfaceDrawContext.h"
55*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/OpsTask.h"
56*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/surface/SkSurface_Ganesh.h"
57*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
58*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
59*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/BackendSurfaceFactory.h"
60*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/BackendTextureImageFactory.h"
61*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ManagedBackendTexture.h"
62*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ProxyUtils.h"
63*c8dee2aaSAndroid Build Coastguard Worker 
64*c8dee2aaSAndroid Build Coastguard Worker #include <initializer_list>
65*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
66*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
67*c8dee2aaSAndroid Build Coastguard Worker 
68*c8dee2aaSAndroid Build Coastguard Worker class GrRenderTask;
69*c8dee2aaSAndroid Build Coastguard Worker 
70*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_DIRECT3D)
71*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/d3d/GrD3DTypes.h"
72*c8dee2aaSAndroid Build Coastguard Worker #endif
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_METAL)
75*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/mtl/GrMtlBackendSurface.h"
76*c8dee2aaSAndroid Build Coastguard Worker #endif
77*c8dee2aaSAndroid Build Coastguard Worker 
78*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GL)
79*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
80*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLTypes.h"
81*c8dee2aaSAndroid Build Coastguard Worker #endif
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_VULKAN)
84*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
85*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkTypes.h"
86*c8dee2aaSAndroid Build Coastguard Worker #endif
87*c8dee2aaSAndroid Build Coastguard Worker 
88*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kSize = 8;
89*c8dee2aaSAndroid Build Coastguard Worker 
90*c8dee2aaSAndroid Build Coastguard Worker // Test that the correct mip map states are on the GrTextures when wrapping GrBackendTextures in
91*c8dee2aaSAndroid Build Coastguard Worker // SkImages and SkSurfaces
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)92*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest,
93*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
94*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
95*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kApiLevel_T) {
96*c8dee2aaSAndroid Build Coastguard Worker     using namespace skgpu;
97*c8dee2aaSAndroid Build Coastguard Worker 
98*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = ctxInfo.directContext();
99*c8dee2aaSAndroid Build Coastguard Worker     if (!dContext->priv().caps()->mipmapSupport()) {
100*c8dee2aaSAndroid Build Coastguard Worker         return;
101*c8dee2aaSAndroid Build Coastguard Worker     }
102*c8dee2aaSAndroid Build Coastguard Worker 
103*c8dee2aaSAndroid Build Coastguard Worker     Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());
104*c8dee2aaSAndroid Build Coastguard Worker 
105*c8dee2aaSAndroid Build Coastguard Worker     for (auto mipmapped : { Mipmapped::kNo, Mipmapped::kYes }) {
106*c8dee2aaSAndroid Build Coastguard Worker         for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
107*c8dee2aaSAndroid Build Coastguard Worker             // createBackendTexture currently doesn't support uploading data to mip maps
108*c8dee2aaSAndroid Build Coastguard Worker             // so we don't send any. However, we pretend there is data for the checks below which is
109*c8dee2aaSAndroid Build Coastguard Worker             // fine since we are never actually using these textures for any work on the gpu.
110*c8dee2aaSAndroid Build Coastguard Worker             auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithData(dContext,
111*c8dee2aaSAndroid Build Coastguard Worker                                                                          kSize,
112*c8dee2aaSAndroid Build Coastguard Worker                                                                          kSize,
113*c8dee2aaSAndroid Build Coastguard Worker                                                                          kRGBA_8888_SkColorType,
114*c8dee2aaSAndroid Build Coastguard Worker                                                                          SkColors::kTransparent,
115*c8dee2aaSAndroid Build Coastguard Worker                                                                          mipmapped,
116*c8dee2aaSAndroid Build Coastguard Worker                                                                          renderable,
117*c8dee2aaSAndroid Build Coastguard Worker                                                                          isProtected);
118*c8dee2aaSAndroid Build Coastguard Worker             if (!mbet) {
119*c8dee2aaSAndroid Build Coastguard Worker                 ERRORF(reporter, "Could not make texture.");
120*c8dee2aaSAndroid Build Coastguard Worker                 return;
121*c8dee2aaSAndroid Build Coastguard Worker             }
122*c8dee2aaSAndroid Build Coastguard Worker 
123*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<GrTextureProxy> proxy;
124*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkImage> image;
125*c8dee2aaSAndroid Build Coastguard Worker             if (renderable == GrRenderable::kYes) {
126*c8dee2aaSAndroid Build Coastguard Worker                 sk_sp<SkSurface> surface = SkSurfaces::WrapBackendTexture(
127*c8dee2aaSAndroid Build Coastguard Worker                         dContext,
128*c8dee2aaSAndroid Build Coastguard Worker                         mbet->texture(),
129*c8dee2aaSAndroid Build Coastguard Worker                         kTopLeft_GrSurfaceOrigin,
130*c8dee2aaSAndroid Build Coastguard Worker                         0,
131*c8dee2aaSAndroid Build Coastguard Worker                         kRGBA_8888_SkColorType,
132*c8dee2aaSAndroid Build Coastguard Worker                         /*color space*/ nullptr,
133*c8dee2aaSAndroid Build Coastguard Worker                         /*surface props*/ nullptr,
134*c8dee2aaSAndroid Build Coastguard Worker                         sk_gpu_test::ManagedBackendTexture::ReleaseProc,
135*c8dee2aaSAndroid Build Coastguard Worker                         mbet->releaseContext());
136*c8dee2aaSAndroid Build Coastguard Worker 
137*c8dee2aaSAndroid Build Coastguard Worker                 auto device = ((SkSurface_Ganesh*)surface.get())->getDevice();
138*c8dee2aaSAndroid Build Coastguard Worker                 proxy = device->readSurfaceView().asTextureProxyRef();
139*c8dee2aaSAndroid Build Coastguard Worker             } else {
140*c8dee2aaSAndroid Build Coastguard Worker                 image = SkImages::BorrowTextureFrom(dContext,
141*c8dee2aaSAndroid Build Coastguard Worker                                                     mbet->texture(),
142*c8dee2aaSAndroid Build Coastguard Worker                                                     kTopLeft_GrSurfaceOrigin,
143*c8dee2aaSAndroid Build Coastguard Worker                                                     kRGBA_8888_SkColorType,
144*c8dee2aaSAndroid Build Coastguard Worker                                                     kPremul_SkAlphaType,
145*c8dee2aaSAndroid Build Coastguard Worker                                                     /* color space */ nullptr,
146*c8dee2aaSAndroid Build Coastguard Worker                                                     sk_gpu_test::ManagedBackendTexture::ReleaseProc,
147*c8dee2aaSAndroid Build Coastguard Worker                                                     mbet->releaseContext());
148*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, (mipmapped == Mipmapped::kYes) == image->hasMipmaps());
149*c8dee2aaSAndroid Build Coastguard Worker                 proxy = sk_ref_sp(sk_gpu_test::GetTextureImageProxy(image.get(), dContext));
150*c8dee2aaSAndroid Build Coastguard Worker             }
151*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, proxy);
152*c8dee2aaSAndroid Build Coastguard Worker             if (!proxy) {
153*c8dee2aaSAndroid Build Coastguard Worker                 continue;
154*c8dee2aaSAndroid Build Coastguard Worker             }
155*c8dee2aaSAndroid Build Coastguard Worker 
156*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, proxy->isInstantiated());
157*c8dee2aaSAndroid Build Coastguard Worker 
158*c8dee2aaSAndroid Build Coastguard Worker             GrTexture* texture = proxy->peekTexture();
159*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, texture);
160*c8dee2aaSAndroid Build Coastguard Worker             if (!texture) {
161*c8dee2aaSAndroid Build Coastguard Worker                 continue;
162*c8dee2aaSAndroid Build Coastguard Worker             }
163*c8dee2aaSAndroid Build Coastguard Worker 
164*c8dee2aaSAndroid Build Coastguard Worker             if (mipmapped == Mipmapped::kYes) {
165*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, Mipmapped::kYes == texture->mipmapped());
166*c8dee2aaSAndroid Build Coastguard Worker                 if (GrRenderable::kYes == renderable) {
167*c8dee2aaSAndroid Build Coastguard Worker                     REPORTER_ASSERT(reporter, texture->mipmapsAreDirty());
168*c8dee2aaSAndroid Build Coastguard Worker                 } else {
169*c8dee2aaSAndroid Build Coastguard Worker                     REPORTER_ASSERT(reporter, !texture->mipmapsAreDirty());
170*c8dee2aaSAndroid Build Coastguard Worker                 }
171*c8dee2aaSAndroid Build Coastguard Worker             } else {
172*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, Mipmapped::kNo == texture->mipmapped());
173*c8dee2aaSAndroid Build Coastguard Worker             }
174*c8dee2aaSAndroid Build Coastguard Worker         }
175*c8dee2aaSAndroid Build Coastguard Worker     }
176*c8dee2aaSAndroid Build Coastguard Worker }
177*c8dee2aaSAndroid Build Coastguard Worker 
178*c8dee2aaSAndroid Build Coastguard Worker // Test that we correctly copy or don't copy GrBackendTextures in the GrBackendTextureImageGenerator
179*c8dee2aaSAndroid Build Coastguard Worker // based on if we will use mips in the draw and the mip status of the GrBackendTexture.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)180*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest,
181*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
182*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
183*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kApiLevel_T) {
184*c8dee2aaSAndroid Build Coastguard Worker     using namespace skgpu;
185*c8dee2aaSAndroid Build Coastguard Worker 
186*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = ctxInfo.directContext();
187*c8dee2aaSAndroid Build Coastguard Worker     if (!dContext->priv().caps()->mipmapSupport()) {
188*c8dee2aaSAndroid Build Coastguard Worker         return;
189*c8dee2aaSAndroid Build Coastguard Worker     }
190*c8dee2aaSAndroid Build Coastguard Worker 
191*c8dee2aaSAndroid Build Coastguard Worker     Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());
192*c8dee2aaSAndroid Build Coastguard Worker 
193*c8dee2aaSAndroid Build Coastguard Worker     for (auto betMipmapped : { Mipmapped::kNo, Mipmapped::kYes }) {
194*c8dee2aaSAndroid Build Coastguard Worker         for (auto requestMipmapped : { Mipmapped::kNo, Mipmapped::kYes }) {
195*c8dee2aaSAndroid Build Coastguard Worker             auto ii =
196*c8dee2aaSAndroid Build Coastguard Worker                     SkImageInfo::Make({kSize, kSize}, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
197*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkImage> image = sk_gpu_test::MakeBackendTextureImage(
198*c8dee2aaSAndroid Build Coastguard Worker                     dContext, ii, SkColors::kTransparent, betMipmapped,
199*c8dee2aaSAndroid Build Coastguard Worker                     Renderable::kNo,
200*c8dee2aaSAndroid Build Coastguard Worker                     GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin,
201*c8dee2aaSAndroid Build Coastguard Worker                     isProtected);
202*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, (betMipmapped == Mipmapped::kYes) == image->hasMipmaps());
203*c8dee2aaSAndroid Build Coastguard Worker 
204*c8dee2aaSAndroid Build Coastguard Worker             GrTextureProxy* proxy = sk_gpu_test::GetTextureImageProxy(image.get(), dContext);
205*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, proxy);
206*c8dee2aaSAndroid Build Coastguard Worker             if (!proxy) {
207*c8dee2aaSAndroid Build Coastguard Worker                 return;
208*c8dee2aaSAndroid Build Coastguard Worker             }
209*c8dee2aaSAndroid Build Coastguard Worker 
210*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, proxy->isInstantiated());
211*c8dee2aaSAndroid Build Coastguard Worker 
212*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<GrTexture> texture = sk_ref_sp(proxy->peekTexture());
213*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, texture);
214*c8dee2aaSAndroid Build Coastguard Worker             if (!texture) {
215*c8dee2aaSAndroid Build Coastguard Worker                 return;
216*c8dee2aaSAndroid Build Coastguard Worker             }
217*c8dee2aaSAndroid Build Coastguard Worker 
218*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<GrTextureGenerator> textureGen = GrBackendTextureImageGenerator::Make(
219*c8dee2aaSAndroid Build Coastguard Worker                     texture, kTopLeft_GrSurfaceOrigin, nullptr, kRGBA_8888_SkColorType,
220*c8dee2aaSAndroid Build Coastguard Worker                     kPremul_SkAlphaType, nullptr);
221*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, textureGen);
222*c8dee2aaSAndroid Build Coastguard Worker             if (!textureGen) {
223*c8dee2aaSAndroid Build Coastguard Worker                 return;
224*c8dee2aaSAndroid Build Coastguard Worker             }
225*c8dee2aaSAndroid Build Coastguard Worker 
226*c8dee2aaSAndroid Build Coastguard Worker             SkImageInfo imageInfo = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
227*c8dee2aaSAndroid Build Coastguard Worker                                                       kPremul_SkAlphaType);
228*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceProxyView genView = textureGen->generateTexture(
229*c8dee2aaSAndroid Build Coastguard Worker                     dContext, imageInfo, requestMipmapped, GrImageTexGenPolicy::kDraw);
230*c8dee2aaSAndroid Build Coastguard Worker             GrSurfaceProxy* genProxy = genView.proxy();
231*c8dee2aaSAndroid Build Coastguard Worker 
232*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, genProxy);
233*c8dee2aaSAndroid Build Coastguard Worker             if (!genProxy) {
234*c8dee2aaSAndroid Build Coastguard Worker                 return;
235*c8dee2aaSAndroid Build Coastguard Worker             }
236*c8dee2aaSAndroid Build Coastguard Worker 
237*c8dee2aaSAndroid Build Coastguard Worker             if (genProxy->isLazy()) {
238*c8dee2aaSAndroid Build Coastguard Worker                 genProxy->priv().doLazyInstantiation(dContext->priv().resourceProvider());
239*c8dee2aaSAndroid Build Coastguard Worker             } else if (!genProxy->isInstantiated()) {
240*c8dee2aaSAndroid Build Coastguard Worker                 genProxy->instantiate(dContext->priv().resourceProvider());
241*c8dee2aaSAndroid Build Coastguard Worker             }
242*c8dee2aaSAndroid Build Coastguard Worker 
243*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, genProxy->isInstantiated());
244*c8dee2aaSAndroid Build Coastguard Worker             if (!genProxy->isInstantiated()) {
245*c8dee2aaSAndroid Build Coastguard Worker                 return;
246*c8dee2aaSAndroid Build Coastguard Worker             }
247*c8dee2aaSAndroid Build Coastguard Worker 
248*c8dee2aaSAndroid Build Coastguard Worker             GrTexture* genTexture = genProxy->peekTexture();
249*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, genTexture);
250*c8dee2aaSAndroid Build Coastguard Worker             if (!genTexture) {
251*c8dee2aaSAndroid Build Coastguard Worker                 return;
252*c8dee2aaSAndroid Build Coastguard Worker             }
253*c8dee2aaSAndroid Build Coastguard Worker 
254*c8dee2aaSAndroid Build Coastguard Worker             GrBackendTexture backendTex = texture->getBackendTexture();
255*c8dee2aaSAndroid Build Coastguard Worker             GrBackendTexture genBackendTex = genTexture->getBackendTexture();
256*c8dee2aaSAndroid Build Coastguard Worker 
257*c8dee2aaSAndroid Build Coastguard Worker             if (GrBackendApi::kOpenGL == genBackendTex.backend()) {
258*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
259*c8dee2aaSAndroid Build Coastguard Worker                 GrGLTextureInfo genTexInfo;
260*c8dee2aaSAndroid Build Coastguard Worker                 GrGLTextureInfo origTexInfo;
261*c8dee2aaSAndroid Build Coastguard Worker                 if (GrBackendTextures::GetGLTextureInfo(genBackendTex, &genTexInfo) &&
262*c8dee2aaSAndroid Build Coastguard Worker                     GrBackendTextures::GetGLTextureInfo(backendTex, &origTexInfo)) {
263*c8dee2aaSAndroid Build Coastguard Worker                     if (requestMipmapped == Mipmapped::kYes && betMipmapped == Mipmapped::kNo) {
264*c8dee2aaSAndroid Build Coastguard Worker                         // We did a copy so the texture IDs should be different
265*c8dee2aaSAndroid Build Coastguard Worker                         REPORTER_ASSERT(reporter, origTexInfo.fID != genTexInfo.fID);
266*c8dee2aaSAndroid Build Coastguard Worker                     } else {
267*c8dee2aaSAndroid Build Coastguard Worker                         REPORTER_ASSERT(reporter, origTexInfo.fID == genTexInfo.fID);
268*c8dee2aaSAndroid Build Coastguard Worker                     }
269*c8dee2aaSAndroid Build Coastguard Worker                 } else {
270*c8dee2aaSAndroid Build Coastguard Worker                     ERRORF(reporter, "Failed to get GrGLTextureInfo");
271*c8dee2aaSAndroid Build Coastguard Worker                 }
272*c8dee2aaSAndroid Build Coastguard Worker #endif
273*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
274*c8dee2aaSAndroid Build Coastguard Worker             } else if (GrBackendApi::kVulkan == genBackendTex.backend()) {
275*c8dee2aaSAndroid Build Coastguard Worker                 GrVkImageInfo genImageInfo;
276*c8dee2aaSAndroid Build Coastguard Worker                 GrVkImageInfo origImageInfo;
277*c8dee2aaSAndroid Build Coastguard Worker                 if (GrBackendTextures::GetVkImageInfo(genBackendTex, &genImageInfo) &&
278*c8dee2aaSAndroid Build Coastguard Worker                     GrBackendTextures::GetVkImageInfo(backendTex, &origImageInfo)) {
279*c8dee2aaSAndroid Build Coastguard Worker                     if (requestMipmapped == Mipmapped::kYes && betMipmapped == Mipmapped::kNo) {
280*c8dee2aaSAndroid Build Coastguard Worker                         // We did a copy so the texture IDs should be different
281*c8dee2aaSAndroid Build Coastguard Worker                         REPORTER_ASSERT(reporter, origImageInfo.fImage != genImageInfo.fImage);
282*c8dee2aaSAndroid Build Coastguard Worker                     } else {
283*c8dee2aaSAndroid Build Coastguard Worker                         REPORTER_ASSERT(reporter, origImageInfo.fImage == genImageInfo.fImage);
284*c8dee2aaSAndroid Build Coastguard Worker                     }
285*c8dee2aaSAndroid Build Coastguard Worker                 } else {
286*c8dee2aaSAndroid Build Coastguard Worker                     ERRORF(reporter, "Failed to get GrVkImageInfo");
287*c8dee2aaSAndroid Build Coastguard Worker                 }
288*c8dee2aaSAndroid Build Coastguard Worker #endif
289*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_METAL
290*c8dee2aaSAndroid Build Coastguard Worker             } else if (GrBackendApi::kMetal == genBackendTex.backend()) {
291*c8dee2aaSAndroid Build Coastguard Worker                 GrMtlTextureInfo genImageInfo;
292*c8dee2aaSAndroid Build Coastguard Worker                 GrMtlTextureInfo origImageInfo;
293*c8dee2aaSAndroid Build Coastguard Worker                 if (GrBackendTextures::GetMtlTextureInfo(genBackendTex, &genImageInfo) &&
294*c8dee2aaSAndroid Build Coastguard Worker                     GrBackendTextures::GetMtlTextureInfo(backendTex, &origImageInfo)) {
295*c8dee2aaSAndroid Build Coastguard Worker                     if (requestMipmapped == Mipmapped::kYes && betMipmapped == Mipmapped::kNo) {
296*c8dee2aaSAndroid Build Coastguard Worker                         // We did a copy so the texture IDs should be different
297*c8dee2aaSAndroid Build Coastguard Worker                         REPORTER_ASSERT(reporter, origImageInfo.fTexture != genImageInfo.fTexture);
298*c8dee2aaSAndroid Build Coastguard Worker                     } else {
299*c8dee2aaSAndroid Build Coastguard Worker                         REPORTER_ASSERT(reporter, origImageInfo.fTexture == genImageInfo.fTexture);
300*c8dee2aaSAndroid Build Coastguard Worker                     }
301*c8dee2aaSAndroid Build Coastguard Worker                 } else {
302*c8dee2aaSAndroid Build Coastguard Worker                     ERRORF(reporter, "Failed to get GrMtlTextureInfo");
303*c8dee2aaSAndroid Build Coastguard Worker                 }
304*c8dee2aaSAndroid Build Coastguard Worker #endif
305*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DIRECT3D
306*c8dee2aaSAndroid Build Coastguard Worker             } else if (GrBackendApi::kDirect3D == genBackendTex.backend()) {
307*c8dee2aaSAndroid Build Coastguard Worker                 GrD3DTextureResourceInfo genImageInfo;
308*c8dee2aaSAndroid Build Coastguard Worker                 GrD3DTextureResourceInfo origImageInfo;
309*c8dee2aaSAndroid Build Coastguard Worker                 if (genBackendTex.getD3DTextureResourceInfo(&genImageInfo) &&
310*c8dee2aaSAndroid Build Coastguard Worker                     backendTex.getD3DTextureResourceInfo(&origImageInfo)) {
311*c8dee2aaSAndroid Build Coastguard Worker                     if (requestMipmapped == Mipmapped::kYes && betMipmapped == Mipmapped::kNo) {
312*c8dee2aaSAndroid Build Coastguard Worker                         // We did a copy so the texture resources should be different
313*c8dee2aaSAndroid Build Coastguard Worker                         REPORTER_ASSERT(reporter,
314*c8dee2aaSAndroid Build Coastguard Worker                                         origImageInfo.fResource != genImageInfo.fResource);
315*c8dee2aaSAndroid Build Coastguard Worker                     } else {
316*c8dee2aaSAndroid Build Coastguard Worker                         REPORTER_ASSERT(reporter,
317*c8dee2aaSAndroid Build Coastguard Worker                                         origImageInfo.fResource == genImageInfo.fResource);
318*c8dee2aaSAndroid Build Coastguard Worker                     }
319*c8dee2aaSAndroid Build Coastguard Worker                 } else {
320*c8dee2aaSAndroid Build Coastguard Worker                     ERRORF(reporter, "Failed to get GrMtlTextureInfo");
321*c8dee2aaSAndroid Build Coastguard Worker                 }
322*c8dee2aaSAndroid Build Coastguard Worker #endif
323*c8dee2aaSAndroid Build Coastguard Worker             } else {
324*c8dee2aaSAndroid Build Coastguard Worker                 REPORTER_ASSERT(reporter, false);
325*c8dee2aaSAndroid Build Coastguard Worker             }
326*c8dee2aaSAndroid Build Coastguard Worker         }
327*c8dee2aaSAndroid Build Coastguard Worker     }
328*c8dee2aaSAndroid Build Coastguard Worker }
329*c8dee2aaSAndroid Build Coastguard Worker 
330*c8dee2aaSAndroid Build Coastguard Worker // Test that when we call makeImageSnapshot on an SkSurface we retains the same mip status as the
331*c8dee2aaSAndroid Build Coastguard Worker // resource we took the snapshot of.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrImageSnapshotMipMappedTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)332*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrImageSnapshotMipMappedTest,
333*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
334*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
335*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kApiLevel_T) {
336*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = ctxInfo.directContext();
337*c8dee2aaSAndroid Build Coastguard Worker     if (!dContext->priv().caps()->mipmapSupport()) {
338*c8dee2aaSAndroid Build Coastguard Worker         return;
339*c8dee2aaSAndroid Build Coastguard Worker     }
340*c8dee2aaSAndroid Build Coastguard Worker 
341*c8dee2aaSAndroid Build Coastguard Worker     GrProtected isProtected = GrProtected(dContext->priv().caps()->supportsProtectedContent());
342*c8dee2aaSAndroid Build Coastguard Worker 
343*c8dee2aaSAndroid Build Coastguard Worker     auto resourceProvider = dContext->priv().resourceProvider();
344*c8dee2aaSAndroid Build Coastguard Worker 
345*c8dee2aaSAndroid Build Coastguard Worker     for (auto willUseMips : {false, true}) {
346*c8dee2aaSAndroid Build Coastguard Worker         for (auto isWrapped : {false, true}) {
347*c8dee2aaSAndroid Build Coastguard Worker             skgpu::Mipmapped mipmapped =
348*c8dee2aaSAndroid Build Coastguard Worker                     willUseMips ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
349*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkSurface> surface;
350*c8dee2aaSAndroid Build Coastguard Worker             SkImageInfo info =
351*c8dee2aaSAndroid Build Coastguard Worker                     SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
352*c8dee2aaSAndroid Build Coastguard Worker             if (isWrapped) {
353*c8dee2aaSAndroid Build Coastguard Worker                 surface = sk_gpu_test::MakeBackendTextureSurface(dContext,
354*c8dee2aaSAndroid Build Coastguard Worker                                                                  info,
355*c8dee2aaSAndroid Build Coastguard Worker                                                                  kTopLeft_GrSurfaceOrigin,
356*c8dee2aaSAndroid Build Coastguard Worker                                                                  /* sample count */ 1,
357*c8dee2aaSAndroid Build Coastguard Worker                                                                  mipmapped,
358*c8dee2aaSAndroid Build Coastguard Worker                                                                  isProtected);
359*c8dee2aaSAndroid Build Coastguard Worker             } else {
360*c8dee2aaSAndroid Build Coastguard Worker                 surface = SkSurfaces::RenderTarget(dContext,
361*c8dee2aaSAndroid Build Coastguard Worker                                                    skgpu::Budgeted::kYes,
362*c8dee2aaSAndroid Build Coastguard Worker                                                    info,
363*c8dee2aaSAndroid Build Coastguard Worker                                                    /* sample count */ 1,
364*c8dee2aaSAndroid Build Coastguard Worker                                                    kTopLeft_GrSurfaceOrigin,
365*c8dee2aaSAndroid Build Coastguard Worker                                                    nullptr,
366*c8dee2aaSAndroid Build Coastguard Worker                                                    willUseMips);
367*c8dee2aaSAndroid Build Coastguard Worker             }
368*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, surface);
369*c8dee2aaSAndroid Build Coastguard Worker             auto device = ((SkSurface_Ganesh*)surface.get())->getDevice();
370*c8dee2aaSAndroid Build Coastguard Worker             GrTextureProxy* texProxy = device->readSurfaceView().asTextureProxy();
371*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, mipmapped == texProxy->mipmapped());
372*c8dee2aaSAndroid Build Coastguard Worker 
373*c8dee2aaSAndroid Build Coastguard Worker             texProxy->instantiate(resourceProvider);
374*c8dee2aaSAndroid Build Coastguard Worker             GrTexture* texture = texProxy->peekTexture();
375*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, mipmapped == texture->mipmapped());
376*c8dee2aaSAndroid Build Coastguard Worker 
377*c8dee2aaSAndroid Build Coastguard Worker             sk_sp<SkImage> image = surface->makeImageSnapshot();
378*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, willUseMips == image->hasMipmaps());
379*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, image);
380*c8dee2aaSAndroid Build Coastguard Worker             texProxy = sk_gpu_test::GetTextureImageProxy(image.get(), dContext);
381*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, mipmapped == texProxy->mipmapped());
382*c8dee2aaSAndroid Build Coastguard Worker 
383*c8dee2aaSAndroid Build Coastguard Worker             texProxy->instantiate(resourceProvider);
384*c8dee2aaSAndroid Build Coastguard Worker             texture = texProxy->peekTexture();
385*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, mipmapped == texture->mipmapped());
386*c8dee2aaSAndroid Build Coastguard Worker         }
387*c8dee2aaSAndroid Build Coastguard Worker     }
388*c8dee2aaSAndroid Build Coastguard Worker }
389*c8dee2aaSAndroid Build Coastguard Worker 
390*c8dee2aaSAndroid Build Coastguard Worker // Test that we don't create a mip mapped texture if the size is 1x1 even if the filter mode is set
391*c8dee2aaSAndroid Build Coastguard Worker // to use mips. This test passes by not crashing or hitting asserts in code.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(Gr1x1TextureMipMappedTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)392*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(Gr1x1TextureMipMappedTest,
393*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
394*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
395*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kApiLevel_T) {
396*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = ctxInfo.directContext();
397*c8dee2aaSAndroid Build Coastguard Worker     if (!dContext->priv().caps()->mipmapSupport()) {
398*c8dee2aaSAndroid Build Coastguard Worker         return;
399*c8dee2aaSAndroid Build Coastguard Worker     }
400*c8dee2aaSAndroid Build Coastguard Worker 
401*c8dee2aaSAndroid Build Coastguard Worker     // Make surface to draw into
402*c8dee2aaSAndroid Build Coastguard Worker     SkImageInfo info = SkImageInfo::MakeN32(16, 16, kPremul_SkAlphaType);
403*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kNo, info);
404*c8dee2aaSAndroid Build Coastguard Worker 
405*c8dee2aaSAndroid Build Coastguard Worker     // Make 1x1 raster bitmap
406*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap bmp;
407*c8dee2aaSAndroid Build Coastguard Worker     bmp.allocN32Pixels(1, 1);
408*c8dee2aaSAndroid Build Coastguard Worker     SkPMColor* pixel = reinterpret_cast<SkPMColor*>(bmp.getPixels());
409*c8dee2aaSAndroid Build Coastguard Worker     *pixel = 0;
410*c8dee2aaSAndroid Build Coastguard Worker 
411*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImage> bmpImage = bmp.asImage();
412*c8dee2aaSAndroid Build Coastguard Worker 
413*c8dee2aaSAndroid Build Coastguard Worker     // Make sure we scale so we don't optimize out the use of mips.
414*c8dee2aaSAndroid Build Coastguard Worker     surface->getCanvas()->scale(0.5f, 0.5f);
415*c8dee2aaSAndroid Build Coastguard Worker 
416*c8dee2aaSAndroid Build Coastguard Worker     // This should upload the image to a non mipped GrTextureProxy.
417*c8dee2aaSAndroid Build Coastguard Worker     surface->getCanvas()->drawImage(bmpImage, 0, 0);
418*c8dee2aaSAndroid Build Coastguard Worker     dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
419*c8dee2aaSAndroid Build Coastguard Worker 
420*c8dee2aaSAndroid Build Coastguard Worker     // Now set the filter quality to high so we use mip maps. We should find the non mipped texture
421*c8dee2aaSAndroid Build Coastguard Worker     // in the cache for the SkImage. Since the texture is 1x1 we should just use that texture
422*c8dee2aaSAndroid Build Coastguard Worker     // instead of trying to do a copy to a mipped texture.
423*c8dee2aaSAndroid Build Coastguard Worker     surface->getCanvas()->drawImage(bmpImage, 0, 0, SkSamplingOptions({1.0f/3, 1.0f/3}));
424*c8dee2aaSAndroid Build Coastguard Worker     dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
425*c8dee2aaSAndroid Build Coastguard Worker }
426*c8dee2aaSAndroid Build Coastguard Worker 
427*c8dee2aaSAndroid Build Coastguard Worker // Create a new render target and draw 'mipmapView' into it using the provided 'filter'.
draw_mipmap_into_new_render_target(GrRecordingContext * rContext,GrColorType colorType,SkAlphaType alphaType,GrSurfaceProxyView mipmapView,GrSamplerState::MipmapMode mm)428*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<skgpu::ganesh::SurfaceDrawContext> draw_mipmap_into_new_render_target(
429*c8dee2aaSAndroid Build Coastguard Worker         GrRecordingContext* rContext,
430*c8dee2aaSAndroid Build Coastguard Worker         GrColorType colorType,
431*c8dee2aaSAndroid Build Coastguard Worker         SkAlphaType alphaType,
432*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceProxyView mipmapView,
433*c8dee2aaSAndroid Build Coastguard Worker         GrSamplerState::MipmapMode mm) {
434*c8dee2aaSAndroid Build Coastguard Worker     auto proxyProvider = rContext->priv().proxyProvider();
435*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrSurfaceProxy> renderTarget =
436*c8dee2aaSAndroid Build Coastguard Worker             proxyProvider->createProxy(mipmapView.proxy()->backendFormat(),
437*c8dee2aaSAndroid Build Coastguard Worker                                        {1, 1},
438*c8dee2aaSAndroid Build Coastguard Worker                                        GrRenderable::kYes,
439*c8dee2aaSAndroid Build Coastguard Worker                                        1,
440*c8dee2aaSAndroid Build Coastguard Worker                                        skgpu::Mipmapped::kNo,
441*c8dee2aaSAndroid Build Coastguard Worker                                        SkBackingFit::kApprox,
442*c8dee2aaSAndroid Build Coastguard Worker                                        skgpu::Budgeted::kYes,
443*c8dee2aaSAndroid Build Coastguard Worker                                        GrProtected::kNo,
444*c8dee2aaSAndroid Build Coastguard Worker                                        /*label=*/"DrawMipMapViewTest");
445*c8dee2aaSAndroid Build Coastguard Worker 
446*c8dee2aaSAndroid Build Coastguard Worker     auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(rContext,
447*c8dee2aaSAndroid Build Coastguard Worker                                                        colorType,
448*c8dee2aaSAndroid Build Coastguard Worker                                                        std::move(renderTarget),
449*c8dee2aaSAndroid Build Coastguard Worker                                                        nullptr,
450*c8dee2aaSAndroid Build Coastguard Worker                                                        kTopLeft_GrSurfaceOrigin,
451*c8dee2aaSAndroid Build Coastguard Worker                                                        SkSurfaceProps());
452*c8dee2aaSAndroid Build Coastguard Worker 
453*c8dee2aaSAndroid Build Coastguard Worker     sdc->drawTexture(nullptr,
454*c8dee2aaSAndroid Build Coastguard Worker                      std::move(mipmapView),
455*c8dee2aaSAndroid Build Coastguard Worker                      alphaType,
456*c8dee2aaSAndroid Build Coastguard Worker                      GrSamplerState::Filter::kLinear,
457*c8dee2aaSAndroid Build Coastguard Worker                      mm,
458*c8dee2aaSAndroid Build Coastguard Worker                      SkBlendMode::kSrcOver,
459*c8dee2aaSAndroid Build Coastguard Worker                      {1, 1, 1, 1},
460*c8dee2aaSAndroid Build Coastguard Worker                      SkRect::MakeWH(4, 4),
461*c8dee2aaSAndroid Build Coastguard Worker                      SkRect::MakeWH(1, 1),
462*c8dee2aaSAndroid Build Coastguard Worker                      GrQuadAAFlags::kAll,
463*c8dee2aaSAndroid Build Coastguard Worker                      SkCanvas::kFast_SrcRectConstraint,
464*c8dee2aaSAndroid Build Coastguard Worker                      SkMatrix::I(),
465*c8dee2aaSAndroid Build Coastguard Worker                      nullptr);
466*c8dee2aaSAndroid Build Coastguard Worker     return sdc;
467*c8dee2aaSAndroid Build Coastguard Worker }
468*c8dee2aaSAndroid Build Coastguard Worker 
469*c8dee2aaSAndroid Build Coastguard Worker // Test that two opsTasks using the same mipmaps both depend on the same GrTextureResolveRenderTask.
470*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(GrManyDependentsMipMappedTest,
471*c8dee2aaSAndroid Build Coastguard Worker                 reporter,
472*c8dee2aaSAndroid Build Coastguard Worker                 /* options */,
473*c8dee2aaSAndroid Build Coastguard Worker                 CtsEnforcement::kApiLevel_T) {
474*c8dee2aaSAndroid Build Coastguard Worker     using Enable = GrContextOptions::Enable;
475*c8dee2aaSAndroid Build Coastguard Worker     using MipmapMode = GrSamplerState::MipmapMode;
476*c8dee2aaSAndroid Build Coastguard Worker 
477*c8dee2aaSAndroid Build Coastguard Worker     for (auto enableSortingAndReduction : {Enable::kYes, Enable::kNo}) {
478*c8dee2aaSAndroid Build Coastguard Worker         GrMockOptions mockOptions;
479*c8dee2aaSAndroid Build Coastguard Worker         mockOptions.fMipmapSupport = true;
480*c8dee2aaSAndroid Build Coastguard Worker         GrContextOptions ctxOptions;
481*c8dee2aaSAndroid Build Coastguard Worker         ctxOptions.fReduceOpsTaskSplitting = enableSortingAndReduction;
482*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<GrDirectContext> dContext = GrDirectContext::MakeMock(&mockOptions, ctxOptions);
483*c8dee2aaSAndroid Build Coastguard Worker         GrDrawingManager* drawingManager = dContext->priv().drawingManager();
484*c8dee2aaSAndroid Build Coastguard Worker         if (!dContext) {
485*c8dee2aaSAndroid Build Coastguard Worker             ERRORF(reporter, "could not create mock dContext with fReduceOpsTaskSplitting %s.",
486*c8dee2aaSAndroid Build Coastguard Worker                    (Enable::kYes == enableSortingAndReduction) ? "enabled" : "disabled");
487*c8dee2aaSAndroid Build Coastguard Worker             continue;
488*c8dee2aaSAndroid Build Coastguard Worker         }
489*c8dee2aaSAndroid Build Coastguard Worker 
490*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(dContext->priv().caps()->mipmapSupport());
491*c8dee2aaSAndroid Build Coastguard Worker 
492*c8dee2aaSAndroid Build Coastguard Worker         GrBackendFormat format = dContext->defaultBackendFormat(
493*c8dee2aaSAndroid Build Coastguard Worker                 kRGBA_8888_SkColorType, GrRenderable::kYes);
494*c8dee2aaSAndroid Build Coastguard Worker         GrColorType colorType = GrColorType::kRGBA_8888;
495*c8dee2aaSAndroid Build Coastguard Worker         SkAlphaType alphaType = kPremul_SkAlphaType;
496*c8dee2aaSAndroid Build Coastguard Worker 
497*c8dee2aaSAndroid Build Coastguard Worker         GrProxyProvider* proxyProvider = dContext->priv().proxyProvider();
498*c8dee2aaSAndroid Build Coastguard Worker 
499*c8dee2aaSAndroid Build Coastguard Worker         // Create a mipmapped render target.
500*c8dee2aaSAndroid Build Coastguard Worker 
501*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<GrTextureProxy> mipmapProxy =
502*c8dee2aaSAndroid Build Coastguard Worker                 proxyProvider->createProxy(format,
503*c8dee2aaSAndroid Build Coastguard Worker                                            {4, 4},
504*c8dee2aaSAndroid Build Coastguard Worker                                            GrRenderable::kYes,
505*c8dee2aaSAndroid Build Coastguard Worker                                            1,
506*c8dee2aaSAndroid Build Coastguard Worker                                            skgpu::Mipmapped::kYes,
507*c8dee2aaSAndroid Build Coastguard Worker                                            SkBackingFit::kExact,
508*c8dee2aaSAndroid Build Coastguard Worker                                            skgpu::Budgeted::kYes,
509*c8dee2aaSAndroid Build Coastguard Worker                                            GrProtected::kNo,
510*c8dee2aaSAndroid Build Coastguard Worker                                            /*label=*/"ManyDependentsMipMappedTest");
511*c8dee2aaSAndroid Build Coastguard Worker 
512*c8dee2aaSAndroid Build Coastguard Worker         // Mark the mipmaps clean to ensure things still work properly when they won't be marked
513*c8dee2aaSAndroid Build Coastguard Worker         // dirty again until GrRenderTask::makeClosed().
514*c8dee2aaSAndroid Build Coastguard Worker         mipmapProxy->markMipmapsClean();
515*c8dee2aaSAndroid Build Coastguard Worker 
516*c8dee2aaSAndroid Build Coastguard Worker         auto mipmapSDC = skgpu::ganesh::SurfaceDrawContext::Make(dContext.get(),
517*c8dee2aaSAndroid Build Coastguard Worker                                                                  colorType,
518*c8dee2aaSAndroid Build Coastguard Worker                                                                  mipmapProxy,
519*c8dee2aaSAndroid Build Coastguard Worker                                                                  nullptr,
520*c8dee2aaSAndroid Build Coastguard Worker                                                                  kTopLeft_GrSurfaceOrigin,
521*c8dee2aaSAndroid Build Coastguard Worker                                                                  SkSurfaceProps());
522*c8dee2aaSAndroid Build Coastguard Worker 
523*c8dee2aaSAndroid Build Coastguard Worker         mipmapSDC->clear(SkPMColor4f{.1f, .2f, .3f, .4f});
524*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, drawingManager->getLastRenderTask(mipmapProxy.get()));
525*c8dee2aaSAndroid Build Coastguard Worker         // mipmapProxy's last render task should now just be the opsTask containing the clear.
526*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,
527*c8dee2aaSAndroid Build Coastguard Worker                 mipmapSDC->testingOnly_PeekLastOpsTask() ==
528*c8dee2aaSAndroid Build Coastguard Worker                         drawingManager->getLastRenderTask(mipmapProxy.get()));
529*c8dee2aaSAndroid Build Coastguard Worker 
530*c8dee2aaSAndroid Build Coastguard Worker         // Mipmaps don't get marked dirty until makeClosed().
531*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !mipmapProxy->mipmapsAreDirty());
532*c8dee2aaSAndroid Build Coastguard Worker 
533*c8dee2aaSAndroid Build Coastguard Worker         skgpu::Swizzle swizzle = dContext->priv().caps()->getReadSwizzle(format, colorType);
534*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceProxyView mipmapView(mipmapProxy, kTopLeft_GrSurfaceOrigin, swizzle);
535*c8dee2aaSAndroid Build Coastguard Worker 
536*c8dee2aaSAndroid Build Coastguard Worker         // Draw the dirty mipmap texture into a render target.
537*c8dee2aaSAndroid Build Coastguard Worker         auto sdc1 = draw_mipmap_into_new_render_target(dContext.get(), colorType, alphaType,
538*c8dee2aaSAndroid Build Coastguard Worker                                                        mipmapView, MipmapMode::kLinear);
539*c8dee2aaSAndroid Build Coastguard Worker         auto sdc1Task = sk_ref_sp(sdc1->testingOnly_PeekLastOpsTask());
540*c8dee2aaSAndroid Build Coastguard Worker 
541*c8dee2aaSAndroid Build Coastguard Worker         // Mipmaps should have gotten marked dirty during makeClosed, then marked clean again as
542*c8dee2aaSAndroid Build Coastguard Worker         // soon as a GrTextureResolveRenderTask was inserted. The way we know they were resolved is
543*c8dee2aaSAndroid Build Coastguard Worker         // if mipmapProxy->getLastRenderTask() has switched from the opsTask that drew to it, to the
544*c8dee2aaSAndroid Build Coastguard Worker         // task that resolved its mips.
545*c8dee2aaSAndroid Build Coastguard Worker         GrRenderTask* initialMipmapRegenTask = drawingManager->getLastRenderTask(mipmapProxy.get());
546*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, initialMipmapRegenTask);
547*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,
548*c8dee2aaSAndroid Build Coastguard Worker                 initialMipmapRegenTask != mipmapSDC->testingOnly_PeekLastOpsTask());
549*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !mipmapProxy->mipmapsAreDirty());
550*c8dee2aaSAndroid Build Coastguard Worker 
551*c8dee2aaSAndroid Build Coastguard Worker         // Draw the now-clean mipmap texture into a second target.
552*c8dee2aaSAndroid Build Coastguard Worker         auto sdc2 = draw_mipmap_into_new_render_target(dContext.get(), colorType, alphaType,
553*c8dee2aaSAndroid Build Coastguard Worker                                                        mipmapView, MipmapMode::kLinear);
554*c8dee2aaSAndroid Build Coastguard Worker         auto sdc2Task = sk_ref_sp(sdc2->testingOnly_PeekLastOpsTask());
555*c8dee2aaSAndroid Build Coastguard Worker 
556*c8dee2aaSAndroid Build Coastguard Worker         // Make sure the mipmap texture still has the same regen task.
557*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,
558*c8dee2aaSAndroid Build Coastguard Worker                     drawingManager->getLastRenderTask(mipmapProxy.get()) == initialMipmapRegenTask);
559*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!mipmapProxy->mipmapsAreDirty());
560*c8dee2aaSAndroid Build Coastguard Worker 
561*c8dee2aaSAndroid Build Coastguard Worker         // Reset everything so we can go again, this time with the first draw not mipmapped.
562*c8dee2aaSAndroid Build Coastguard Worker         dContext->flushAndSubmit();
563*c8dee2aaSAndroid Build Coastguard Worker 
564*c8dee2aaSAndroid Build Coastguard Worker         // Mip regen tasks don't get added as dependencies until makeClosed().
565*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, sdc1Task->dependsOn(initialMipmapRegenTask));
566*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, sdc2Task->dependsOn(initialMipmapRegenTask));
567*c8dee2aaSAndroid Build Coastguard Worker 
568*c8dee2aaSAndroid Build Coastguard Worker         // Render something to dirty the mips.
569*c8dee2aaSAndroid Build Coastguard Worker         mipmapSDC->clear(SkPMColor4f{.1f, .2f, .3f, .4f});
570*c8dee2aaSAndroid Build Coastguard Worker         auto mipmapRTCTask = sk_ref_sp(mipmapSDC->testingOnly_PeekLastOpsTask());
571*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, mipmapRTCTask);
572*c8dee2aaSAndroid Build Coastguard Worker 
573*c8dee2aaSAndroid Build Coastguard Worker         // mipmapProxy's last render task should now just be the opsTask containing the clear.
574*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,
575*c8dee2aaSAndroid Build Coastguard Worker                     mipmapRTCTask.get() == drawingManager->getLastRenderTask(mipmapProxy.get()));
576*c8dee2aaSAndroid Build Coastguard Worker 
577*c8dee2aaSAndroid Build Coastguard Worker         // Mipmaps don't get marked dirty until makeClosed().
578*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !mipmapProxy->mipmapsAreDirty());
579*c8dee2aaSAndroid Build Coastguard Worker 
580*c8dee2aaSAndroid Build Coastguard Worker         // Draw the dirty mipmap texture into a render target, but don't do mipmap filtering.
581*c8dee2aaSAndroid Build Coastguard Worker         sdc1 = draw_mipmap_into_new_render_target(dContext.get(), colorType, alphaType,
582*c8dee2aaSAndroid Build Coastguard Worker                                                   mipmapView, MipmapMode::kNone);
583*c8dee2aaSAndroid Build Coastguard Worker 
584*c8dee2aaSAndroid Build Coastguard Worker         // Mipmaps should have gotten marked dirty during makeClosed() when adding the dependency.
585*c8dee2aaSAndroid Build Coastguard Worker         // Since the last draw did not use mips, they will not have been regenerated and should
586*c8dee2aaSAndroid Build Coastguard Worker         // therefore still be dirty.
587*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, mipmapProxy->mipmapsAreDirty());
588*c8dee2aaSAndroid Build Coastguard Worker 
589*c8dee2aaSAndroid Build Coastguard Worker         // Since mips weren't regenerated, the last render task shouldn't have changed.
590*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter,
591*c8dee2aaSAndroid Build Coastguard Worker                     mipmapRTCTask.get() == drawingManager->getLastRenderTask(mipmapProxy.get()));
592*c8dee2aaSAndroid Build Coastguard Worker 
593*c8dee2aaSAndroid Build Coastguard Worker         // Draw the stil-dirty mipmap texture into a second target with mipmap filtering.
594*c8dee2aaSAndroid Build Coastguard Worker         sdc2 = draw_mipmap_into_new_render_target(dContext.get(), colorType, alphaType,
595*c8dee2aaSAndroid Build Coastguard Worker                                                   std::move(mipmapView), MipmapMode::kLinear);
596*c8dee2aaSAndroid Build Coastguard Worker         sdc2Task = sk_ref_sp(sdc2->testingOnly_PeekLastOpsTask());
597*c8dee2aaSAndroid Build Coastguard Worker 
598*c8dee2aaSAndroid Build Coastguard Worker         // Make sure the mipmap texture now has a new last render task that regenerates the mips,
599*c8dee2aaSAndroid Build Coastguard Worker         // and that the mipmaps are now clean.
600*c8dee2aaSAndroid Build Coastguard Worker         auto mipRegenTask2 = drawingManager->getLastRenderTask(mipmapProxy.get());
601*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, mipRegenTask2);
602*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, mipmapRTCTask.get() != mipRegenTask2);
603*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!mipmapProxy->mipmapsAreDirty());
604*c8dee2aaSAndroid Build Coastguard Worker 
605*c8dee2aaSAndroid Build Coastguard Worker         // Mip regen tasks don't get added as dependencies until makeClosed().
606*c8dee2aaSAndroid Build Coastguard Worker         dContext->flushAndSubmit();
607*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, sdc2Task->dependsOn(mipRegenTask2));
608*c8dee2aaSAndroid Build Coastguard Worker     }
609*c8dee2aaSAndroid Build Coastguard Worker }
610