xref: /aosp_15_r20/external/skia/tests/TextureBindingsResetTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2019 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 "tests/Test.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkAlphaType.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSamplingOptions.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkImageGanesh.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLFunctions.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLInterface.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLTypes.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTDArray.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpu.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrShaderCaps.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLCaps.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLDefines.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLGpu.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLUtil.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/gl/GLTestContext.h"
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker struct GrContextOptions;
47*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_GL_CONTEXT(TextureBindingsResetTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)48*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_GL_CONTEXT(TextureBindingsResetTest,
49*c8dee2aaSAndroid Build Coastguard Worker                                reporter,
50*c8dee2aaSAndroid Build Coastguard Worker                                ctxInfo,
51*c8dee2aaSAndroid Build Coastguard Worker                                CtsEnforcement::kApiLevel_T) {
52*c8dee2aaSAndroid Build Coastguard Worker #define GL(F) GR_GL_CALL(ctxInfo.glContext()->gl(), F)
53*c8dee2aaSAndroid Build Coastguard Worker 
54*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = ctxInfo.directContext();
55*c8dee2aaSAndroid Build Coastguard Worker     GrGpu* gpu = dContext->priv().getGpu();
56*c8dee2aaSAndroid Build Coastguard Worker     GrGLGpu* glGpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
57*c8dee2aaSAndroid Build Coastguard Worker 
58*c8dee2aaSAndroid Build Coastguard Worker     struct Target {
59*c8dee2aaSAndroid Build Coastguard Worker         GrGLenum fName;
60*c8dee2aaSAndroid Build Coastguard Worker         GrGLenum fQuery;
61*c8dee2aaSAndroid Build Coastguard Worker     };
62*c8dee2aaSAndroid Build Coastguard Worker     SkTDArray<Target> targets;
63*c8dee2aaSAndroid Build Coastguard Worker     targets.push_back({GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BINDING_2D});
64*c8dee2aaSAndroid Build Coastguard Worker     bool supportExternal;
65*c8dee2aaSAndroid Build Coastguard Worker     if ((supportExternal = glGpu->glCaps().shaderCaps()->fExternalTextureSupport)) {
66*c8dee2aaSAndroid Build Coastguard Worker         targets.push_back({GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_BINDING_EXTERNAL});
67*c8dee2aaSAndroid Build Coastguard Worker     }
68*c8dee2aaSAndroid Build Coastguard Worker     bool supportRectangle;
69*c8dee2aaSAndroid Build Coastguard Worker     if ((supportRectangle = glGpu->glCaps().rectangleTextureSupport())) {
70*c8dee2aaSAndroid Build Coastguard Worker         targets.push_back({GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_BINDING_RECTANGLE});
71*c8dee2aaSAndroid Build Coastguard Worker     }
72*c8dee2aaSAndroid Build Coastguard Worker     GrGLint numUnits = 0;
73*c8dee2aaSAndroid Build Coastguard Worker     GL(GetIntegerv(GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numUnits));
74*c8dee2aaSAndroid Build Coastguard Worker     SkTDArray<GrGLuint> claimedIDs;
75*c8dee2aaSAndroid Build Coastguard Worker     claimedIDs.resize(numUnits * targets.size());
76*c8dee2aaSAndroid Build Coastguard Worker     GL(GenTextures(claimedIDs.size(), claimedIDs.begin()));
77*c8dee2aaSAndroid Build Coastguard Worker 
78*c8dee2aaSAndroid Build Coastguard Worker     auto resetBindings = [&] {
79*c8dee2aaSAndroid Build Coastguard Worker         int i = 0;
80*c8dee2aaSAndroid Build Coastguard Worker         for (int u = 0; u < numUnits; ++u) {
81*c8dee2aaSAndroid Build Coastguard Worker             GL(ActiveTexture(GR_GL_TEXTURE0 + u));
82*c8dee2aaSAndroid Build Coastguard Worker             for (auto target : targets) {
83*c8dee2aaSAndroid Build Coastguard Worker                 GL(BindTexture(target.fName, claimedIDs[i++]));
84*c8dee2aaSAndroid Build Coastguard Worker             }
85*c8dee2aaSAndroid Build Coastguard Worker         }
86*c8dee2aaSAndroid Build Coastguard Worker     };
87*c8dee2aaSAndroid Build Coastguard Worker     auto checkBindings = [&] {
88*c8dee2aaSAndroid Build Coastguard Worker         int i = 0;
89*c8dee2aaSAndroid Build Coastguard Worker         for (int u = 0; u < numUnits; ++u) {
90*c8dee2aaSAndroid Build Coastguard Worker             GL(ActiveTexture(GR_GL_TEXTURE0 + u));
91*c8dee2aaSAndroid Build Coastguard Worker             for (auto target : targets) {
92*c8dee2aaSAndroid Build Coastguard Worker                 GrGLint boundID = -1;
93*c8dee2aaSAndroid Build Coastguard Worker                 GL(GetIntegerv(target.fQuery, &boundID));
94*c8dee2aaSAndroid Build Coastguard Worker                 if (boundID != (int) claimedIDs[i] && boundID != 0) {
95*c8dee2aaSAndroid Build Coastguard Worker                     ERRORF(reporter, "Unit %d, target 0x%04x has ID %d bound. Expected %u or 0.", u,
96*c8dee2aaSAndroid Build Coastguard Worker                            target.fName, boundID, claimedIDs[i]);
97*c8dee2aaSAndroid Build Coastguard Worker                     return;
98*c8dee2aaSAndroid Build Coastguard Worker                 }
99*c8dee2aaSAndroid Build Coastguard Worker                 ++i;
100*c8dee2aaSAndroid Build Coastguard Worker             }
101*c8dee2aaSAndroid Build Coastguard Worker         }
102*c8dee2aaSAndroid Build Coastguard Worker     };
103*c8dee2aaSAndroid Build Coastguard Worker 
104*c8dee2aaSAndroid Build Coastguard Worker     // Initialize texture unit/target combo bindings to 0.
105*c8dee2aaSAndroid Build Coastguard Worker     dContext->flushAndSubmit();
106*c8dee2aaSAndroid Build Coastguard Worker     resetBindings();
107*c8dee2aaSAndroid Build Coastguard Worker     dContext->resetContext();
108*c8dee2aaSAndroid Build Coastguard Worker 
109*c8dee2aaSAndroid Build Coastguard Worker     // Test creating a texture and then resetting bindings.
110*c8dee2aaSAndroid Build Coastguard Worker     static constexpr SkISize kDims = {10, 10};
111*c8dee2aaSAndroid Build Coastguard Worker     GrBackendFormat format = gpu->caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
112*c8dee2aaSAndroid Build Coastguard Worker                                                                   GrRenderable::kNo);
113*c8dee2aaSAndroid Build Coastguard Worker     auto tex = gpu->createTexture(kDims,
114*c8dee2aaSAndroid Build Coastguard Worker                                   format,
115*c8dee2aaSAndroid Build Coastguard Worker                                   GrTextureType::k2D,
116*c8dee2aaSAndroid Build Coastguard Worker                                   GrRenderable::kNo,
117*c8dee2aaSAndroid Build Coastguard Worker                                   1,
118*c8dee2aaSAndroid Build Coastguard Worker                                   skgpu::Mipmapped::kNo,
119*c8dee2aaSAndroid Build Coastguard Worker                                   skgpu::Budgeted::kNo,
120*c8dee2aaSAndroid Build Coastguard Worker                                   GrProtected::kNo,
121*c8dee2aaSAndroid Build Coastguard Worker                                   /*label=*/"TextureBindingsResetTest");
122*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, tex);
123*c8dee2aaSAndroid Build Coastguard Worker     dContext->resetGLTextureBindings();
124*c8dee2aaSAndroid Build Coastguard Worker     checkBindings();
125*c8dee2aaSAndroid Build Coastguard Worker     resetBindings();
126*c8dee2aaSAndroid Build Coastguard Worker     dContext->resetContext();
127*c8dee2aaSAndroid Build Coastguard Worker 
128*c8dee2aaSAndroid Build Coastguard Worker     // Test drawing and then resetting bindings. This should force a MIP regeneration if MIP
129*c8dee2aaSAndroid Build Coastguard Worker     // maps are supported as well.
130*c8dee2aaSAndroid Build Coastguard Worker     auto info = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
131*c8dee2aaSAndroid Build Coastguard Worker     auto surf = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kYes, info, 1, nullptr);
132*c8dee2aaSAndroid Build Coastguard Worker     surf->getCanvas()->clear(0x80FF0000);
133*c8dee2aaSAndroid Build Coastguard Worker     auto img = surf->makeImageSnapshot();
134*c8dee2aaSAndroid Build Coastguard Worker     surf->getCanvas()->clear(SK_ColorBLUE);
135*c8dee2aaSAndroid Build Coastguard Worker     surf->getCanvas()->save();
136*c8dee2aaSAndroid Build Coastguard Worker     surf->getCanvas()->scale(0.25, 0.25);
137*c8dee2aaSAndroid Build Coastguard Worker     surf->getCanvas()->drawImage(img.get(), 0, 0, SkSamplingOptions({1.0f/3, 1.0f/3}), nullptr);
138*c8dee2aaSAndroid Build Coastguard Worker     surf->getCanvas()->restore();
139*c8dee2aaSAndroid Build Coastguard Worker     dContext->flushAndSubmit(surf.get(), GrSyncCpu::kNo);
140*c8dee2aaSAndroid Build Coastguard Worker     dContext->resetGLTextureBindings();
141*c8dee2aaSAndroid Build Coastguard Worker     checkBindings();
142*c8dee2aaSAndroid Build Coastguard Worker     resetBindings();
143*c8dee2aaSAndroid Build Coastguard Worker     dContext->resetContext();
144*c8dee2aaSAndroid Build Coastguard Worker 
145*c8dee2aaSAndroid Build Coastguard Worker     if (supportExternal) {
146*c8dee2aaSAndroid Build Coastguard Worker         GrBackendTexture texture2D = dContext->createBackendTexture(10,
147*c8dee2aaSAndroid Build Coastguard Worker                                                                     10,
148*c8dee2aaSAndroid Build Coastguard Worker                                                                     kRGBA_8888_SkColorType,
149*c8dee2aaSAndroid Build Coastguard Worker                                                                     SkColors::kTransparent,
150*c8dee2aaSAndroid Build Coastguard Worker                                                                     skgpu::Mipmapped::kNo,
151*c8dee2aaSAndroid Build Coastguard Worker                                                                     GrRenderable::kNo,
152*c8dee2aaSAndroid Build Coastguard Worker                                                                     GrProtected::kNo);
153*c8dee2aaSAndroid Build Coastguard Worker         GrGLTextureInfo info2D;
154*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, GrBackendTextures::GetGLTextureInfo(texture2D, &info2D));
155*c8dee2aaSAndroid Build Coastguard Worker         GrEGLImage eglImage = ctxInfo.glContext()->texture2DToEGLImage(info2D.fID);
156*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, eglImage);
157*c8dee2aaSAndroid Build Coastguard Worker         GrGLTextureInfo infoExternal;
158*c8dee2aaSAndroid Build Coastguard Worker         infoExternal.fID = ctxInfo.glContext()->eglImageToExternalTexture(eglImage);
159*c8dee2aaSAndroid Build Coastguard Worker         infoExternal.fTarget = GR_GL_TEXTURE_EXTERNAL;
160*c8dee2aaSAndroid Build Coastguard Worker         infoExternal.fFormat = info2D.fFormat;
161*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, infoExternal.fID);
162*c8dee2aaSAndroid Build Coastguard Worker         infoExternal.fProtected = info2D.fProtected;
163*c8dee2aaSAndroid Build Coastguard Worker         GrBackendTexture backendTexture =
164*c8dee2aaSAndroid Build Coastguard Worker                 GrBackendTextures::MakeGL(10, 10, skgpu::Mipmapped::kNo, infoExternal);
165*c8dee2aaSAndroid Build Coastguard Worker         // Above texture creation will have messed with GL state and bindings.
166*c8dee2aaSAndroid Build Coastguard Worker         resetBindings();
167*c8dee2aaSAndroid Build Coastguard Worker         dContext->resetContext();
168*c8dee2aaSAndroid Build Coastguard Worker         img = SkImages::BorrowTextureFrom(dContext,
169*c8dee2aaSAndroid Build Coastguard Worker                                           backendTexture,
170*c8dee2aaSAndroid Build Coastguard Worker                                           kTopLeft_GrSurfaceOrigin,
171*c8dee2aaSAndroid Build Coastguard Worker                                           kRGBA_8888_SkColorType,
172*c8dee2aaSAndroid Build Coastguard Worker                                           kPremul_SkAlphaType,
173*c8dee2aaSAndroid Build Coastguard Worker                                           nullptr);
174*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, img);
175*c8dee2aaSAndroid Build Coastguard Worker         surf->getCanvas()->drawImage(img, 0, 0);
176*c8dee2aaSAndroid Build Coastguard Worker         img.reset();
177*c8dee2aaSAndroid Build Coastguard Worker         dContext->flushAndSubmit(surf.get(), GrSyncCpu::kNo);
178*c8dee2aaSAndroid Build Coastguard Worker         dContext->resetGLTextureBindings();
179*c8dee2aaSAndroid Build Coastguard Worker         checkBindings();
180*c8dee2aaSAndroid Build Coastguard Worker         resetBindings();
181*c8dee2aaSAndroid Build Coastguard Worker         GL(DeleteTextures(1, &infoExternal.fID));
182*c8dee2aaSAndroid Build Coastguard Worker         ctxInfo.glContext()->destroyEGLImage(eglImage);
183*c8dee2aaSAndroid Build Coastguard Worker         dContext->deleteBackendTexture(texture2D);
184*c8dee2aaSAndroid Build Coastguard Worker         dContext->resetContext();
185*c8dee2aaSAndroid Build Coastguard Worker     }
186*c8dee2aaSAndroid Build Coastguard Worker 
187*c8dee2aaSAndroid Build Coastguard Worker     if (supportRectangle) {
188*c8dee2aaSAndroid Build Coastguard Worker         format = GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_RECTANGLE);
189*c8dee2aaSAndroid Build Coastguard Worker         GrBackendTexture rectangleTexture = dContext->createBackendTexture(
190*c8dee2aaSAndroid Build Coastguard Worker                 10, 10, format, skgpu::Mipmapped::kNo, GrRenderable::kNo);
191*c8dee2aaSAndroid Build Coastguard Worker         if (rectangleTexture.isValid()) {
192*c8dee2aaSAndroid Build Coastguard Worker             img = SkImages::BorrowTextureFrom(dContext,
193*c8dee2aaSAndroid Build Coastguard Worker                                               rectangleTexture,
194*c8dee2aaSAndroid Build Coastguard Worker                                               kTopLeft_GrSurfaceOrigin,
195*c8dee2aaSAndroid Build Coastguard Worker                                               kRGBA_8888_SkColorType,
196*c8dee2aaSAndroid Build Coastguard Worker                                               kPremul_SkAlphaType,
197*c8dee2aaSAndroid Build Coastguard Worker                                               nullptr);
198*c8dee2aaSAndroid Build Coastguard Worker             REPORTER_ASSERT(reporter, img);
199*c8dee2aaSAndroid Build Coastguard Worker             surf->getCanvas()->drawImage(img, 0, 0);
200*c8dee2aaSAndroid Build Coastguard Worker             img.reset();
201*c8dee2aaSAndroid Build Coastguard Worker             dContext->flushAndSubmit(surf.get(), GrSyncCpu::kNo);
202*c8dee2aaSAndroid Build Coastguard Worker             dContext->resetGLTextureBindings();
203*c8dee2aaSAndroid Build Coastguard Worker             checkBindings();
204*c8dee2aaSAndroid Build Coastguard Worker             resetBindings();
205*c8dee2aaSAndroid Build Coastguard Worker             dContext->deleteBackendTexture(rectangleTexture);
206*c8dee2aaSAndroid Build Coastguard Worker         }
207*c8dee2aaSAndroid Build Coastguard Worker     }
208*c8dee2aaSAndroid Build Coastguard Worker 
209*c8dee2aaSAndroid Build Coastguard Worker     GL(DeleteTextures(claimedIDs.size(), claimedIDs.begin()));
210*c8dee2aaSAndroid Build Coastguard Worker 
211*c8dee2aaSAndroid Build Coastguard Worker #undef GL
212*c8dee2aaSAndroid Build Coastguard Worker }
213*c8dee2aaSAndroid Build Coastguard Worker 
214*c8dee2aaSAndroid Build Coastguard Worker #endif  // SK_GL
215