1 /*
2 * Copyright 2019 Google LLC
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 "include/core/SkTypes.h"
9
10 #ifdef SK_GL
11
12 #include "include/core/SkAlphaType.h"
13 #include "include/core/SkCanvas.h"
14 #include "include/core/SkColorSpace.h"
15 #include "include/core/SkColorType.h"
16 #include "include/core/SkImage.h"
17 #include "include/core/SkImageInfo.h"
18 #include "include/core/SkRefCnt.h"
19 #include "include/core/SkScalar.h"
20 #include "include/core/SkSurface.h"
21 #include "include/core/SkTypes.h"
22 #include "include/gpu/GpuTypes.h"
23 #include "include/gpu/GrBackendSurface.h"
24 #include "include/gpu/GrDirectContext.h"
25 #include "include/gpu/GrTypes.h"
26 #include "include/gpu/gl/GrGLTypes.h"
27 #include "include/private/gpu/ganesh/GrGLTypesPriv.h"
28 #include "src/gpu/ganesh/GrDirectContextPriv.h"
29 #include "src/gpu/ganesh/GrSurfaceProxy.h"
30 #include "src/gpu/ganesh/GrTextureProxy.h"
31 #include "src/gpu/ganesh/gl/GrGLCaps.h"
32 #include "src/gpu/ganesh/gl/GrGLTexture.h"
33 #include "tests/CtsEnforcement.h"
34 #include "tests/Test.h"
35 #include "tools/gpu/ProxyUtils.h"
36 struct GrContextOptions;
37
sampler_params_invalid(const GrGLTextureParameters & parameters)38 static bool sampler_params_invalid(const GrGLTextureParameters& parameters) {
39 return SkScalarIsNaN(parameters.samplerOverriddenState().fMaxLOD);
40 }
41
nonsampler_params_invalid(const GrGLTextureParameters & parameters)42 static bool nonsampler_params_invalid(const GrGLTextureParameters& parameters) {
43 GrGLTextureParameters::NonsamplerState nsState = parameters.nonsamplerState();
44 GrGLTextureParameters::NonsamplerState invalidNSState;
45 invalidNSState.invalidate();
46 return nsState.fBaseMipMapLevel == invalidNSState.fBaseMipMapLevel &&
47 nsState.fMaxMipmapLevel == invalidNSState.fMaxMipmapLevel &&
48 nsState.fSwizzleIsRGBA == invalidNSState.fSwizzleIsRGBA;
49 }
50
params_invalid(const GrGLTextureParameters & parameters)51 static bool params_invalid(const GrGLTextureParameters& parameters) {
52 return sampler_params_invalid(parameters) && nonsampler_params_invalid(parameters);
53 }
54
params_valid(const GrGLTextureParameters & parameters,const GrGLCaps * caps)55 static bool params_valid(const GrGLTextureParameters& parameters, const GrGLCaps* caps) {
56 if (nonsampler_params_invalid(parameters)) {
57 return false;
58 }
59 // We should only set the texture params that are equivalent to sampler param to valid if we're
60 // not using sampler objects.
61 return caps->useSamplerObjects() == sampler_params_invalid(parameters);
62 }
63
DEF_GANESH_TEST_FOR_ALL_GL_CONTEXTS(GLTextureParameters,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)64 DEF_GANESH_TEST_FOR_ALL_GL_CONTEXTS(GLTextureParameters,
65 reporter,
66 ctxInfo,
67 CtsEnforcement::kApiLevel_T) {
68 auto dContext = ctxInfo.directContext();
69 auto caps = static_cast<const GrGLCaps*>(dContext->priv().caps());
70
71 GrBackendTexture backendTex = dContext->createBackendTexture(1,
72 1,
73 kRGBA_8888_SkColorType,
74 GrMipmapped::kNo,
75 GrRenderable::kNo,
76 GrProtected::kNo);
77 REPORTER_ASSERT(reporter, backendTex.isValid());
78
79 GrGLTextureInfo info;
80 REPORTER_ASSERT(reporter, backendTex.getGLTextureInfo(&info));
81
82 GrBackendTexture backendTexCopy = backendTex;
83 REPORTER_ASSERT(reporter, backendTexCopy.isSameTexture(backendTex));
84
85 sk_sp<SkImage> wrappedImage =
86 SkImage::MakeFromTexture(dContext, backendTex, kTopLeft_GrSurfaceOrigin,
87 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
88 REPORTER_ASSERT(reporter, wrappedImage);
89
90 GrSurfaceProxy* proxy = sk_gpu_test::GetTextureImageProxy(wrappedImage.get(), dContext);
91 REPORTER_ASSERT(reporter, proxy);
92 REPORTER_ASSERT(reporter, proxy->isInstantiated());
93 auto texture = static_cast<GrGLTexture*>(proxy->peekTexture());
94 REPORTER_ASSERT(reporter, texture);
95 auto parameters = texture->parameters();
96 REPORTER_ASSERT(reporter, parameters);
97 GrGLTextureParameters::SamplerOverriddenState invalidSState;
98 invalidSState.invalidate();
99 GrGLTextureParameters::NonsamplerState invalidNSState;
100 invalidNSState.invalidate();
101
102 auto surf = SkSurface::MakeRenderTarget(
103 dContext,
104 skgpu::Budgeted::kYes,
105 SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType),
106 1,
107 nullptr);
108 REPORTER_ASSERT(reporter, surf);
109
110 // Test invalidating from the GL backend texture.
111 backendTex.glTextureParametersModified();
112 REPORTER_ASSERT(reporter, params_invalid(*parameters));
113
114 REPORTER_ASSERT(reporter, surf);
115 surf->getCanvas()->drawImage(wrappedImage, 0, 0);
116 surf->flushAndSubmit();
117 REPORTER_ASSERT(reporter, params_valid(*parameters, caps));
118
119 // Test invalidating from the copy.
120 backendTexCopy.glTextureParametersModified();
121 REPORTER_ASSERT(reporter, params_invalid(*parameters));
122
123 // Check that we can do things like assigning the backend texture to invalid one, assign an
124 // invalid one, assign a backend texture to itself etc. Success here is that we don't hit any
125 // of our ref counting asserts.
126 REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(backendTex, backendTexCopy));
127
128 GrBackendTexture invalidTexture;
129 REPORTER_ASSERT(reporter, !invalidTexture.isValid());
130 REPORTER_ASSERT(reporter,
131 !GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTexCopy));
132
133 backendTexCopy = invalidTexture;
134 REPORTER_ASSERT(reporter, !backendTexCopy.isValid());
135 REPORTER_ASSERT(reporter,
136 !GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTexCopy));
137
138 invalidTexture = backendTex;
139 REPORTER_ASSERT(reporter, invalidTexture.isValid());
140 REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTex));
141
142 invalidTexture = static_cast<decltype(invalidTexture)&>(invalidTexture);
143 REPORTER_ASSERT(reporter, invalidTexture.isValid());
144 REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(invalidTexture, invalidTexture));
145
146 wrappedImage.reset();
147 dContext->flush();
148 dContext->submit(true);
149 dContext->deleteBackendTexture(backendTex);
150 }
151 #endif
152