mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-01-01 04:18:46 +01:00
cefclient: osr: Implement shader-based rendering for Linux (fixes #3187)
Windows still uses OpenGL 1.1 to avoid the added complexity of linking newer OpenGL APIs on that platform. MacOS has deprecated OpenGL and we should eventually provide a Metal-based implementation on that platform.
This commit is contained in:
parent
5a9b8e2bc4
commit
3507249202
@ -4,11 +4,20 @@
|
||||
|
||||
#include "tests/cefclient/browser/osr_renderer.h"
|
||||
|
||||
#if USE_SHADERS
|
||||
// Expose prototypes for OpenGL shader functions.
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <gl/gl.h>
|
||||
#elif defined(OS_MAC)
|
||||
#define GL_SILENCE_DEPRECATION
|
||||
#if USE_SHADERS
|
||||
#include <OpenGL/gl3.h>
|
||||
#else
|
||||
#include <OpenGL/gl.h>
|
||||
#endif
|
||||
#elif defined(OS_LINUX)
|
||||
#include <GL/gl.h>
|
||||
#else
|
||||
@ -41,14 +50,205 @@
|
||||
|
||||
namespace client {
|
||||
|
||||
#if USE_SHADERS
|
||||
namespace {
|
||||
|
||||
const char* kScreenVertexShader =
|
||||
"#version 330 core\n"
|
||||
"out vec2 texCoord;\n"
|
||||
"uniform mat4 transform;\n"
|
||||
"void main() {\n"
|
||||
"\tfloat x = float(((uint(gl_VertexID) + 2u) / 3u)\%2u);\n"
|
||||
"\tfloat y = float(((uint(gl_VertexID) + 1u) / 3u)\%2u);\n"
|
||||
"\tvec4 pos = vec4(-1.0f + x*2.0f, -1.0f + y*2.0f, 0.0f, 1.0f);\n"
|
||||
"\tgl_Position = transform * pos;\n"
|
||||
"\ttexCoord = vec2(x, -y);\n"
|
||||
"}";
|
||||
|
||||
const char* kScreenFragmentShader =
|
||||
"#version 330 core\n"
|
||||
"out vec4 fColor;\n"
|
||||
"in vec2 texCoord;\n"
|
||||
"uniform sampler2D texture;\n"
|
||||
"void main() {\n"
|
||||
"\tfColor = texture2D(texture, texCoord);\n"
|
||||
"}";
|
||||
|
||||
const char* kUpdateRectVertexShader =
|
||||
"#version 330 core\n"
|
||||
"layout (location = 0) in vec2 pos;\n"
|
||||
"layout (location = 1) in vec3 color;\n"
|
||||
"out vec4 vColor;\n"
|
||||
"uniform mat4 transform;\n"
|
||||
"void main() {\n"
|
||||
"\tgl_Position = transform * vec4(pos, 0.0f, 1.0f);\n"
|
||||
"\tvColor = vec4(color, 1.0f);\n"
|
||||
"}";
|
||||
|
||||
const char* kUpdateRectFragmentShader =
|
||||
"#version 330 core\n"
|
||||
"out vec4 fColor;\n"
|
||||
"in vec4 vColor;\n"
|
||||
"void main() {\n"
|
||||
"\tfColor = vColor;\n"
|
||||
"}";
|
||||
|
||||
// clang-format off
|
||||
constexpr float kLineVertices[] = {
|
||||
// pos // color
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
using mat4x4_t = float[16];
|
||||
|
||||
void mat4x4_identity(mat4x4_t& matrix) {
|
||||
// row 0
|
||||
matrix[0] = 1.0f;
|
||||
matrix[1] = 0.0f;
|
||||
matrix[2] = 0.0f;
|
||||
matrix[3] = 0.0f;
|
||||
|
||||
// row 1
|
||||
matrix[4] = 0.0f;
|
||||
matrix[5] = 1.0f;
|
||||
matrix[6] = 0.0f;
|
||||
matrix[7] = 0.0f;
|
||||
|
||||
// row 2
|
||||
matrix[8] = 0.0f;
|
||||
matrix[9] = 0.0f;
|
||||
matrix[10] = 1.0f;
|
||||
matrix[11] = 0.0f;
|
||||
|
||||
// row 3
|
||||
matrix[12] = 0.0f;
|
||||
matrix[13] = 0.0f;
|
||||
matrix[14] = 0.0f;
|
||||
matrix[15] = 1.0f;
|
||||
}
|
||||
|
||||
void mat4x4_rotate(mat4x4_t& matrix, float angle, float x, float y, float z) {
|
||||
float c, s, t;
|
||||
float length, theta;
|
||||
|
||||
// degrees to radians
|
||||
theta = angle * (M_PI / 180.0f);
|
||||
|
||||
// normalize
|
||||
length = sqrtf(x * x + y * y + z * z);
|
||||
|
||||
// too close to 0, can't make normalized vector
|
||||
if (length < 0.0001f) {
|
||||
return;
|
||||
}
|
||||
|
||||
x /= length;
|
||||
y /= length;
|
||||
z /= length;
|
||||
|
||||
c = cosf(theta);
|
||||
s = sinf(theta);
|
||||
t = 1.0f - c;
|
||||
|
||||
// row 0
|
||||
matrix[0] = t * x * x + c;
|
||||
matrix[1] = t * x * y - s * z;
|
||||
matrix[2] = t * x * z + s * y;
|
||||
matrix[3] = 0.0f;
|
||||
|
||||
// row 1
|
||||
matrix[4] = t * y * x + s * z;
|
||||
matrix[5] = t * y * y + c;
|
||||
matrix[6] = t * y * z - s * x;
|
||||
matrix[7] = 0.0f;
|
||||
|
||||
// row 2
|
||||
matrix[8] = t * x * z - s * y;
|
||||
matrix[9] = t * y * z + s * x;
|
||||
matrix[10] = t * z * z + c;
|
||||
matrix[11] = 0.0f;
|
||||
|
||||
// row 3
|
||||
matrix[12] = 0.0f;
|
||||
matrix[13] = 0.0f;
|
||||
matrix[14] = 0.0f;
|
||||
matrix[15] = 1.0f;
|
||||
}
|
||||
|
||||
void mat4x4_ortho(mat4x4_t& matrix,
|
||||
float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float near,
|
||||
float far) {
|
||||
// row 0
|
||||
matrix[0] = 2.0f / (right - left);
|
||||
matrix[1] = 0.0f;
|
||||
matrix[2] = 0.0f;
|
||||
matrix[3] = 0.0f;
|
||||
|
||||
// row 1
|
||||
matrix[4] = 0.0f;
|
||||
matrix[5] = 2.0f / (top - bottom);
|
||||
matrix[6] = 0.0f;
|
||||
matrix[7] = 0.0f;
|
||||
|
||||
// row 2
|
||||
matrix[8] = 0.0f;
|
||||
matrix[9] = 0.0f;
|
||||
matrix[10] = -2.0f / (far - near);
|
||||
matrix[11] = 0.0f;
|
||||
|
||||
// row 3
|
||||
matrix[12] = -(right + left) / (right - left);
|
||||
matrix[13] = -(top + bottom) / (top - bottom);
|
||||
matrix[14] = -(far + near) / (far - near);
|
||||
matrix[15] = 1.0f;
|
||||
}
|
||||
|
||||
void mat4x4_multiply(mat4x4_t& c, const mat4x4_t& a, const mat4x4_t& b) {
|
||||
// row 0
|
||||
c[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8];
|
||||
c[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9];
|
||||
c[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10];
|
||||
c[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3];
|
||||
|
||||
// row 1
|
||||
c[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8];
|
||||
c[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9];
|
||||
c[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10];
|
||||
c[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7];
|
||||
|
||||
// row 2
|
||||
c[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8];
|
||||
c[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9];
|
||||
c[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
|
||||
c[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
|
||||
|
||||
// row 3
|
||||
c[12] = 0.0f;
|
||||
c[13] = 0.0f;
|
||||
c[14] = 0.0f;
|
||||
c[15] = 1.0f;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#endif // USE_SHADERS
|
||||
|
||||
OsrRenderer::OsrRenderer(const OsrRendererSettings& settings)
|
||||
: settings_(settings),
|
||||
initialized_(false),
|
||||
texture_id_(0),
|
||||
view_width_(0),
|
||||
view_height_(0),
|
||||
spin_x_(0),
|
||||
spin_y_(0) {}
|
||||
: settings_(settings)
|
||||
#if USE_SHADERS
|
||||
,
|
||||
line_vertices_(kLineVertices, kLineVertices + std::size(kLineVertices))
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
OsrRenderer::~OsrRenderer() {
|
||||
Cleanup();
|
||||
@ -73,6 +273,133 @@ void OsrRenderer::Initialize() {
|
||||
VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
#if USE_SHADERS
|
||||
glGenVertexArrays(1, &vao_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
glGenBuffers(1, &vbo_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glBindVertexArray(vao_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
glBufferData(GL_ARRAY_BUFFER, line_vertices_.size() * sizeof(float), nullptr,
|
||||
GL_STATIC_DRAW);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
int success;
|
||||
unsigned int vertex_shader_id;
|
||||
unsigned int fragment_shader_id;
|
||||
char infoLog[512];
|
||||
|
||||
// create & compile screen vertex shader program
|
||||
vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);
|
||||
VERIFY_NO_ERROR;
|
||||
glShaderSource(vertex_shader_id, 1, &kScreenVertexShader, NULL);
|
||||
VERIFY_NO_ERROR;
|
||||
glCompileShader(vertex_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
glGetShaderiv(vertex_shader_id, GL_COMPILE_STATUS, &success);
|
||||
VERIFY_NO_ERROR;
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(vertex_shader_id, 512, NULL, infoLog);
|
||||
VERIFY_NO_ERROR;
|
||||
LOG(ERROR) << "Vertex shader compile error: " << infoLog;
|
||||
}
|
||||
|
||||
// create & compile screen fragment shader program
|
||||
fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
VERIFY_NO_ERROR;
|
||||
glShaderSource(fragment_shader_id, 1, &kScreenFragmentShader, NULL);
|
||||
VERIFY_NO_ERROR;
|
||||
glCompileShader(fragment_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
glGetShaderiv(fragment_shader_id, GL_COMPILE_STATUS, &success);
|
||||
VERIFY_NO_ERROR;
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(fragment_shader_id, 512, NULL, infoLog);
|
||||
VERIFY_NO_ERROR;
|
||||
LOG(ERROR) << "Fragment shader compile error: " << infoLog;
|
||||
}
|
||||
|
||||
// create final shader program
|
||||
screen_shader_program_id_ = glCreateProgram();
|
||||
VERIFY_NO_ERROR;
|
||||
glAttachShader(screen_shader_program_id_, vertex_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
glAttachShader(screen_shader_program_id_, fragment_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
glLinkProgram(screen_shader_program_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
glGetProgramiv(screen_shader_program_id_, GL_LINK_STATUS, &success);
|
||||
VERIFY_NO_ERROR;
|
||||
if (!success) {
|
||||
glGetProgramInfoLog(screen_shader_program_id_, 512, NULL, infoLog);
|
||||
VERIFY_NO_ERROR;
|
||||
LOG(ERROR) << "Shader program link error: " << infoLog;
|
||||
}
|
||||
|
||||
// delete the shader's as they're linked into our program now
|
||||
glDeleteShader(vertex_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
glDeleteShader(fragment_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// create & compile update rect vertex shader program
|
||||
vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);
|
||||
VERIFY_NO_ERROR;
|
||||
glShaderSource(vertex_shader_id, 1, &kUpdateRectVertexShader, NULL);
|
||||
VERIFY_NO_ERROR;
|
||||
glCompileShader(vertex_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
glGetShaderiv(vertex_shader_id, GL_COMPILE_STATUS, &success);
|
||||
VERIFY_NO_ERROR;
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(vertex_shader_id, 512, NULL, infoLog);
|
||||
VERIFY_NO_ERROR;
|
||||
LOG(ERROR) << "Vertex shader compile error: " << infoLog;
|
||||
}
|
||||
|
||||
// create & compile update rect fragment shader program
|
||||
fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
VERIFY_NO_ERROR;
|
||||
glShaderSource(fragment_shader_id, 1, &kUpdateRectFragmentShader, NULL);
|
||||
VERIFY_NO_ERROR;
|
||||
glCompileShader(fragment_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
glGetShaderiv(fragment_shader_id, GL_COMPILE_STATUS, &success);
|
||||
VERIFY_NO_ERROR;
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(fragment_shader_id, 512, NULL, infoLog);
|
||||
VERIFY_NO_ERROR;
|
||||
LOG(ERROR) << "Fragment shader compile error: " << infoLog;
|
||||
}
|
||||
|
||||
// create final shader program
|
||||
update_rect_shader_program_id_ = glCreateProgram();
|
||||
VERIFY_NO_ERROR;
|
||||
glAttachShader(update_rect_shader_program_id_, vertex_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
glAttachShader(update_rect_shader_program_id_, fragment_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
glLinkProgram(update_rect_shader_program_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
glGetProgramiv(update_rect_shader_program_id_, GL_LINK_STATUS, &success);
|
||||
VERIFY_NO_ERROR;
|
||||
if (!success) {
|
||||
glGetProgramInfoLog(update_rect_shader_program_id_, 512, NULL, infoLog);
|
||||
VERIFY_NO_ERROR;
|
||||
LOG(ERROR) << "Shader program link error: " << infoLog;
|
||||
}
|
||||
|
||||
// delete the shader's as they're linked into our program now
|
||||
glDeleteShader(vertex_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
glDeleteShader(fragment_shader_id);
|
||||
VERIFY_NO_ERROR;
|
||||
#endif // USE_SHADERS
|
||||
|
||||
// Necessary for non-power-of-2 textures to render correctly.
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
VERIFY_NO_ERROR;
|
||||
@ -89,8 +416,15 @@ void OsrRenderer::Initialize() {
|
||||
VERIFY_NO_ERROR;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
VERIFY_NO_ERROR;
|
||||
#if USE_SHADERS
|
||||
glUseProgram(screen_shader_program_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
glUniform1i(glGetUniformLocation(screen_shader_program_id_, "texture"), 0);
|
||||
VERIFY_NO_ERROR;
|
||||
#else
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
VERIFY_NO_ERROR;
|
||||
#endif
|
||||
|
||||
initialized_ = true;
|
||||
}
|
||||
@ -99,6 +433,17 @@ void OsrRenderer::Cleanup() {
|
||||
if (texture_id_ != 0) {
|
||||
glDeleteTextures(1, &texture_id_);
|
||||
}
|
||||
#if USE_SHADERS
|
||||
if (vao_id_ != 0) {
|
||||
glDeleteVertexArrays(1, &vao_id_);
|
||||
}
|
||||
if (screen_shader_program_id_ != 0) {
|
||||
glDeleteProgram(screen_shader_program_id_);
|
||||
}
|
||||
if (update_rect_shader_program_id_ != 0) {
|
||||
glDeleteProgram(screen_shader_program_id_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OsrRenderer::Render() {
|
||||
@ -108,6 +453,131 @@ void OsrRenderer::Render() {
|
||||
|
||||
DCHECK(initialized_);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
VERIFY_NO_ERROR;
|
||||
// Match GL units to screen coordinates.
|
||||
glViewport(0, 0, view_width_, view_height_);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
#if USE_SHADERS
|
||||
mat4x4_t transformation;
|
||||
mat4x4_t rotX, rotY;
|
||||
|
||||
mat4x4_identity(transformation);
|
||||
mat4x4_identity(rotX);
|
||||
mat4x4_identity(rotY);
|
||||
|
||||
// Rotate the view based on the mouse spin.
|
||||
if (spin_x_ != 0) {
|
||||
mat4x4_rotate(rotX, -spin_x_, 1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
if (spin_y_ != 0) {
|
||||
mat4x4_rotate(rotY, -spin_y_, 0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
mat4x4_multiply(transformation, rotX, rotY);
|
||||
|
||||
if (IsTransparent()) {
|
||||
// Alpha blending style. Texture values have premultiplied alpha.
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// Enable alpha blending.
|
||||
glEnable(GL_BLEND);
|
||||
VERIFY_NO_ERROR;
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
VERIFY_NO_ERROR;
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glUseProgram(screen_shader_program_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
glUniformMatrix4fv(
|
||||
glGetUniformLocation(screen_shader_program_id_, "transform"), 1, GL_FALSE,
|
||||
transformation);
|
||||
VERIFY_NO_ERROR;
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
if (IsTransparent()) {
|
||||
// Disable alpha blending.
|
||||
glDisable(GL_BLEND);
|
||||
VERIFY_NO_ERROR;
|
||||
}
|
||||
// Draw a rectangle around the update region.
|
||||
if (settings_.show_update_rect && !update_rect_.IsEmpty()) {
|
||||
mat4x4_t projection;
|
||||
int left = update_rect_.x;
|
||||
int right = update_rect_.x + update_rect_.width;
|
||||
int top = update_rect_.y;
|
||||
int bottom = update_rect_.y + update_rect_.height;
|
||||
float* vertices = line_vertices_.data();
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// Shrink the box so that top & right sides are drawn.
|
||||
top += 1;
|
||||
right -= 1;
|
||||
#else
|
||||
// Shrink the box so that left & bottom sides are drawn.
|
||||
left += 1;
|
||||
bottom -= 1;
|
||||
#endif
|
||||
|
||||
mat4x4_ortho(projection, 0.0f, view_width_, view_height_, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
// v0
|
||||
vertices[0] = left;
|
||||
vertices[1] = top;
|
||||
|
||||
// v1
|
||||
vertices[5] = right;
|
||||
vertices[6] = top;
|
||||
|
||||
// v2
|
||||
vertices[10] = right;
|
||||
vertices[11] = bottom;
|
||||
|
||||
// v3
|
||||
vertices[15] = left;
|
||||
vertices[16] = bottom;
|
||||
|
||||
// v4
|
||||
vertices[20] = left;
|
||||
vertices[21] = top;
|
||||
|
||||
void* ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||
VERIFY_NO_ERROR;
|
||||
memcpy(ptr, line_vertices_.data(), line_vertices_.size() * sizeof(float));
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glLineWidth(1.0f);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glUseProgram(update_rect_shader_program_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
glUniformMatrix4fv(
|
||||
glGetUniformLocation(update_rect_shader_program_id_, "transform"), 1,
|
||||
GL_FALSE, projection);
|
||||
VERIFY_NO_ERROR;
|
||||
glEnableVertexAttribArray(0);
|
||||
VERIFY_NO_ERROR;
|
||||
glEnableVertexAttribArray(1);
|
||||
VERIFY_NO_ERROR;
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float),
|
||||
(void*)0);
|
||||
VERIFY_NO_ERROR;
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float),
|
||||
(void*)(2 * sizeof(float)));
|
||||
VERIFY_NO_ERROR;
|
||||
glDrawArrays(GL_LINE_LOOP, 0, 5);
|
||||
VERIFY_NO_ERROR;
|
||||
glDisableVertexAttribArray(0);
|
||||
VERIFY_NO_ERROR;
|
||||
glDisableVertexAttribArray(1);
|
||||
VERIFY_NO_ERROR;
|
||||
}
|
||||
#else // !USE_SHADERS
|
||||
struct {
|
||||
float tu, tv;
|
||||
float x, y, z;
|
||||
@ -116,17 +586,11 @@ void OsrRenderer::Render() {
|
||||
{1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
|
||||
{0.0f, 0.0f, -1.0f, 1.0f, 0.0f}};
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
VERIFY_NO_ERROR;
|
||||
glLoadIdentity();
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// Match GL units to screen coordinates.
|
||||
glViewport(0, 0, view_width_, view_height_);
|
||||
VERIFY_NO_ERROR;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
VERIFY_NO_ERROR;
|
||||
glLoadIdentity();
|
||||
@ -239,6 +703,7 @@ void OsrRenderer::Render() {
|
||||
glPopAttrib();
|
||||
VERIFY_NO_ERROR;
|
||||
}
|
||||
#endif // !USE_SHADERS
|
||||
}
|
||||
|
||||
void OsrRenderer::OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) {
|
||||
@ -304,9 +769,11 @@ void OsrRenderer::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
#if !USE_SHADERS
|
||||
// Enable 2D textures.
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
VERIFY_NO_ERROR;
|
||||
#endif
|
||||
|
||||
DCHECK_NE(texture_id_, 0U);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||
@ -389,9 +856,11 @@ void OsrRenderer::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
#if !USE_SHADERS
|
||||
// Disable 2D textures.
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
VERIFY_NO_ERROR;
|
||||
#endif
|
||||
|
||||
if (IsTransparent()) {
|
||||
// Disable alpha blending.
|
||||
|
@ -6,10 +6,22 @@
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_OSR_RENDERER_H_
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "include/cef_browser.h"
|
||||
#include "include/cef_render_handler.h"
|
||||
#include "tests/cefclient/browser/osr_renderer_settings.h"
|
||||
|
||||
// Enable shader-based rendering for Linux only. Windows still uses OpenGL 1.1
|
||||
// to avoid the added complexity of linking newer OpenGL APIs on that platform.
|
||||
// MacOS has deprecated OpenGL and we should eventually provide a Metal-based
|
||||
// implementation on that platform.
|
||||
#if defined(OS_LINUX)
|
||||
#define USE_SHADERS 1
|
||||
#else
|
||||
#define USE_SHADERS 0
|
||||
#endif
|
||||
|
||||
namespace client {
|
||||
|
||||
class OsrRenderer {
|
||||
@ -57,14 +69,21 @@ class OsrRenderer {
|
||||
}
|
||||
|
||||
const OsrRendererSettings settings_;
|
||||
bool initialized_;
|
||||
unsigned int texture_id_;
|
||||
int view_width_;
|
||||
int view_height_;
|
||||
bool initialized_ = false;
|
||||
unsigned int texture_id_ = 0;
|
||||
#if USE_SHADERS
|
||||
unsigned int vao_id_ = 0;
|
||||
unsigned int vbo_id_ = 0;
|
||||
unsigned int screen_shader_program_id_ = 0;
|
||||
unsigned int update_rect_shader_program_id_ = 0;
|
||||
std::vector<float> line_vertices_;
|
||||
#endif
|
||||
int view_width_ = 0;
|
||||
int view_height_ = 0;
|
||||
CefRect popup_rect_;
|
||||
CefRect original_popup_rect_;
|
||||
float spin_x_;
|
||||
float spin_y_;
|
||||
float spin_x_ = 0;
|
||||
float spin_y_ = 0;
|
||||
CefRect update_rect_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(OsrRenderer);
|
||||
|
@ -31,13 +31,11 @@ namespace client {
|
||||
namespace {
|
||||
|
||||
int XErrorHandlerImpl(Display* display, XErrorEvent* event) {
|
||||
LOG(WARNING) << "X error received: "
|
||||
<< "type " << event->type << ", "
|
||||
<< "serial " << event->serial << ", "
|
||||
<< "error_code " << static_cast<int>(event->error_code) << ", "
|
||||
<< "request_code " << static_cast<int>(event->request_code)
|
||||
<< ", "
|
||||
<< "minor_code " << static_cast<int>(event->minor_code);
|
||||
LOG(WARNING) << "X error received: " << "type " << event->type << ", "
|
||||
<< "serial " << event->serial << ", " << "error_code "
|
||||
<< static_cast<int>(event->error_code) << ", " << "request_code "
|
||||
<< static_cast<int>(event->request_code) << ", " << "minor_code "
|
||||
<< static_cast<int>(event->minor_code);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -98,13 +96,6 @@ int RunMain(int argc, char* argv[]) {
|
||||
// Populate the settings based on command line arguments.
|
||||
context->PopulateSettings(&settings);
|
||||
|
||||
if (settings.windowless_rendering_enabled) {
|
||||
// Force the app to use OpenGL <= 3.1 when off-screen rendering is enabled.
|
||||
// TODO(cefclient): Rewrite OSRRenderer to use shaders instead of the
|
||||
// fixed-function pipeline which was removed in OpenGL 3.2 (back in 2009).
|
||||
setenv("MESA_GL_VERSION_OVERRIDE", "3.1", /*overwrite=*/0);
|
||||
}
|
||||
|
||||
// Create the main message loop object.
|
||||
std::unique_ptr<MainMessageLoop> message_loop;
|
||||
if (settings.multi_threaded_message_loop) {
|
||||
|
Loading…
Reference in New Issue
Block a user