blob: ca47fbae25c65b8d5050d681e0489ee9af15413b [file] [log] [blame]
// Copyright 2017 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.
// This file defines tests that implementations of GLImage should pass in order
// to be conformant.
#include "ui/gl/test/gl_image_test_template.h"
namespace gl {
namespace {
GLuint LoadVertexShader() {
bool is_desktop_core_profile =
GLContext::GetCurrent()->GetVersionInfo()->is_desktop_core_profile;
std::string vertex_shader = base::StringPrintf(
"%s" // version
"%s vec2 a_position;\n"
"%s vec2 v_texCoord;\n"
"void main() {\n"
" gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0);\n"
" v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5;\n"
"}",
is_desktop_core_profile ? "#version 150\n" : "",
is_desktop_core_profile ? "in" : "attribute",
is_desktop_core_profile ? "out" : "varying");
return GLHelper::LoadShader(GL_VERTEX_SHADER, vertex_shader.c_str());
}
// Compiles a fragment shader for sampling out of a texture of |size| bound to
// |target| and checks for compilation errors.
GLuint LoadFragmentShader(unsigned target, const gfx::Size& size) {
bool is_desktop_core_profile =
GLContext::GetCurrent()->GetVersionInfo()->is_desktop_core_profile;
bool is_gles = GLContext::GetCurrent()->GetVersionInfo()->is_es;
std::string fragment_shader_main = base::StringPrintf(
"uniform SamplerType a_texture;\n"
"%s vec2 v_texCoord;\n"
"%s" // output variable declaration
"void main() {\n"
" %s = TextureLookup(a_texture, v_texCoord * TextureScale);\n"
"}",
is_desktop_core_profile ? "in" : "varying",
is_desktop_core_profile ? "out vec4 my_FragData;\n" : "",
is_desktop_core_profile ? "my_FragData" : "gl_FragData[0]");
switch (target) {
case GL_TEXTURE_2D:
return GLHelper::LoadShader(
GL_FRAGMENT_SHADER,
base::StringPrintf("%s" // version
"%s" // precision
"#define SamplerType sampler2D\n"
"#define TextureLookup %s\n"
"#define TextureScale vec2(1.0, 1.0)\n"
"%s", // main function
is_desktop_core_profile ? "#version 150\n" : "",
is_gles ? "precision mediump float;\n" : "",
is_desktop_core_profile ? "texture" : "texture2D",
fragment_shader_main.c_str())
.c_str());
case GL_TEXTURE_RECTANGLE_ARB:
DCHECK(!is_gles);
return GLHelper::LoadShader(
GL_FRAGMENT_SHADER,
base::StringPrintf(
"%s" // version
"%s" // extension
"#define SamplerType sampler2DRect\n"
"#define TextureLookup %s\n"
"#define TextureScale vec2(%f, %f)\n"
"%s", // main function
is_desktop_core_profile ? "#version 150\n" : "",
is_desktop_core_profile
? ""
: "#extension GL_ARB_texture_rectangle : require\n",
is_desktop_core_profile ? "texture" : "texture2DRect",
static_cast<double>(size.width()),
static_cast<double>(size.height()), fragment_shader_main.c_str())
.c_str());
case GL_TEXTURE_EXTERNAL_OES:
DCHECK(is_gles);
return GLHelper::LoadShader(
GL_FRAGMENT_SHADER,
base::StringPrintf("#extension GL_OES_EGL_image_external : require\n"
"%s" // precision
"#define SamplerType samplerExternalOES\n"
"#define TextureLookup texture2D\n"
"#define TextureScale vec2(1.0, 1.0)\n"
"%s", // main function
is_gles ? "precision mediump float;\n" : "",
fragment_shader_main.c_str())
.c_str());
default:
NOTREACHED();
return 0;
}
}
} // namespace
namespace internal {
// Draws texture bound to |target| of texture unit 0 to the currently bound
// frame buffer.
void DrawTextureQuad(GLenum target, const gfx::Size& size) {
GLuint vao = 0;
if (GLHelper::ShouldTestsUseVAOs()) {
glGenVertexArraysOES(1, &vao);
glBindVertexArrayOES(vao);
}
GLuint vertex_shader = LoadVertexShader();
GLuint fragment_shader = LoadFragmentShader(target, size);
GLuint program = GLHelper::SetupProgram(vertex_shader, fragment_shader);
EXPECT_NE(program, 0u);
glUseProgram(program);
GLint sampler_location = glGetUniformLocation(program, "a_texture");
ASSERT_NE(sampler_location, -1);
glUniform1i(sampler_location, 0);
GLuint vertex_buffer = GLHelper::SetupQuadVertexBuffer();
GLHelper::DrawQuad(vertex_buffer);
if (vao != 0) {
glDeleteVertexArraysOES(1, &vao);
}
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
glDeleteProgram(program);
glDeleteBuffersARB(1, &vertex_buffer);
}
} // namespace internal
base::Optional<GLImplementation>
GLImageTestDelegateBase::GetPreferedGLImplementation() const {
return base::nullopt;
}
bool GLImageTestDelegateBase::SkipTest() const {
return false;
}
} // namespace gl