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