blob: 2dc4318b991d6bb4e59a9d39a7a6f3204cb0bb20 [file] [log] [blame]
// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "GLSnapshotTestStateUtils.h"
#include "GLSnapshotTesting.h"
#include "OpenGLTestContext.h"
#include <gtest/gtest.h>
#include <map>
namespace gfxstream {
namespace gl {
namespace {
static const GLenum kGLES2GlobalBufferBindings[] = {
GL_ARRAY_BUFFER_BINDING, GL_ELEMENT_ARRAY_BUFFER_BINDING};
// Buffers could also be bound with vertex attribute arrays.
class SnapshotGlBufferObjectsTest : public SnapshotPreserveTest {
public:
void defaultStateCheck() override {
for (GLenum bindTarget : kGLES2GlobalBufferBindings) {
EXPECT_TRUE(compareGlobalGlInt(gl, bindTarget, 0))
<< "no global buffer object bindings are bound by default";
}
for (auto& it : m_buffers_data) {
EXPECT_EQ(GL_FALSE, gl->glIsBuffer(it.first))
<< "test-added buffer objects should not exist by default";
}
}
void changedStateCheck() override {
// Check that right buffers are bound
for (auto& it : m_bindings) {
GLenum boundTarget;
switch (it.first) {
case GL_ARRAY_BUFFER:
boundTarget = GL_ARRAY_BUFFER_BINDING;
break;
case GL_ELEMENT_ARRAY_BUFFER:
boundTarget = GL_ELEMENT_ARRAY_BUFFER_BINDING;
break;
default:
FAIL() << "Unknown binding location " << it.first;
}
EXPECT_TRUE(compareGlobalGlInt(gl, boundTarget, it.second))
<< "buffer binding " << describeGlEnum(boundTarget)
<< " should be bound with " << it.second;
}
// Check that all buffers have the correct attributes
for (auto& it : m_buffers_data) {
checkBufferData(it.first, it.second);
}
}
void stateChange() override { m_buffer_state_change(); }
// Creates a buffer with the properties in |data| and records its state so
// it can be checked for preservation after a snapshot.
GLuint addBuffer(GlBufferData data) {
GLuint name = createBuffer(gl, data);
m_buffers_data[name] = data;
return name;
}
// Binds a buffer and records the binding to be checked for preservation
// after a snapshot.
void bindBuffer(GLenum binding, GLuint buffer) {
gl->glBindBuffer(binding, buffer);
EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
m_bindings[binding] = buffer;
}
void setObjectStateChange(std::function<void()> func) {
m_buffer_state_change = func;
}
protected:
void checkBufferData(GLuint name, GlBufferData data) {
SCOPED_TRACE("checking data for buffer " + std::to_string(name));
EXPECT_EQ(GL_TRUE, gl->glIsBuffer(name));
// We bind to GL_ARRAY_BUFFER in order to read buffer data,
// so let's hold on to what the old binding was so we can restore it
GLuint currentArrayBuffer;
gl->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&currentArrayBuffer);
EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
gl->glBindBuffer(GL_ARRAY_BUFFER, name);
EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
EXPECT_TRUE(compareBufferParameter(GL_ARRAY_BUFFER, GL_BUFFER_SIZE,
(GLint)data.size));
EXPECT_TRUE(compareBufferParameter(GL_ARRAY_BUFFER, GL_BUFFER_USAGE,
(GLint)data.usage));
// TODO(benzene): compare actual buffer contents?
// in GLES2 there doesn't seem to be a way to directly read the buffer
// contents
// Restore the old binding
gl->glBindBuffer(GL_ARRAY_BUFFER, currentArrayBuffer);
EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
}
testing::AssertionResult compareBufferParameter(GLenum target,
GLenum paramName,
GLint expected) {
GLint value;
gl->glGetBufferParameteriv(target, paramName, &value);
EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
return compareValue<GLint>(
expected, value,
"mismatch on parameter " + describeGlEnum(paramName) +
" for buffer bound to " + describeGlEnum(target));
}
std::map<GLenum, GLuint> m_bindings;
std::map<GLuint, GlBufferData> m_buffers_data;
std::function<void()> m_buffer_state_change = [] {};
};
TEST_F(SnapshotGlBufferObjectsTest, BindArrayAndElementBuffers) {
setObjectStateChange([this] {
GlBufferData arrayData = {128, nullptr, GL_STATIC_DRAW};
GlBufferData elementArrayData = {256, nullptr, GL_DYNAMIC_DRAW};
GLuint arrayBuff = addBuffer(arrayData);
GLuint elementArrayBuff = addBuffer(elementArrayData);
bindBuffer(GL_ARRAY_BUFFER, arrayBuff);
bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuff);
});
doCheckedSnapshot();
}
} // namespace
} // namespace gl
} // namespace gfxstream