mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
305 lines
8.2 KiB
C++
305 lines
8.2 KiB
C++
// Copyright 2014 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include <GLES2/gl2.h>
|
|
#include <GLES2/gl2ext.h>
|
|
|
|
#include "gpu/command_buffer/tests/gl_manager.h"
|
|
#include "gpu/command_buffer/tests/gl_test_utils.h"
|
|
#include "testing/gmock/include/gmock/gmock.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
|
|
#define SHADER(Src) #Src
|
|
|
|
namespace gpu {
|
|
|
|
class GLVirtualContextsTest : public testing::Test {
|
|
protected:
|
|
static const int kSize0 = 4;
|
|
static const int kSize1 = 8;
|
|
static const int kSize2 = 16;
|
|
|
|
static const GLfloat kFloatRed[4];
|
|
static const GLfloat kFloatGreen[4];
|
|
static const uint8 kExpectedRed[4];
|
|
static const uint8 kExpectedGreen[4];
|
|
|
|
void SetUp() override {
|
|
GLManager::Options options;
|
|
options.size = gfx::Size(kSize0, kSize0);
|
|
gl_real_.Initialize(options);
|
|
gl_real_shared_.Initialize(options);
|
|
options.virtual_manager = &gl_real_shared_;
|
|
options.size = gfx::Size(kSize1, kSize1);
|
|
gl1_.Initialize(options);
|
|
options.size = gfx::Size(kSize2, kSize2);
|
|
gl2_.Initialize(options);
|
|
}
|
|
|
|
void TearDown() override {
|
|
gl1_.Destroy();
|
|
gl2_.Destroy();
|
|
gl_real_shared_.Destroy();
|
|
gl_real_.Destroy();
|
|
}
|
|
|
|
GLuint SetupColoredVertexProgram() {
|
|
static const char* v_shader_str = SHADER(
|
|
attribute vec4 a_position;
|
|
attribute vec4 a_color;
|
|
varying vec4 v_color;
|
|
void main()
|
|
{
|
|
gl_Position = a_position;
|
|
v_color = a_color;
|
|
}
|
|
);
|
|
|
|
static const char* f_shader_str = SHADER(
|
|
precision mediump float;
|
|
varying vec4 v_color;
|
|
void main()
|
|
{
|
|
gl_FragColor = v_color;
|
|
}
|
|
);
|
|
|
|
GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
|
|
glUseProgram(program);
|
|
return program;
|
|
}
|
|
|
|
void SetUpColoredUnitQuad(const GLfloat* color) {
|
|
GLuint program1 = SetupColoredVertexProgram();
|
|
GLuint position_loc1 = glGetAttribLocation(program1, "a_position");
|
|
GLuint color_loc1 = glGetAttribLocation(program1, "a_color");
|
|
GLTestHelper::SetupUnitQuad(position_loc1);
|
|
GLTestHelper::SetupColorsForUnitQuad(color_loc1, color, GL_STATIC_DRAW);
|
|
}
|
|
|
|
GLManager gl_real_;
|
|
GLManager gl_real_shared_;
|
|
GLManager gl1_;
|
|
GLManager gl2_;
|
|
};
|
|
|
|
const GLfloat GLVirtualContextsTest::kFloatRed[4] = {
|
|
1.0f, 0.0f, 0.0f, 1.0f,
|
|
};
|
|
const GLfloat GLVirtualContextsTest::kFloatGreen[4] = {
|
|
0.0f, 1.0f, 0.0f, 1.0f,
|
|
};
|
|
const uint8 GLVirtualContextsTest::kExpectedRed[4] = {
|
|
255, 0, 0, 255,
|
|
};
|
|
const uint8 GLVirtualContextsTest::kExpectedGreen[4] = {
|
|
0, 255, 0, 255,
|
|
};
|
|
|
|
namespace {
|
|
|
|
void SetupSimpleShader(const uint8* color) {
|
|
static const char* v_shader_str = SHADER(
|
|
attribute vec4 a_Position;
|
|
void main()
|
|
{
|
|
gl_Position = a_Position;
|
|
}
|
|
);
|
|
|
|
static const char* f_shader_str = SHADER(
|
|
precision mediump float;
|
|
uniform vec4 u_color;
|
|
void main()
|
|
{
|
|
gl_FragColor = u_color;
|
|
}
|
|
);
|
|
|
|
GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
|
|
glUseProgram(program);
|
|
|
|
GLuint position_loc = glGetAttribLocation(program, "a_Position");
|
|
|
|
GLTestHelper::SetupUnitQuad(position_loc);
|
|
|
|
GLuint color_loc = glGetUniformLocation(program, "u_color");
|
|
glUniform4f(
|
|
color_loc,
|
|
color[0] / 255.0f,
|
|
color[1] / 255.0f,
|
|
color[2] / 255.0f,
|
|
color[3] / 255.0f);
|
|
}
|
|
|
|
void TestDraw(int size) {
|
|
uint8 expected_clear[] = { 127, 0, 255, 0, };
|
|
glClearColor(0.5f, 0.0f, 1.0f, 0.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, size, size, 1, expected_clear));
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
// http://crbug.com/281565
|
|
TEST_F(GLVirtualContextsTest, Basic) {
|
|
struct TestInfo {
|
|
int size;
|
|
uint8 color[4];
|
|
GLManager* manager;
|
|
};
|
|
const int kNumTests = 3;
|
|
TestInfo tests[] = {
|
|
{ kSize0, { 255, 0, 0, 0, }, &gl_real_, },
|
|
{ kSize1, { 0, 255, 0, 0, }, &gl1_, },
|
|
{ kSize2, { 0, 0, 255, 0, }, &gl2_, },
|
|
};
|
|
|
|
for (int ii = 0; ii < kNumTests; ++ii) {
|
|
const TestInfo& test = tests[ii];
|
|
GLManager* gl_manager = test.manager;
|
|
gl_manager->MakeCurrent();
|
|
SetupSimpleShader(test.color);
|
|
}
|
|
|
|
for (int ii = 0; ii < kNumTests; ++ii) {
|
|
const TestInfo& test = tests[ii];
|
|
GLManager* gl_manager = test.manager;
|
|
gl_manager->MakeCurrent();
|
|
TestDraw(test.size);
|
|
}
|
|
|
|
for (int ii = 0; ii < kNumTests; ++ii) {
|
|
const TestInfo& test = tests[ii];
|
|
GLManager* gl_manager = test.manager;
|
|
gl_manager->MakeCurrent();
|
|
EXPECT_TRUE(GLTestHelper::CheckPixels(
|
|
0, 0, test.size, test.size, 0, test.color));
|
|
}
|
|
|
|
for (int ii = 0; ii < kNumTests; ++ii) {
|
|
const TestInfo& test = tests[ii];
|
|
GLManager* gl_manager = test.manager;
|
|
gl_manager->MakeCurrent();
|
|
GLTestHelper::CheckGLError("no errors", __LINE__);
|
|
}
|
|
}
|
|
|
|
// http://crbug.com/363407
|
|
TEST_F(GLVirtualContextsTest, VertexArrayObjectRestore) {
|
|
GLuint vao1 = 0, vao2 = 0;
|
|
|
|
gl1_.MakeCurrent();
|
|
// Set up red quad in vao1.
|
|
glGenVertexArraysOES(1, &vao1);
|
|
glBindVertexArrayOES(vao1);
|
|
SetUpColoredUnitQuad(kFloatRed);
|
|
glFinish();
|
|
|
|
gl2_.MakeCurrent();
|
|
// Set up green quad in vao2.
|
|
glGenVertexArraysOES(1, &vao2);
|
|
glBindVertexArrayOES(vao2);
|
|
SetUpColoredUnitQuad(kFloatGreen);
|
|
glFinish();
|
|
|
|
gl1_.MakeCurrent();
|
|
// Test to ensure that vao1 is still the active VAO for this context.
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed));
|
|
glFinish();
|
|
GLTestHelper::CheckGLError("no errors", __LINE__);
|
|
|
|
gl2_.MakeCurrent();
|
|
// Test to ensure that vao2 is still the active VAO for this context.
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
EXPECT_TRUE(
|
|
GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen));
|
|
glFinish();
|
|
GLTestHelper::CheckGLError("no errors", __LINE__);
|
|
}
|
|
|
|
// http://crbug.com/363407
|
|
TEST_F(GLVirtualContextsTest, VertexArrayObjectRestoreRebind) {
|
|
GLuint vao1 = 0, vao2 = 0;
|
|
|
|
gl1_.MakeCurrent();
|
|
// Set up red quad in vao1.
|
|
glGenVertexArraysOES(1, &vao1);
|
|
glBindVertexArrayOES(vao1);
|
|
SetUpColoredUnitQuad(kFloatRed);
|
|
glFinish();
|
|
|
|
gl2_.MakeCurrent();
|
|
// Set up green quad in new vao2.
|
|
glGenVertexArraysOES(1, &vao2);
|
|
glBindVertexArrayOES(vao2);
|
|
SetUpColoredUnitQuad(kFloatGreen);
|
|
glFinish();
|
|
|
|
gl1_.MakeCurrent();
|
|
// Test to ensure that vao1 hasn't been corrupted after rebinding.
|
|
// Bind 0 is required so that bind vao1 is not optimized away in the service.
|
|
glBindVertexArrayOES(0);
|
|
glBindVertexArrayOES(vao1);
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed));
|
|
glFinish();
|
|
GLTestHelper::CheckGLError("no errors", __LINE__);
|
|
|
|
gl2_.MakeCurrent();
|
|
// Test to ensure that vao1 hasn't been corrupted after rebinding.
|
|
// Bind 0 is required so that bind vao2 is not optimized away in the service.
|
|
glBindVertexArrayOES(0);
|
|
glBindVertexArrayOES(vao2);
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
EXPECT_TRUE(
|
|
GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen));
|
|
glFinish();
|
|
|
|
GLTestHelper::CheckGLError("no errors", __LINE__);
|
|
}
|
|
|
|
// http://crbug.com/363407
|
|
TEST_F(GLVirtualContextsTest, VertexArrayObjectRestoreDefault) {
|
|
gl1_.MakeCurrent();
|
|
// Set up red quad in default VAO.
|
|
SetUpColoredUnitQuad(kFloatRed);
|
|
glFinish();
|
|
|
|
gl2_.MakeCurrent();
|
|
// Set up green quad in default VAO.
|
|
SetUpColoredUnitQuad(kFloatGreen);
|
|
glFinish();
|
|
|
|
// Gen & bind a non-default VAO.
|
|
GLuint vao;
|
|
glGenVertexArraysOES(1, &vao);
|
|
glBindVertexArrayOES(vao);
|
|
glFinish();
|
|
|
|
gl1_.MakeCurrent();
|
|
// Test to ensure that default VAO on gl1_ is still valid.
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, kSize1, kSize1, 0, kExpectedRed));
|
|
glFinish();
|
|
|
|
gl2_.MakeCurrent();
|
|
// Test to ensure that default VAO on gl2_ is still valid.
|
|
// This tests that a default VAO is restored even when it's not currently
|
|
// bound during the context switch.
|
|
glBindVertexArrayOES(0);
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
EXPECT_TRUE(
|
|
GLTestHelper::CheckPixels(0, 0, kSize2, kSize2, 0, kExpectedGreen));
|
|
glFinish();
|
|
|
|
GLTestHelper::CheckGLError("no errors", __LINE__);
|
|
}
|
|
|
|
} // namespace gpu
|
|
|