blob: 05c3c6ef739a586fbcde9fe36ad198f23bf8e71c [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 "GLSnapshotTesting.h"
#include "apigen-codec-common/glUtils.h"
#include <gtest/gtest.h>
#include <map>
namespace gfxstream {
namespace gl {
namespace {
struct GlFramebufferAttachment {
GLenum type;
GLuint name;
GLenum textureLevel;
GLenum textureCubeMapFace;
};
struct GlFramebufferObjectState {
std::map<GLenum, GlFramebufferAttachment> attachments;
};
class SnapshotGlFramebufferObjectTest : public SnapshotPreserveTest {
public:
void defaultStateCheck() override {
EXPECT_EQ(GL_FALSE, gl->glIsFramebuffer(m_framebuffer_name));
EXPECT_TRUE(compareGlobalGlInt(gl, GL_FRAMEBUFFER_BINDING, 0));
}
void changedStateCheck() override {
EXPECT_EQ(GL_TRUE, gl->glIsFramebuffer(m_framebuffer_name));
EXPECT_TRUE(compareGlobalGlInt(gl, GL_FRAMEBUFFER_BINDING,
m_framebuffer_name));
// don't lose current framebuffer binding
GLint currentBind;
gl->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currentBind);
EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
for (auto& pair : m_state.attachments) {
const GLenum& attachment = pair.first;
GlFramebufferAttachment& expected = pair.second;
GlFramebufferAttachment current = {};
gl->glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer_name);
gl->glGetFramebufferAttachmentParameteriv(
GL_FRAMEBUFFER, attachment,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
(GLint*)&current.type);
EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
if (current.type != GL_NONE) {
gl->glGetFramebufferAttachmentParameteriv(
GL_FRAMEBUFFER, attachment,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
(GLint*)&current.name);
if (current.type == GL_TEXTURE) {
gl->glGetFramebufferAttachmentParameteriv(
GL_FRAMEBUFFER, attachment,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
(GLint*)&current.textureLevel);
gl->glGetFramebufferAttachmentParameteriv(
GL_FRAMEBUFFER, attachment,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE,
(GLint*)&current.textureCubeMapFace);
}
}
EXPECT_EQ(expected.type, current.type);
EXPECT_EQ(expected.name, current.name);
EXPECT_EQ(expected.textureLevel, current.textureLevel);
EXPECT_EQ(expected.textureCubeMapFace, current.textureCubeMapFace);
}
// restore framebuffer binding
gl->glBindFramebuffer(GL_FRAMEBUFFER, currentBind);
}
void stateChange() override {
gl->glGenFramebuffers(1, &m_framebuffer_name);
gl->glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer_name);
m_state_changer();
}
void setStateChanger(std::function<void()> changer) {
m_state_changer = changer;
}
protected:
GLuint m_framebuffer_name = 0;
GlFramebufferObjectState m_state = {};
std::function<void()> m_state_changer = [] {};
};
TEST_F(SnapshotGlFramebufferObjectTest, CreateAndBind) {
doCheckedSnapshot();
}
TEST_F(SnapshotGlFramebufferObjectTest, BindDepthRenderbuffer) {
setStateChanger([this] {
GLuint renderbuffer;
gl->glGenRenderbuffers(1, &renderbuffer);
gl->glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
gl->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, renderbuffer);
EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
m_state.attachments[GL_DEPTH_ATTACHMENT] = {GL_RENDERBUFFER,
renderbuffer, 0, 0};
});
doCheckedSnapshot();
}
TEST_F(SnapshotGlFramebufferObjectTest, BindStencilTextureCubeFace) {
setStateChanger([this] {
GLuint texture;
gl->glGenTextures(1, &texture);
gl->glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
gl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X, texture, 0);
EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
m_state.attachments[GL_STENCIL_ATTACHMENT] = {
GL_TEXTURE, texture, 0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X};
});
doCheckedSnapshot();
}
TEST_F(SnapshotGlFramebufferObjectTest, BindColor0Texture2D) {
setStateChanger([this] {
GLuint texture;
gl->glGenTextures(1, &texture);
gl->glBindTexture(GL_TEXTURE_2D, texture);
// In GLES2, mipmap level must be 0
gl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, texture, 0);
EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
m_state.attachments[GL_COLOR_ATTACHMENT0] = {GL_TEXTURE, texture, 0, 0};
});
doCheckedSnapshot();
}
} // namespace
} // namespace gl
} // namespace gfxstream