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