• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&parameters.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