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