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
23 namespace gfxstream {
24 namespace gl {
25 namespace {
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:
defaultStateCheck()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
changedStateCheck()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
stateChange()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.
addBuffer(GlBufferData data)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.
bindBuffer(GLenum binding,GLuint buffer)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
setObjectStateChange(std::function<void ()> func)89 void setObjectStateChange(std::function<void()> func) {
90 m_buffer_state_change = func;
91 }
92
93 protected:
checkBufferData(GLuint name,GlBufferData data)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
compareBufferParameter(GLenum target,GLenum paramName,GLint expected)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;
__anon126380d70202null133 std::function<void()> m_buffer_state_change = [] {};
134 };
135
TEST_F(SnapshotGlBufferObjectsTest,BindArrayAndElementBuffers)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
148 } // namespace
149 } // namespace gl
150 } // namespace gfxstream
151