Lingfeng Yang | 0e6868f | 2020-11-03 12:32:59 -0800 | [diff] [blame] | 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 | #include "GLSnapshotTestStateUtils.h" |
| 16 | #include "GLSnapshotTesting.h" |
| 17 | #include "OpenGLTestContext.h" |
| 18 | |
| 19 | #include <gtest/gtest.h> |
| 20 | |
| 21 | #include <map> |
| 22 | |
Jason Macnak | ed0c9e6 | 2023-03-30 15:58:24 -0700 | [diff] [blame] | 23 | namespace gfxstream { |
| 24 | namespace gl { |
| 25 | namespace { |
Lingfeng Yang | 0e6868f | 2020-11-03 12:32:59 -0800 | [diff] [blame] | 26 | |
| 27 | static const GLenum kGLES2GlobalBufferBindings[] = { |
| 28 | GL_ARRAY_BUFFER_BINDING, GL_ELEMENT_ARRAY_BUFFER_BINDING}; |
| 29 | // Buffers could also be bound with vertex attribute arrays. |
| 30 | |
| 31 | class SnapshotGlBufferObjectsTest : public SnapshotPreserveTest { |
| 32 | public: |
| 33 | void defaultStateCheck() override { |
| 34 | for (GLenum bindTarget : kGLES2GlobalBufferBindings) { |
| 35 | EXPECT_TRUE(compareGlobalGlInt(gl, bindTarget, 0)) |
| 36 | << "no global buffer object bindings are bound by default"; |
| 37 | } |
| 38 | for (auto& it : m_buffers_data) { |
| 39 | EXPECT_EQ(GL_FALSE, gl->glIsBuffer(it.first)) |
| 40 | << "test-added buffer objects should not exist by default"; |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | void changedStateCheck() override { |
| 45 | // Check that right buffers are bound |
| 46 | for (auto& it : m_bindings) { |
| 47 | GLenum boundTarget; |
| 48 | switch (it.first) { |
| 49 | case GL_ARRAY_BUFFER: |
| 50 | boundTarget = GL_ARRAY_BUFFER_BINDING; |
| 51 | break; |
| 52 | case GL_ELEMENT_ARRAY_BUFFER: |
| 53 | boundTarget = GL_ELEMENT_ARRAY_BUFFER_BINDING; |
| 54 | break; |
| 55 | default: |
| 56 | FAIL() << "Unknown binding location " << it.first; |
| 57 | } |
| 58 | |
| 59 | EXPECT_TRUE(compareGlobalGlInt(gl, boundTarget, it.second)) |
| 60 | << "buffer binding " << describeGlEnum(boundTarget) |
| 61 | << " should be bound with " << it.second; |
| 62 | } |
| 63 | |
| 64 | // Check that all buffers have the correct attributes |
| 65 | for (auto& it : m_buffers_data) { |
| 66 | checkBufferData(it.first, it.second); |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | void stateChange() override { m_buffer_state_change(); } |
| 71 | |
| 72 | // Creates a buffer with the properties in |data| and records its state so |
| 73 | // it can be checked for preservation after a snapshot. |
| 74 | GLuint addBuffer(GlBufferData data) { |
| 75 | GLuint name = createBuffer(gl, data); |
| 76 | m_buffers_data[name] = data; |
| 77 | return name; |
| 78 | } |
| 79 | |
| 80 | // Binds a buffer and records the binding to be checked for preservation |
| 81 | // after a snapshot. |
| 82 | void bindBuffer(GLenum binding, GLuint buffer) { |
| 83 | gl->glBindBuffer(binding, buffer); |
| 84 | EXPECT_EQ(GL_NO_ERROR, gl->glGetError()); |
| 85 | |
| 86 | m_bindings[binding] = buffer; |
| 87 | } |
| 88 | |
| 89 | void setObjectStateChange(std::function<void()> func) { |
| 90 | m_buffer_state_change = func; |
| 91 | } |
| 92 | |
| 93 | protected: |
| 94 | void checkBufferData(GLuint name, GlBufferData data) { |
| 95 | SCOPED_TRACE("checking data for buffer " + std::to_string(name)); |
| 96 | EXPECT_EQ(GL_TRUE, gl->glIsBuffer(name)); |
| 97 | |
| 98 | // We bind to GL_ARRAY_BUFFER in order to read buffer data, |
| 99 | // so let's hold on to what the old binding was so we can restore it |
| 100 | GLuint currentArrayBuffer; |
| 101 | gl->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)¤tArrayBuffer); |
| 102 | EXPECT_EQ(GL_NO_ERROR, gl->glGetError()); |
| 103 | |
| 104 | gl->glBindBuffer(GL_ARRAY_BUFFER, name); |
| 105 | EXPECT_EQ(GL_NO_ERROR, gl->glGetError()); |
| 106 | EXPECT_TRUE(compareBufferParameter(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, |
| 107 | (GLint)data.size)); |
| 108 | EXPECT_TRUE(compareBufferParameter(GL_ARRAY_BUFFER, GL_BUFFER_USAGE, |
| 109 | (GLint)data.usage)); |
| 110 | // TODO(benzene): compare actual buffer contents? |
| 111 | // in GLES2 there doesn't seem to be a way to directly read the buffer |
| 112 | // contents |
| 113 | |
| 114 | // Restore the old binding |
| 115 | gl->glBindBuffer(GL_ARRAY_BUFFER, currentArrayBuffer); |
| 116 | EXPECT_EQ(GL_NO_ERROR, gl->glGetError()); |
| 117 | } |
| 118 | |
| 119 | testing::AssertionResult compareBufferParameter(GLenum target, |
| 120 | GLenum paramName, |
| 121 | GLint expected) { |
| 122 | GLint value; |
| 123 | gl->glGetBufferParameteriv(target, paramName, &value); |
| 124 | EXPECT_EQ(GL_NO_ERROR, gl->glGetError()); |
| 125 | return compareValue<GLint>( |
| 126 | expected, value, |
| 127 | "mismatch on parameter " + describeGlEnum(paramName) + |
| 128 | " for buffer bound to " + describeGlEnum(target)); |
| 129 | } |
| 130 | |
| 131 | std::map<GLenum, GLuint> m_bindings; |
| 132 | std::map<GLuint, GlBufferData> m_buffers_data; |
| 133 | std::function<void()> m_buffer_state_change = [] {}; |
| 134 | }; |
| 135 | |
| 136 | TEST_F(SnapshotGlBufferObjectsTest, BindArrayAndElementBuffers) { |
| 137 | setObjectStateChange([this] { |
| 138 | GlBufferData arrayData = {128, nullptr, GL_STATIC_DRAW}; |
| 139 | GlBufferData elementArrayData = {256, nullptr, GL_DYNAMIC_DRAW}; |
| 140 | GLuint arrayBuff = addBuffer(arrayData); |
| 141 | GLuint elementArrayBuff = addBuffer(elementArrayData); |
| 142 | bindBuffer(GL_ARRAY_BUFFER, arrayBuff); |
| 143 | bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuff); |
| 144 | }); |
| 145 | doCheckedSnapshot(); |
| 146 | } |
| 147 | |
Jason Macnak | ed0c9e6 | 2023-03-30 15:58:24 -0700 | [diff] [blame] | 148 | } // namespace |
| 149 | } // namespace gl |
| 150 | } // namespace gfxstream |