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