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