• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include "aemu/base/files/PathUtils.h"
18 #include "aemu/base/system/System.h"
19 #include "aemu/base/testing/TestSystem.h"
20 
21 #include "OpenGLTestContext.h"
22 
23 #include <gtest/gtest.h>
24 
25 #include <memory>
26 #include <vector>
27 
28 namespace gfxstream {
29 namespace gl {
30 
31 struct GlValues {
32     std::vector<GLint> ints;
33     std::vector<GLfloat> floats;
34 };
35 
36 struct GlBufferData {
37     GLsizeiptr size;
38     GLvoid* bytes;
39     GLenum usage;
40 };
41 
42 // Capabilities which, according to the GLES2 spec, start disabled.
43 static const GLenum kGLES2CanBeEnabled[] = {GL_BLEND,
44                                             GL_CULL_FACE,
45                                             GL_DEPTH_TEST,
46                                             GL_POLYGON_OFFSET_FILL,
47                                             GL_SAMPLE_ALPHA_TO_COVERAGE,
48                                             GL_SAMPLE_COVERAGE,
49                                             GL_SCISSOR_TEST,
50                                             GL_STENCIL_TEST};
51 
52 // Capabilities which, according to the GLES2 spec, start enabled.
53 static const GLenum kGLES2CanBeDisabled[] = {GL_DITHER};
54 
55 // Modes for CullFace
56 static const GLenum kGLES2CullFaceModes[] = {GL_BACK, GL_FRONT,
57                                              GL_FRONT_AND_BACK};
58 
59 // Modes for FrontFace
60 static const GLenum kGLES2FrontFaceModes[] = {GL_CCW, GL_CW};
61 
62 // Valid Stencil test functions
63 static const GLenum kGLES2StencilFuncs[] = {GL_NEVER,   GL_ALWAYS,  GL_LESS,
64                                             GL_LEQUAL,  GL_EQUAL,   GL_GEQUAL,
65                                             GL_GREATER, GL_NOTEQUAL};
66 // Valid Stencil test result operations
67 static const GLenum kGLES2StencilOps[] = {GL_KEEP,      GL_ZERO,     GL_REPLACE,
68                                           GL_INCR,      GL_DECR,     GL_INVERT,
69                                           GL_INCR_WRAP, GL_DECR_WRAP};
70 
71 // Modes for the BlendEquation
72 static const GLenum kGLES2BlendEquations[] = {GL_FUNC_ADD, GL_FUNC_SUBTRACT,
73                                               GL_FUNC_REVERSE_SUBTRACT};
74 
75 // Valid Blend functions
76 static const GLenum kGLES2BlendFuncs[] = {GL_ZERO,
77                                           GL_ONE,
78                                           GL_SRC_COLOR,
79                                           GL_ONE_MINUS_SRC_COLOR,
80                                           GL_DST_COLOR,
81                                           GL_ONE_MINUS_DST_COLOR,
82                                           GL_SRC_ALPHA,
83                                           GL_ONE_MINUS_SRC_ALPHA,
84                                           GL_CONSTANT_COLOR,
85                                           GL_ONE_MINUS_CONSTANT_COLOR,
86                                           GL_CONSTANT_ALPHA,
87                                           GL_ONE_MINUS_CONSTANT_ALPHA,
88                                           GL_SRC_ALPHA_SATURATE};
89 
90 // Valid GENERATE_MIPMAP_HINT values
91 static const GLenum kGLES2GenerateMipmapHints[] = {GL_DONT_CARE, GL_FASTEST,
92                                                    GL_NICEST};
93 
94 // Returns a string useful for failure messages describing |enumValue|.
95 std::string describeGlEnum(GLenum enumValue);
96 
97 // For building other compare functions which return AssertionResult.
98 // Compares an |actual| against an |expected| value. Returns a failure values
99 // do not match; provide |description| to attach details to the failure message.
100 template <class T>
101 testing::AssertionResult compareValue(T expected,
102                                       T actual,
103                                       const std::string& description = "");
104 
105 // Compares a global GL value, known by |name| and retrieved as a boolean,
106 // against an |expected| value.
107 testing::AssertionResult compareGlobalGlBoolean(const GLESv2Dispatch* gl,
108                                                 GLenum name,
109                                                 GLboolean expected);
110 
111 // Compares a global GL value, known by |name| and retrieved as an integer,
112 // against an |expected| value.
113 testing::AssertionResult compareGlobalGlInt(const GLESv2Dispatch* gl,
114                                             GLenum name,
115                                             GLint expected);
116 
117 testing::AssertionResult compareGlobalGlInt_i(const GLESv2Dispatch* gl,
118                                               GLenum name,
119                                               GLuint index,
120                                               GLint expected);
121 // Compares a global GL value, known by |name| and retrieved as a float, against
122 // an |expected| value.
123 testing::AssertionResult compareGlobalGlFloat(const GLESv2Dispatch* gl,
124                                               GLenum name,
125                                               GLfloat expected);
126 
127 // For building other compare functions which return AssertionResult.
128 // Compare the values at each index of a vector |actual| against an |expected|.
129 // Returns a failure if any values are mismatched; provide |description| to
130 // attach details to the failure message.
131 // |actual| is allowed to contain more elements than |expected|.
132 template <class T>
133 testing::AssertionResult compareVector(
134         const std::vector<T>& expected,
135         const std::vector<T>& actual,
136         const std::string& description = "vector");
137 
138 // Compares a vector of global GL values, known by |name| and retrieved as a
139 // boolean array, against |expected| values.
140 // Specify |size| if more space is needed than the size of |expected|.
141 testing::AssertionResult compareGlobalGlBooleanv(
142         const GLESv2Dispatch* gl,
143         GLenum name,
144         const std::vector<GLboolean>& expected,
145         GLuint size = 0);
146 
147 testing::AssertionResult compareGlobalGlBooleanv_i(
148         const GLESv2Dispatch* gl,
149         GLenum name,
150         GLuint index,
151         const std::vector<GLboolean>& expected,
152         GLuint size = 0);
153 
154 
155 // Compares a vector of global GL values, known by |name| and retrieved as an
156 // integer array, against |expected| values.
157 // Specify |size| if more space is needed than the size of |expected|.
158 testing::AssertionResult compareGlobalGlIntv(const GLESv2Dispatch* gl,
159                                              GLenum name,
160                                              const std::vector<GLint>& expected,
161                                              GLuint size = 0);
162 
163 testing::AssertionResult compareGlobalGlIntv_i(const GLESv2Dispatch* gl,
164                                                GLenum name,
165                                                GLuint index,
166                                                const std::vector<GLint>& expected,
167                                                GLuint size = 0);
168 
169 // Compares a vector of global GL values, known by |name| and retrieved as a
170 // float array, against |expected| values.
171 // Specify |size| if more space is needed than the size of |expected|.
172 testing::AssertionResult compareGlobalGlFloatv(
173         const GLESv2Dispatch* gl,
174         GLenum name,
175         const std::vector<GLfloat>& expected,
176         GLuint size = 0);
177 
178 // SnapshotTest - A helper class for performing a test related to saving or
179 // loading GL translator snapshots. As a test fixture, its setup will prepare a
180 // fresh GL state and paths for temporary snapshot files.
181 //
182 // doSnapshot saves a snapshot, clears the GL state, then loads the snapshot.
183 // saveSnapshot and loadSnapshot can be used to perform saves and loads
184 // independently.
185 //
186 // Usage example:
187 //     TEST_F(SnapshotTest, PreserveFooBar) {
188 //         // clean GL state is ready
189 //         EXPECT_TRUE(fooBarState());
190 //         modifyGlStateFooBar();
191 //         EXPECT_FALSE(fooBarState());  // GL state has been changed
192 //         doSnapshot(); // saves, resets, and reloads the state
193 //         EXPECT_FALSE(fooBarState());  // Snapshot preserved the state change
194 //     }
195 //
196 class SnapshotTest : public gfxstream::gl::GLTest {
197    public:
198     SnapshotTest() = default;
199 
200     void SetUp() override;
201 
202     // Mimics FrameBuffer.onSave, with fewer objects to manage.
203     // |streamFile| is a filename into which the snapshot will be saved.
204     // |textureFile| is a filename into which the textures will be saved.
205     void saveSnapshot(const std::string streamFile,
206                       const std::string textureFile);
207 
208     // Mimics FrameBuffer.onLoad, with fewer objects to manage.
209     // Assumes that a valid display is present.
210     // |streamFile| is a filename from which the snapshot will be loaded.
211     // |textureFile| is a filename from which the textures will be loaded.
212     void loadSnapshot(const std::string streamFile,
213                       const std::string textureFile);
214 
215     // Performs a teardown and reset of graphics objects in preparation for
216     // a snapshot load.
217     void preloadReset();
218 
219     // Mimics saving and then loading a graphics snapshot.
220     // To verify that state has been reset to some default before the load,
221     // assertions can be performed in |preloadCheck|.
222     void doSnapshot(std::function<void()> preloadCheck);
223 
224 protected:
225     android::base::TestSystem mTestSystem;
226     std::string mSnapshotPath = {};
227 };
228 
229 // SnapshotPreserveTest - A helper class building on SnapshotTest for granular
230 // testing of the GL snapshot. This is specifically for the common case where a
231 // piece of GL state has a known default, and our test aims to verify that the
232 // snapshot preserves this piece of state when it has been changed from the
233 // default.
234 //
235 // This acts as an abstract class; implementations should override the state
236 // check state change functions to perform the assertions and operations
237 // relevant to the part of GL state that they are testing.
238 // doCheckedSnapshot can be but does not need to be overwritten. It performs the
239 // following:
240 //      - check for default state
241 //      - make state changes, check that the state changes are in effect
242 //      - save a snapshot, reset the GL state, then check for default state
243 //      - load the snapshot, check that the state changes are in effect again
244 //
245 // Usage example with a subclass:
246 //     class SnapshotEnableFooTest : public SnapshotPreserveTest {
247 //         void defaultStateCheck() override { EXPECT_FALSE(isFooEnabled()); }
248 //         void changedStateCheck() override { EXPECT_TRUE(isFooEnabled());  }
249 //         void stateChange() override { enableFoo(); }
250 //     };
251 //     TEST_F(SnapshotEnableFooTest, PreserveFooEnable) {
252 //         doCheckedSnapshot();
253 //     }
254 //
255 class SnapshotPreserveTest : public SnapshotTest {
256 public:
257     // Asserts that we are working from a clean starting state.
defaultStateCheck()258     virtual void defaultStateCheck() {
259         ADD_FAILURE() << "Snapshot test needs a default state check function.";
260     }
261 
262     // Asserts that any expected changes to state have occurred.
changedStateCheck()263     virtual void changedStateCheck() {
264         ADD_FAILURE()
265                 << "Snapshot test needs a post-change state check function.";
266     }
267 
268     // Modifies the state.
stateChange()269     virtual void stateChange() {
270         ADD_FAILURE() << "Snapshot test needs a state-changer function.";
271     }
272 
273     // Sets up a non-default state and asserts that a snapshot preserves it.
274     virtual void doCheckedSnapshot();
275 };
276 
277 // SnapshotSetValueTest - A helper class for testing preservation of pieces of
278 // GL state where default and changed state checks are comparisons against the
279 // same type of expected reference value.
280 //
281 // The expected |m_default_value| and |m_changed_value| should be set before
282 // a checked snapshot is attempted.
283 //
284 // Usage example with a subclass:
285 //     class SnapshotSetFooTest : public SnapshotSetValueTest<Foo> {
286 //         void stateCheck(Foo expected) { EXPECT_EQ(expected, getFoo()); }
287 //         void stateChange() override { setFoo(*m_changed_value); }
288 //     };
289 //     TEST_F(SnapshotSetFooTest, SetFooValue) {
290 //         setExpectedValues(kFooDefaultValue, kFooTestValue);
291 //         doCheckedSnapshot();
292 //     }
293 //
294 template <class T>
295 class SnapshotSetValueTest : public SnapshotPreserveTest {
296 public:
297     // Configures the test to assert against values which it should consider
298     // default and values which it should expect after changes.
setExpectedValues(T defaultValue,T changedValue)299     void setExpectedValues(T defaultValue, T changedValue) {
300         m_default_value = std::unique_ptr<T>(new T(defaultValue));
301         m_changed_value = std::unique_ptr<T>(new T(changedValue));
302     }
303 
304     // Checks part of state against an expected value.
stateCheck(T expected)305     virtual void stateCheck(T expected) {
306         ADD_FAILURE() << "Snapshot test needs a state-check function.";
307     };
308 
defaultStateCheck()309     void defaultStateCheck() override { stateCheck(*m_default_value); }
changedStateCheck()310     void changedStateCheck() override { stateCheck(*m_changed_value); }
311 
doCheckedSnapshot()312     void doCheckedSnapshot() override {
313         if (m_default_value == nullptr || m_changed_value == nullptr) {
314             FAIL() << "Snapshot test not provided expected values.";
315         }
316         SnapshotPreserveTest::doCheckedSnapshot();
317     }
318 
319 protected:
320     std::unique_ptr<T> m_default_value;
321     std::unique_ptr<T> m_changed_value;
322 };
323 
324 }  // namespace gl
325 }  // namespace gfxstream
326