blob: 2dc4318b991d6bb4e59a9d39a7a6f3204cb0bb20 [file] [log] [blame]
Lingfeng Yang0e6868f2020-11-03 12:32:59 -08001// 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 Macnaked0c9e62023-03-30 15:58:24 -070023namespace gfxstream {
24namespace gl {
25namespace {
Lingfeng Yang0e6868f2020-11-03 12:32:59 -080026
27static const GLenum kGLES2GlobalBufferBindings[] = {
28 GL_ARRAY_BUFFER_BINDING, GL_ELEMENT_ARRAY_BUFFER_BINDING};
29// Buffers could also be bound with vertex attribute arrays.
30
31class SnapshotGlBufferObjectsTest : public SnapshotPreserveTest {
32public:
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
93protected:
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*)&currentArrayBuffer);
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
136TEST_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 Macnaked0c9e62023-03-30 15:58:24 -0700148} // namespace
149} // namespace gl
150} // namespace gfxstream