• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "GrContextPriv.h"
9 #include "SkSurface.h"
10 #include "Test.h"
11 #include "gl/GrGLDefines.h"
12 #include "gl/GrGLGpu.h"
13 #include "gl/GrGLUtil.h"
14 
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(TextureBindingsResetTest,reporter,ctxInfo)15 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(TextureBindingsResetTest, reporter, ctxInfo) {
16 #define GL(F) GR_GL_CALL(ctxInfo.glContext()->gl(), F)
17 
18     GrContext* context = ctxInfo.grContext();
19     GrGLGpu* gpu = static_cast<GrGLGpu*>(context->priv().getGpu());
20 
21     struct Target {
22         GrGLenum fName;
23         GrGLenum fQuery;
24     };
25     SkTDArray<Target> targets;
26     targets.push_back({GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BINDING_2D});
27     bool supportExternal;
28     if ((supportExternal = gpu->glCaps().shaderCaps()->externalTextureSupport())) {
29         targets.push_back({GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_BINDING_EXTERNAL});
30     }
31     bool supportRectangle;
32     if ((supportRectangle = gpu->glCaps().rectangleTextureSupport())) {
33         targets.push_back({GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_BINDING_RECTANGLE});
34     }
35     GrGLint numUnits;
36     GL(GetIntegerv(GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numUnits));
37     SkTDArray<GrGLuint> claimedIDs;
38     claimedIDs.setCount(numUnits * targets.count());
39     GL(GenTextures(claimedIDs.count(), claimedIDs.begin()));
40 
41     auto resetBindings = [&] {
42         int i = 0;
43         for (int u = 0; u < numUnits; ++u) {
44             GL(ActiveTexture(GR_GL_TEXTURE0 + u));
45             for (auto target : targets) {
46                 GL(BindTexture(target.fName, claimedIDs[i++]));
47             }
48         }
49     };
50     auto checkBindings = [&] {
51         int i = 0;
52         for (int u = 0; u < numUnits; ++u) {
53             GL(ActiveTexture(GR_GL_TEXTURE0 + u));
54             for (auto target : targets) {
55                 GrGLuint boundID = ~0;
56                 GL(GetIntegerv(target.fQuery, reinterpret_cast<GrGLint*>(&boundID)));
57                 if (boundID != claimedIDs[i] && boundID != 0) {
58                     ERRORF(reporter, "Unit %d, target 0x%04x has ID %d bound. Expected %d or 0.", u,
59                            target.fName, boundID, claimedIDs[i]);
60                     return;
61                 }
62                 ++i;
63             }
64         }
65     };
66 
67     // Initialize texture unit/target combo bindings to 0.
68     context->flush();
69     resetBindings();
70     context->resetContext();
71 
72     // Test creating a texture and then resetting bindings.
73     GrSurfaceDesc desc;
74     desc.fWidth = desc.fHeight = 10;
75     desc.fConfig = kRGBA_8888_GrPixelConfig;
76     auto tex = gpu->createTexture(desc, SkBudgeted::kNo);
77     REPORTER_ASSERT(reporter, tex);
78     context->resetGLTextureBindings();
79     checkBindings();
80     resetBindings();
81     context->resetContext();
82 
83     // Test drawing and then resetting bindings. This should force a MIP regeneration if MIP
84     // maps are supported as well.
85     auto info = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
86     auto surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 1, nullptr);
87     surf->getCanvas()->clear(0x80FF0000);
88     auto img = surf->makeImageSnapshot();
89     surf->getCanvas()->clear(SK_ColorBLUE);
90     surf->getCanvas()->save();
91     surf->getCanvas()->scale(0.25, 0.25);
92     SkPaint paint;
93     paint.setFilterQuality(kHigh_SkFilterQuality);
94     surf->getCanvas()->drawImage(img, 0, 0, &paint);
95     surf->getCanvas()->restore();
96     surf->flush();
97     context->resetGLTextureBindings();
98     checkBindings();
99     resetBindings();
100     context->resetContext();
101 
102     if (supportExternal) {
103         GrBackendTexture texture2D = gpu->createTestingOnlyBackendTexture(
104                 nullptr, 10, 10, GrColorType::kRGBA_8888, false, GrMipMapped::kNo);
105         GrGLTextureInfo info2D;
106         REPORTER_ASSERT(reporter, texture2D.getGLTextureInfo(&info2D));
107         GrEGLImage eglImage = ctxInfo.glContext()->texture2DToEGLImage(info2D.fID);
108         REPORTER_ASSERT(reporter, eglImage);
109         GrGLTextureInfo infoExternal;
110         infoExternal.fID = ctxInfo.glContext()->eglImageToExternalTexture(eglImage);
111         infoExternal.fTarget = GR_GL_TEXTURE_EXTERNAL;
112         infoExternal.fFormat = info2D.fFormat;
113         REPORTER_ASSERT(reporter, infoExternal.fID);
114         GrBackendTexture backendTexture(10, 10, GrMipMapped::kNo, infoExternal);
115         // Above texture creation will have messed with GL state and bindings.
116         resetBindings();
117         context->resetContext();
118         img = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
119                                        kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
120         REPORTER_ASSERT(reporter, img);
121         surf->getCanvas()->drawImage(img, 0, 0);
122         img.reset();
123         surf->flush();
124         context->resetGLTextureBindings();
125         checkBindings();
126         resetBindings();
127         GL(DeleteTextures(1, &infoExternal.fID));
128         ctxInfo.glContext()->destroyEGLImage(eglImage);
129         gpu->deleteTestingOnlyBackendTexture(texture2D);
130         context->resetContext();
131     }
132 
133     if (supportRectangle) {
134         GrGLuint id = ctxInfo.glContext()->createTextureRectangle(10, 10, GR_GL_RGBA, GR_GL_RGBA,
135                                                                   GR_GL_UNSIGNED_BYTE, nullptr);
136         // Above texture creation will have messed with GL state and bindings.
137         resetBindings();
138         context->resetContext();
139         if (id) {
140             GrGLTextureInfo info;
141             info.fTarget = GR_GL_TEXTURE_RECTANGLE;
142             info.fFormat = GR_GL_RGBA8;
143             info.fID = id;
144             GrBackendTexture backendTexture(10, 10, GrMipMapped::kNo, info);
145             img = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
146                                            kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
147             REPORTER_ASSERT(reporter, img);
148             surf->getCanvas()->drawImage(img, 0, 0);
149             img.reset();
150             surf->flush();
151             context->resetGLTextureBindings();
152             checkBindings();
153             resetBindings();
154             GL(DeleteTextures(1, &id));
155             context->resetContext();
156         }
157     }
158 
159     GL(DeleteTextures(claimedIDs.count(), claimedIDs.begin()));
160 
161 #undef GL
162 }
163