blob: 1703a34eae7a74620c82b94948570adcb1b136d0 [file] [log] [blame]
Brian Salomon1f05d452019-02-08 12:33:08 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkSurface.h"
9#include "src/gpu/GrContextPriv.h"
10#include "src/gpu/gl/GrGLDefines.h"
11#include "src/gpu/gl/GrGLGpu.h"
12#include "src/gpu/gl/GrGLUtil.h"
13#include "tests/Test.h"
Brian Salomon1f05d452019-02-08 12:33:08 -050014
John Rosascoa9b348f2019-11-08 13:18:15 -080015#ifdef SK_GL
16
Brian Salomon1f05d452019-02-08 12:33:08 -050017DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(TextureBindingsResetTest, reporter, ctxInfo) {
18#define GL(F) GR_GL_CALL(ctxInfo.glContext()->gl(), F)
19
20 GrContext* context = ctxInfo.grContext();
Robert Phillips9dbcdcc2019-05-13 10:40:06 -040021 GrGpu* gpu = context->priv().getGpu();
22 GrGLGpu* glGpu = static_cast<GrGLGpu*>(context->priv().getGpu());
Brian Salomon1f05d452019-02-08 12:33:08 -050023
24 struct Target {
25 GrGLenum fName;
26 GrGLenum fQuery;
27 };
28 SkTDArray<Target> targets;
29 targets.push_back({GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BINDING_2D});
30 bool supportExternal;
Robert Phillips9dbcdcc2019-05-13 10:40:06 -040031 if ((supportExternal = glGpu->glCaps().shaderCaps()->externalTextureSupport())) {
Brian Salomon1f05d452019-02-08 12:33:08 -050032 targets.push_back({GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_BINDING_EXTERNAL});
33 }
34 bool supportRectangle;
Robert Phillips9dbcdcc2019-05-13 10:40:06 -040035 if ((supportRectangle = glGpu->glCaps().rectangleTextureSupport())) {
Brian Salomon1f05d452019-02-08 12:33:08 -050036 targets.push_back({GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_BINDING_RECTANGLE});
37 }
38 GrGLint numUnits;
39 GL(GetIntegerv(GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numUnits));
40 SkTDArray<GrGLuint> claimedIDs;
41 claimedIDs.setCount(numUnits * targets.count());
42 GL(GenTextures(claimedIDs.count(), claimedIDs.begin()));
43
44 auto resetBindings = [&] {
45 int i = 0;
46 for (int u = 0; u < numUnits; ++u) {
47 GL(ActiveTexture(GR_GL_TEXTURE0 + u));
48 for (auto target : targets) {
49 GL(BindTexture(target.fName, claimedIDs[i++]));
50 }
51 }
52 };
53 auto checkBindings = [&] {
54 int i = 0;
55 for (int u = 0; u < numUnits; ++u) {
56 GL(ActiveTexture(GR_GL_TEXTURE0 + u));
57 for (auto target : targets) {
58 GrGLuint boundID = ~0;
59 GL(GetIntegerv(target.fQuery, reinterpret_cast<GrGLint*>(&boundID)));
60 if (boundID != claimedIDs[i] && boundID != 0) {
61 ERRORF(reporter, "Unit %d, target 0x%04x has ID %d bound. Expected %d or 0.", u,
62 target.fName, boundID, claimedIDs[i]);
63 return;
64 }
65 ++i;
66 }
67 }
68 };
69
70 // Initialize texture unit/target combo bindings to 0.
71 context->flush();
72 resetBindings();
73 context->resetContext();
74
75 // Test creating a texture and then resetting bindings.
76 GrSurfaceDesc desc;
77 desc.fWidth = desc.fHeight = 10;
78 desc.fConfig = kRGBA_8888_GrPixelConfig;
Brian Salomon4eb38b72019-08-05 12:58:39 -040079 auto format = gpu->caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888, GrRenderable::kNo);
Brian Salomona90382f2019-09-17 09:01:56 -040080 auto tex = gpu->createTexture(desc, format, GrRenderable::kNo, 1, GrMipMapped::kNo,
81 SkBudgeted::kNo, GrProtected::kNo);
Brian Salomon1f05d452019-02-08 12:33:08 -050082 REPORTER_ASSERT(reporter, tex);
83 context->resetGLTextureBindings();
84 checkBindings();
85 resetBindings();
86 context->resetContext();
87
88 // Test drawing and then resetting bindings. This should force a MIP regeneration if MIP
89 // maps are supported as well.
90 auto info = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
91 auto surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 1, nullptr);
92 surf->getCanvas()->clear(0x80FF0000);
93 auto img = surf->makeImageSnapshot();
94 surf->getCanvas()->clear(SK_ColorBLUE);
95 surf->getCanvas()->save();
96 surf->getCanvas()->scale(0.25, 0.25);
97 SkPaint paint;
98 paint.setFilterQuality(kHigh_SkFilterQuality);
99 surf->getCanvas()->drawImage(img, 0, 0, &paint);
100 surf->getCanvas()->restore();
101 surf->flush();
102 context->resetGLTextureBindings();
103 checkBindings();
104 resetBindings();
105 context->resetContext();
106
107 if (supportExternal) {
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400108 GrBackendTexture texture2D = context->createBackendTexture(
Robert Phillips80626792019-06-04 07:16:10 -0400109 10, 10, kRGBA_8888_SkColorType,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400110 SkColors::kTransparent, GrMipMapped::kNo, GrRenderable::kNo, GrProtected::kNo);
Brian Salomon1f05d452019-02-08 12:33:08 -0500111 GrGLTextureInfo info2D;
112 REPORTER_ASSERT(reporter, texture2D.getGLTextureInfo(&info2D));
113 GrEGLImage eglImage = ctxInfo.glContext()->texture2DToEGLImage(info2D.fID);
114 REPORTER_ASSERT(reporter, eglImage);
115 GrGLTextureInfo infoExternal;
116 infoExternal.fID = ctxInfo.glContext()->eglImageToExternalTexture(eglImage);
117 infoExternal.fTarget = GR_GL_TEXTURE_EXTERNAL;
118 infoExternal.fFormat = info2D.fFormat;
119 REPORTER_ASSERT(reporter, infoExternal.fID);
120 GrBackendTexture backendTexture(10, 10, GrMipMapped::kNo, infoExternal);
121 // Above texture creation will have messed with GL state and bindings.
122 resetBindings();
123 context->resetContext();
124 img = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
125 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
126 REPORTER_ASSERT(reporter, img);
127 surf->getCanvas()->drawImage(img, 0, 0);
128 img.reset();
129 surf->flush();
130 context->resetGLTextureBindings();
131 checkBindings();
132 resetBindings();
133 GL(DeleteTextures(1, &infoExternal.fID));
134 ctxInfo.glContext()->destroyEGLImage(eglImage);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400135 context->deleteBackendTexture(texture2D);
Brian Salomon1f05d452019-02-08 12:33:08 -0500136 context->resetContext();
137 }
138
139 if (supportRectangle) {
140 GrGLuint id = ctxInfo.glContext()->createTextureRectangle(10, 10, GR_GL_RGBA, GR_GL_RGBA,
141 GR_GL_UNSIGNED_BYTE, nullptr);
142 // Above texture creation will have messed with GL state and bindings.
143 resetBindings();
144 context->resetContext();
145 if (id) {
146 GrGLTextureInfo info;
147 info.fTarget = GR_GL_TEXTURE_RECTANGLE;
148 info.fFormat = GR_GL_RGBA8;
149 info.fID = id;
150 GrBackendTexture backendTexture(10, 10, GrMipMapped::kNo, info);
151 img = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
152 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
153 REPORTER_ASSERT(reporter, img);
154 surf->getCanvas()->drawImage(img, 0, 0);
155 img.reset();
156 surf->flush();
157 context->resetGLTextureBindings();
158 checkBindings();
159 resetBindings();
160 GL(DeleteTextures(1, &id));
161 context->resetContext();
162 }
163 }
164
165 GL(DeleteTextures(claimedIDs.count(), claimedIDs.begin()));
166
167#undef GL
168}
John Rosascoa9b348f2019-11-08 13:18:15 -0800169
170#endif // SK_GL