blob: db60a46c537befade75bbe39597724a520017c18 [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"
Robert Phillips6d344c32020-07-06 10:56:46 -04009#include "include/gpu/GrDirectContext.h"
Adlai Hollera0693042020-10-14 11:23:11 -040010#include "src/gpu/GrDirectContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/gpu/gl/GrGLDefines.h"
12#include "src/gpu/gl/GrGLGpu.h"
13#include "src/gpu/gl/GrGLUtil.h"
14#include "tests/Test.h"
Brian Salomon1f05d452019-02-08 12:33:08 -050015
John Rosascoa9b348f2019-11-08 13:18:15 -080016#ifdef SK_GL
17
Brian Salomon1f05d452019-02-08 12:33:08 -050018DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(TextureBindingsResetTest, reporter, ctxInfo) {
19#define GL(F) GR_GL_CALL(ctxInfo.glContext()->gl(), F)
20
Adlai Holler14dc7912020-08-11 15:48:49 +000021 auto dContext = ctxInfo.directContext();
22 GrGpu* gpu = dContext->priv().getGpu();
23 GrGLGpu* glGpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
Brian Salomon1f05d452019-02-08 12:33:08 -050024
25 struct Target {
26 GrGLenum fName;
27 GrGLenum fQuery;
28 };
29 SkTDArray<Target> targets;
30 targets.push_back({GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BINDING_2D});
31 bool supportExternal;
Robert Phillips9dbcdcc2019-05-13 10:40:06 -040032 if ((supportExternal = glGpu->glCaps().shaderCaps()->externalTextureSupport())) {
Brian Salomon1f05d452019-02-08 12:33:08 -050033 targets.push_back({GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_BINDING_EXTERNAL});
34 }
35 bool supportRectangle;
Robert Phillips9dbcdcc2019-05-13 10:40:06 -040036 if ((supportRectangle = glGpu->glCaps().rectangleTextureSupport())) {
Brian Salomon1f05d452019-02-08 12:33:08 -050037 targets.push_back({GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_BINDING_RECTANGLE});
38 }
39 GrGLint numUnits;
40 GL(GetIntegerv(GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numUnits));
41 SkTDArray<GrGLuint> claimedIDs;
42 claimedIDs.setCount(numUnits * targets.count());
43 GL(GenTextures(claimedIDs.count(), claimedIDs.begin()));
44
45 auto resetBindings = [&] {
46 int i = 0;
47 for (int u = 0; u < numUnits; ++u) {
48 GL(ActiveTexture(GR_GL_TEXTURE0 + u));
49 for (auto target : targets) {
50 GL(BindTexture(target.fName, claimedIDs[i++]));
51 }
52 }
53 };
54 auto checkBindings = [&] {
55 int i = 0;
56 for (int u = 0; u < numUnits; ++u) {
57 GL(ActiveTexture(GR_GL_TEXTURE0 + u));
58 for (auto target : targets) {
59 GrGLuint boundID = ~0;
60 GL(GetIntegerv(target.fQuery, reinterpret_cast<GrGLint*>(&boundID)));
61 if (boundID != claimedIDs[i] && boundID != 0) {
62 ERRORF(reporter, "Unit %d, target 0x%04x has ID %d bound. Expected %d or 0.", u,
63 target.fName, boundID, claimedIDs[i]);
64 return;
65 }
66 ++i;
67 }
68 }
69 };
70
71 // Initialize texture unit/target combo bindings to 0.
Adlai Holler14dc7912020-08-11 15:48:49 +000072 dContext->flushAndSubmit();
Brian Salomon1f05d452019-02-08 12:33:08 -050073 resetBindings();
Adlai Holler14dc7912020-08-11 15:48:49 +000074 dContext->resetContext();
Brian Salomon1f05d452019-02-08 12:33:08 -050075
76 // Test creating a texture and then resetting bindings.
Brian Salomona56a7462020-02-07 14:17:25 -050077 static constexpr SkISize kDims = {10, 10};
John Stilesfa088a62021-08-12 23:01:41 -040078 GrBackendFormat format = gpu->caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
79 GrRenderable::kNo);
Greg Daniel0e9d34d2021-08-13 16:20:18 -040080 auto tex = gpu->createTexture(kDims, format, GrTextureType::k2D, GrRenderable::kNo, 1,
81 GrMipmapped::kNo, SkBudgeted::kNo, GrProtected::kNo);
Brian Salomon1f05d452019-02-08 12:33:08 -050082 REPORTER_ASSERT(reporter, tex);
Adlai Holler14dc7912020-08-11 15:48:49 +000083 dContext->resetGLTextureBindings();
Brian Salomon1f05d452019-02-08 12:33:08 -050084 checkBindings();
85 resetBindings();
Adlai Holler14dc7912020-08-11 15:48:49 +000086 dContext->resetContext();
Brian Salomon1f05d452019-02-08 12:33:08 -050087
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);
Adlai Holler14dc7912020-08-11 15:48:49 +000091 auto surf = SkSurface::MakeRenderTarget(dContext, SkBudgeted::kYes, info, 1, nullptr);
Brian Salomon1f05d452019-02-08 12:33:08 -050092 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);
Mike Reed839eef32020-12-23 11:18:24 -050097 surf->getCanvas()->drawImage(img.get(), 0, 0, SkSamplingOptions({1.0f/3, 1.0f/3}), nullptr);
Brian Salomon1f05d452019-02-08 12:33:08 -050098 surf->getCanvas()->restore();
Greg Daniel0a2464f2020-05-14 15:45:44 -040099 surf->flushAndSubmit();
Adlai Holler14dc7912020-08-11 15:48:49 +0000100 dContext->resetGLTextureBindings();
Brian Salomon1f05d452019-02-08 12:33:08 -0500101 checkBindings();
102 resetBindings();
Adlai Holler14dc7912020-08-11 15:48:49 +0000103 dContext->resetContext();
Brian Salomon1f05d452019-02-08 12:33:08 -0500104
105 if (supportExternal) {
Adlai Holler14dc7912020-08-11 15:48:49 +0000106 GrBackendTexture texture2D = dContext->createBackendTexture(
Robert Phillips80626792019-06-04 07:16:10 -0400107 10, 10, kRGBA_8888_SkColorType,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400108 SkColors::kTransparent, GrMipmapped::kNo, GrRenderable::kNo, GrProtected::kNo);
Brian Salomon1f05d452019-02-08 12:33:08 -0500109 GrGLTextureInfo info2D;
110 REPORTER_ASSERT(reporter, texture2D.getGLTextureInfo(&info2D));
111 GrEGLImage eglImage = ctxInfo.glContext()->texture2DToEGLImage(info2D.fID);
112 REPORTER_ASSERT(reporter, eglImage);
113 GrGLTextureInfo infoExternal;
114 infoExternal.fID = ctxInfo.glContext()->eglImageToExternalTexture(eglImage);
115 infoExternal.fTarget = GR_GL_TEXTURE_EXTERNAL;
116 infoExternal.fFormat = info2D.fFormat;
117 REPORTER_ASSERT(reporter, infoExternal.fID);
Brian Salomon7e67dca2020-07-21 09:27:25 -0400118 GrBackendTexture backendTexture(10, 10, GrMipmapped::kNo, infoExternal);
Brian Salomon1f05d452019-02-08 12:33:08 -0500119 // Above texture creation will have messed with GL state and bindings.
120 resetBindings();
Adlai Holler14dc7912020-08-11 15:48:49 +0000121 dContext->resetContext();
122 img = SkImage::MakeFromTexture(dContext, backendTexture, kTopLeft_GrSurfaceOrigin,
Brian Salomon1f05d452019-02-08 12:33:08 -0500123 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
124 REPORTER_ASSERT(reporter, img);
125 surf->getCanvas()->drawImage(img, 0, 0);
126 img.reset();
Greg Daniel0a2464f2020-05-14 15:45:44 -0400127 surf->flushAndSubmit();
Adlai Holler14dc7912020-08-11 15:48:49 +0000128 dContext->resetGLTextureBindings();
Brian Salomon1f05d452019-02-08 12:33:08 -0500129 checkBindings();
130 resetBindings();
131 GL(DeleteTextures(1, &infoExternal.fID));
132 ctxInfo.glContext()->destroyEGLImage(eglImage);
Adlai Holler14dc7912020-08-11 15:48:49 +0000133 dContext->deleteBackendTexture(texture2D);
134 dContext->resetContext();
Brian Salomon1f05d452019-02-08 12:33:08 -0500135 }
136
137 if (supportRectangle) {
John Stilesfa088a62021-08-12 23:01:41 -0400138 format = GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_RECTANGLE);
Brian Salomon0f396992020-06-19 19:51:21 -0400139 GrBackendTexture rectangleTexture =
Adlai Holler14dc7912020-08-11 15:48:49 +0000140 dContext->createBackendTexture(10, 10, format, GrMipmapped::kNo, GrRenderable::kNo);
Brian Salomon0f396992020-06-19 19:51:21 -0400141 if (rectangleTexture.isValid()) {
Adlai Holler14dc7912020-08-11 15:48:49 +0000142 img = SkImage::MakeFromTexture(dContext, rectangleTexture, kTopLeft_GrSurfaceOrigin,
Brian Salomon1f05d452019-02-08 12:33:08 -0500143 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
144 REPORTER_ASSERT(reporter, img);
145 surf->getCanvas()->drawImage(img, 0, 0);
146 img.reset();
Greg Daniel0a2464f2020-05-14 15:45:44 -0400147 surf->flushAndSubmit();
Adlai Holler14dc7912020-08-11 15:48:49 +0000148 dContext->resetGLTextureBindings();
Brian Salomon1f05d452019-02-08 12:33:08 -0500149 checkBindings();
150 resetBindings();
Adlai Holler14dc7912020-08-11 15:48:49 +0000151 dContext->deleteBackendTexture(rectangleTexture);
Brian Salomon1f05d452019-02-08 12:33:08 -0500152 }
153 }
154
155 GL(DeleteTextures(claimedIDs.count(), claimedIDs.begin()));
156
157#undef GL
158}
John Rosascoa9b348f2019-11-08 13:18:15 -0800159
160#endif // SK_GL