blob: e38ce7b471a2f67e3cd874ce516cc2bc43996aa2 [file] [log] [blame]
//
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RobustResourceInitTest: Tests for GL_ANGLE_robust_resource_initialization.
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
namespace angle
{
class RobustResourceInitTest : public ANGLETest
{
protected:
RobustResourceInitTest()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
// Defer context init until the test body.
setDeferContextInit(true);
setRobustResourceInit(true);
}
bool hasEGLExtension()
{
EGLDisplay display = getEGLWindow()->getDisplay();
ASSERT(display != EGL_NO_DISPLAY);
return (eglDisplayExtensionEnabled(
display, "EGL_ANGLE_create_context_robust_resource_initialization"));
}
bool setup()
{
if (!hasEGLExtension())
{
return false;
}
if (!getEGLWindow()->initializeContext())
{
EXPECT_TRUE(false);
return false;
}
return true;
}
};
// Context creation should fail if EGL_ANGLE_create_context_robust_resource_initialization
// is not available, and succeed otherwise.
TEST_P(RobustResourceInitTest, ExtensionInit)
{
if (hasEGLExtension())
{
// Context creation shold succeed with robust resource init enabled.
EXPECT_TRUE(getEGLWindow()->initializeContext());
// Robust resource init extension should be available.
EXPECT_TRUE(extensionEnabled("GL_ANGLE_robust_resource_initialization"));
// Querying the state value should return true.
GLboolean enabled = 0;
glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
EXPECT_GL_NO_ERROR();
EXPECT_GL_TRUE(enabled);
EXPECT_GL_TRUE(glIsEnabled(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
}
else
{
// Context creation should fail with robust resource init enabled.
EXPECT_FALSE(getEGLWindow()->initializeContext());
// Context creation should succeed with robust resource init disabled.
setRobustResourceInit(false);
ASSERT_TRUE(getEGLWindow()->initializeGL(GetOSWindow()));
// If context extension string exposed, check queries.
if (extensionEnabled("GL_ANGLE_robust_resource_initialization"))
{
GLboolean enabled = 0;
glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
EXPECT_GL_FALSE(enabled);
EXPECT_GL_FALSE(glIsEnabled(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
EXPECT_GL_NO_ERROR();
}
else
{
// Querying robust resource init should return INVALID_ENUM.
GLboolean enabled = 0;
glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
}
}
// Test queries on a normal, non-robust enabled context.
TEST_P(RobustResourceInitTest, QueriesOnNonRobustContext)
{
EGLDisplay display = getEGLWindow()->getDisplay();
ASSERT_TRUE(display != EGL_NO_DISPLAY);
if (!hasEGLExtension())
{
return;
}
setRobustResourceInit(false);
EXPECT_TRUE(getEGLWindow()->initializeContext());
// If context extension string exposed, check queries.
ASSERT_TRUE(extensionEnabled("GL_ANGLE_robust_resource_initialization"));
// Querying robust resource init should return INVALID_ENUM.
GLboolean enabled = 0;
glGetBooleanv(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &enabled);
EXPECT_GL_FALSE(enabled);
EXPECT_GL_FALSE(glIsEnabled(GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
EXPECT_GL_NO_ERROR();
}
// Tests that buffers start zero-filled if the data pointer is null.
TEST_P(RobustResourceInitTest, BufferData)
{
if (!setup())
{
return;
}
GLBuffer buffer;
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, getWindowWidth() * getWindowHeight() * sizeof(GLfloat), nullptr,
GL_STATIC_DRAW);
const std::string &vertexShader =
"attribute vec2 position;\n"
"attribute float testValue;\n"
"varying vec4 colorOut;\n"
"void main() {\n"
" gl_Position = vec4(position, 0, 1);\n"
" colorOut = testValue == 0.0 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
"}";
const std::string &fragmentShader =
"varying mediump vec4 colorOut;\n"
"void main() {\n"
" gl_FragColor = colorOut;\n"
"}";
ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
GLint testValueLoc = glGetAttribLocation(program.get(), "testValue");
ASSERT_NE(-1, testValueLoc);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glVertexAttribPointer(testValueLoc, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
glEnableVertexAttribArray(testValueLoc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
drawQuad(program.get(), "position", 0.5f);
ASSERT_GL_NO_ERROR();
std::vector<GLColor> expected(getWindowWidth() * getWindowHeight(), GLColor::green);
std::vector<GLColor> actual(getWindowWidth() * getWindowHeight());
glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
actual.data());
EXPECT_EQ(expected, actual);
}
ANGLE_INSTANTIATE_TEST(RobustResourceInitTest,
ES2_D3D9(),
ES2_D3D11(),
ES3_D3D11(),
ES2_D3D11_FL9_3(),
ES2_OPENGL(),
ES3_OPENGL(),
ES2_OPENGLES(),
ES3_OPENGLES());
} // namespace