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 "tests/Test.h"
13
14 #include "include/core/SkImage.h"
15 #include "include/core/SkSurface.h"
16 #include "include/gpu/GrBackendSurface.h"
17 #include "include/gpu/GrTexture.h"
18 #include "include/gpu/gl/GrGLTypes.h"
19 #include "include/private/GrGLTypesPriv.h"
20 #include "src/gpu/GrContextPriv.h"
21 #include "src/gpu/GrTextureProxy.h"
22 #include "src/gpu/gl/GrGLCaps.h"
23 #include "src/gpu/gl/GrGLTexture.h"
24 #include "src/image/SkImage_Base.h"
25
sampler_params_invalid(const GrGLTextureParameters & parameters)26 static bool sampler_params_invalid(const GrGLTextureParameters& parameters) {
27 return SkScalarIsNaN(parameters.samplerOverriddenState().fMaxLOD);
28 }
29
nonsampler_params_invalid(const GrGLTextureParameters & parameters)30 static bool nonsampler_params_invalid(const GrGLTextureParameters& parameters) {
31 GrGLTextureParameters::NonsamplerState invalidNSState;
32 invalidNSState.invalidate();
33 return 0 == memcmp(¶meters.nonsamplerState(), &invalidNSState, sizeof(invalidNSState));
34 }
35
params_invalid(const GrGLTextureParameters & parameters)36 static bool params_invalid(const GrGLTextureParameters& parameters) {
37 return sampler_params_invalid(parameters) && nonsampler_params_invalid(parameters);
38 }
39
params_valid(const GrGLTextureParameters & parameters,const GrGLCaps * caps)40 static bool params_valid(const GrGLTextureParameters& parameters, const GrGLCaps* caps) {
41 if (nonsampler_params_invalid(parameters)) {
42 return false;
43 }
44 // We should only set the sampler parameters to valid if we don't have sampler object support.
45 return caps->samplerObjectSupport() == sampler_params_invalid(parameters);
46 }
47
DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLTextureParameters,reporter,ctxInfo)48 DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLTextureParameters, reporter, ctxInfo) {
49 GrContext* context = ctxInfo.grContext();
50
51 GrBackendTexture backendTex = context->createBackendTexture(
52 1, 1, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo, GrProtected::kNo);
53 REPORTER_ASSERT(reporter, backendTex.isValid());
54
55 GrGLTextureInfo info;
56 REPORTER_ASSERT(reporter, backendTex.getGLTextureInfo(&info));
57
58 GrBackendTexture backendTexCopy = backendTex;
59 REPORTER_ASSERT(reporter, backendTexCopy.isSameTexture(backendTex));
60
61 sk_sp<SkImage> wrappedImage =
62 SkImage::MakeFromTexture(context, backendTex, kTopLeft_GrSurfaceOrigin,
63 kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
64 REPORTER_ASSERT(reporter, wrappedImage);
65
66 sk_sp<GrTextureProxy> texProxy = as_IB(wrappedImage)->asTextureProxyRef(context);
67 REPORTER_ASSERT(reporter, texProxy.get());
68 REPORTER_ASSERT(reporter, texProxy->isInstantiated());
69 auto texture = static_cast<GrGLTexture*>(texProxy->peekTexture());
70 REPORTER_ASSERT(reporter, texture);
71 auto parameters = texture->parameters();
72 REPORTER_ASSERT(reporter, parameters);
73 GrGLTextureParameters::SamplerOverriddenState invalidSState;
74 invalidSState.invalidate();
75 GrGLTextureParameters::NonsamplerState invalidNSState;
76 invalidNSState.invalidate();
77
78 // After wrapping we should assume the client's texture can be in any state.
79 REPORTER_ASSERT(reporter, params_invalid(*parameters));
80
81 auto surf = SkSurface::MakeRenderTarget(
82 context, SkBudgeted::kYes,
83 SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType), 1, nullptr);
84 REPORTER_ASSERT(reporter, surf);
85 surf->getCanvas()->drawImage(wrappedImage, 0, 0);
86 surf->flush();
87
88 auto caps = static_cast<const GrGLCaps*>(context->priv().caps());
89 // Now the texture should be in a known state.
90 REPORTER_ASSERT(reporter, params_valid(*parameters, caps));
91
92 // Test invalidating from the GL backend texture.
93 backendTex.glTextureParametersModified();
94 REPORTER_ASSERT(reporter, params_invalid(*parameters));
95
96 REPORTER_ASSERT(reporter, surf);
97 surf->getCanvas()->drawImage(wrappedImage, 0, 0);
98 surf->flush();
99 REPORTER_ASSERT(reporter, params_valid(*parameters, caps));
100
101 // Test invalidating from the copy.
102 backendTexCopy.glTextureParametersModified();
103 REPORTER_ASSERT(reporter, params_invalid(*parameters));
104
105 // Check that we can do things like assigning the backend texture to invalid one, assign an
106 // invalid one, assin a backend texture to inself etc. Success here is that we don't hit any of
107 // our ref counting asserts.
108 REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(backendTex, backendTexCopy));
109
110 GrBackendTexture invalidTexture;
111 REPORTER_ASSERT(reporter, !invalidTexture.isValid());
112 REPORTER_ASSERT(reporter,
113 !GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTexCopy));
114
115 backendTexCopy = invalidTexture;
116 REPORTER_ASSERT(reporter, !backendTexCopy.isValid());
117 REPORTER_ASSERT(reporter,
118 !GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTexCopy));
119
120 invalidTexture = backendTex;
121 REPORTER_ASSERT(reporter, invalidTexture.isValid());
122 REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTex));
123
124 invalidTexture = static_cast<decltype(invalidTexture)&>(invalidTexture);
125 REPORTER_ASSERT(reporter, invalidTexture.isValid());
126 REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(invalidTexture, invalidTexture));
127
128 wrappedImage.reset();
129 GrFlushInfo flushInfo;
130 flushInfo.fFlags = kSyncCpu_GrFlushFlag;
131 context->flush(flushInfo);
132 context->deleteBackendTexture(backendTex);
133 }
134 #endif
135