blob: 3daa712d2812dca54e0a43790a5e3139ee1ae362 [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
15DEF_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();
Robert Phillips9dbcdcc2019-05-13 10:40:06 -040019 GrGpu* gpu = context->priv().getGpu();
20 GrGLGpu* glGpu = static_cast<GrGLGpu*>(context->priv().getGpu());
Brian Salomon1f05d452019-02-08 12:33:08 -050021
22 struct Target {
23 GrGLenum fName;
24 GrGLenum fQuery;
25 };
26 SkTDArray<Target> targets;
27 targets.push_back({GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BINDING_2D});
28 bool supportExternal;
Robert Phillips9dbcdcc2019-05-13 10:40:06 -040029 if ((supportExternal = glGpu->glCaps().shaderCaps()->externalTextureSupport())) {
Brian Salomon1f05d452019-02-08 12:33:08 -050030 targets.push_back({GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_BINDING_EXTERNAL});
31 }
32 bool supportRectangle;
Robert Phillips9dbcdcc2019-05-13 10:40:06 -040033 if ((supportRectangle = glGpu->glCaps().rectangleTextureSupport())) {
Brian Salomon1f05d452019-02-08 12:33:08 -050034 targets.push_back({GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_BINDING_RECTANGLE});
35 }
36 GrGLint numUnits;
37 GL(GetIntegerv(GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numUnits));
38 SkTDArray<GrGLuint> claimedIDs;
39 claimedIDs.setCount(numUnits * targets.count());
40 GL(GenTextures(claimedIDs.count(), claimedIDs.begin()));
41
42 auto resetBindings = [&] {
43 int i = 0;
44 for (int u = 0; u < numUnits; ++u) {
45 GL(ActiveTexture(GR_GL_TEXTURE0 + u));
46 for (auto target : targets) {
47 GL(BindTexture(target.fName, claimedIDs[i++]));
48 }
49 }
50 };
51 auto checkBindings = [&] {
52 int i = 0;
53 for (int u = 0; u < numUnits; ++u) {
54 GL(ActiveTexture(GR_GL_TEXTURE0 + u));
55 for (auto target : targets) {
56 GrGLuint boundID = ~0;
57 GL(GetIntegerv(target.fQuery, reinterpret_cast<GrGLint*>(&boundID)));
58 if (boundID != claimedIDs[i] && boundID != 0) {
59 ERRORF(reporter, "Unit %d, target 0x%04x has ID %d bound. Expected %d or 0.", u,
60 target.fName, boundID, claimedIDs[i]);
61 return;
62 }
63 ++i;
64 }
65 }
66 };
67
68 // Initialize texture unit/target combo bindings to 0.
69 context->flush();
70 resetBindings();
71 context->resetContext();
72
73 // Test creating a texture and then resetting bindings.
74 GrSurfaceDesc desc;
75 desc.fWidth = desc.fHeight = 10;
76 desc.fConfig = kRGBA_8888_GrPixelConfig;
77 auto tex = gpu->createTexture(desc, SkBudgeted::kNo);
78 REPORTER_ASSERT(reporter, tex);
79 context->resetGLTextureBindings();
80 checkBindings();
81 resetBindings();
82 context->resetContext();
83
84 // Test drawing and then resetting bindings. This should force a MIP regeneration if MIP
85 // maps are supported as well.
86 auto info = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
87 auto surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 1, nullptr);
88 surf->getCanvas()->clear(0x80FF0000);
89 auto img = surf->makeImageSnapshot();
90 surf->getCanvas()->clear(SK_ColorBLUE);
91 surf->getCanvas()->save();
92 surf->getCanvas()->scale(0.25, 0.25);
93 SkPaint paint;
94 paint.setFilterQuality(kHigh_SkFilterQuality);
95 surf->getCanvas()->drawImage(img, 0, 0, &paint);
96 surf->getCanvas()->restore();
97 surf->flush();
98 context->resetGLTextureBindings();
99 checkBindings();
100 resetBindings();
101 context->resetContext();
102
103 if (supportExternal) {
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400104 GrBackendTexture texture2D = context->createBackendTexture(
Robert Phillips9dbcdcc2019-05-13 10:40:06 -0400105 10, 10, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo);
Brian Salomon1f05d452019-02-08 12:33:08 -0500106 GrGLTextureInfo info2D;
107 REPORTER_ASSERT(reporter, texture2D.getGLTextureInfo(&info2D));
108 GrEGLImage eglImage = ctxInfo.glContext()->texture2DToEGLImage(info2D.fID);
109 REPORTER_ASSERT(reporter, eglImage);
110 GrGLTextureInfo infoExternal;
111 infoExternal.fID = ctxInfo.glContext()->eglImageToExternalTexture(eglImage);
112 infoExternal.fTarget = GR_GL_TEXTURE_EXTERNAL;
113 infoExternal.fFormat = info2D.fFormat;
114 REPORTER_ASSERT(reporter, infoExternal.fID);
115 GrBackendTexture backendTexture(10, 10, GrMipMapped::kNo, infoExternal);
116 // Above texture creation will have messed with GL state and bindings.
117 resetBindings();
118 context->resetContext();
119 img = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
120 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
121 REPORTER_ASSERT(reporter, img);
122 surf->getCanvas()->drawImage(img, 0, 0);
123 img.reset();
124 surf->flush();
125 context->resetGLTextureBindings();
126 checkBindings();
127 resetBindings();
128 GL(DeleteTextures(1, &infoExternal.fID));
129 ctxInfo.glContext()->destroyEGLImage(eglImage);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400130 context->deleteBackendTexture(texture2D);
Brian Salomon1f05d452019-02-08 12:33:08 -0500131 context->resetContext();
132 }
133
134 if (supportRectangle) {
135 GrGLuint id = ctxInfo.glContext()->createTextureRectangle(10, 10, GR_GL_RGBA, GR_GL_RGBA,
136 GR_GL_UNSIGNED_BYTE, nullptr);
137 // Above texture creation will have messed with GL state and bindings.
138 resetBindings();
139 context->resetContext();
140 if (id) {
141 GrGLTextureInfo info;
142 info.fTarget = GR_GL_TEXTURE_RECTANGLE;
143 info.fFormat = GR_GL_RGBA8;
144 info.fID = id;
145 GrBackendTexture backendTexture(10, 10, GrMipMapped::kNo, info);
146 img = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
147 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
148 REPORTER_ASSERT(reporter, img);
149 surf->getCanvas()->drawImage(img, 0, 0);
150 img.reset();
151 surf->flush();
152 context->resetGLTextureBindings();
153 checkBindings();
154 resetBindings();
155 GL(DeleteTextures(1, &id));
156 context->resetContext();
157 }
158 }
159
160 GL(DeleteTextures(claimedIDs.count(), claimedIDs.begin()));
161
162#undef GL
163}