mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Adds support for the OnAcceleratedPaint callback. Verified to work on macOS and Windows. Linux support is present but not implemented for cefclient, so it is not verified to work. To test: Run `cefclient --off-screen-rendering-enabled --shared-texture-enabled`
This commit is contained in:
committed by
Marshall Greenblatt
parent
dca0435d2f
commit
260dd0ca24
@@ -4,6 +4,12 @@
|
||||
|
||||
#include "tests/cefclient/browser/osr_renderer.h"
|
||||
|
||||
#if !defined(OS_WIN)
|
||||
// Begin disable NSOpenGL deprecation warnings.
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
#if USE_SHADERS
|
||||
// Expose prototypes for OpenGL shader functions.
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
@@ -14,7 +20,6 @@
|
||||
#if defined(OS_WIN)
|
||||
#include <gl/gl.h>
|
||||
#elif defined(OS_MAC)
|
||||
#define GL_SILENCE_DEPRECATION
|
||||
#if USE_SHADERS
|
||||
#include <OpenGL/gl3.h>
|
||||
#else
|
||||
@@ -755,6 +760,210 @@ void OsrRenderer::ClearPopupRects() {
|
||||
original_popup_rect_.Set(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void OsrRenderer::OnAcceleratedPaint(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::PaintElementType type,
|
||||
const CefRenderHandler::RectList& dirtyRects,
|
||||
unsigned int io_surface_tex,
|
||||
int width,
|
||||
int height) {
|
||||
if (!initialized_) {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
#if !defined(OS_WIN)
|
||||
if (width != view_width_ || height != view_height_) {
|
||||
// Width or height has changed, so proceed to update the texture
|
||||
view_width_ = width;
|
||||
view_height_ = height;
|
||||
|
||||
// Rebind texture_id as the active texture
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// Allocate a new storage for texture_id with the new dimensions
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA,
|
||||
GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
if (IsTransparent()) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// Enable alpha blending.
|
||||
glEnable(GL_BLEND);
|
||||
VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
GLuint framebuffer;
|
||||
glGenFramebuffers(1, &framebuffer);
|
||||
VERIFY_NO_ERROR;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
VERIFY_NO_ERROR;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
texture_id_, 0);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// Check framebuffer status
|
||||
DCHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
|
||||
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
VERIFY_NO_ERROR;
|
||||
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// Setup OpenGL states
|
||||
glViewport(0, 0, width, height);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// Bind the GL_TEXTURE_RECTANGLE_ARB texture
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
VERIFY_NO_ERROR;
|
||||
glPushMatrix();
|
||||
VERIFY_NO_ERROR;
|
||||
glLoadIdentity();
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
VERIFY_NO_ERROR;
|
||||
glPushMatrix();
|
||||
VERIFY_NO_ERROR;
|
||||
glLoadIdentity();
|
||||
VERIFY_NO_ERROR;
|
||||
glOrtho(0, width, 0, height, -1, 1);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
VERIFY_NO_ERROR;
|
||||
glPushMatrix();
|
||||
VERIFY_NO_ERROR;
|
||||
glLoadIdentity();
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// rectangleTexture is the GL_TEXTURE_RECTANGLE_ARB
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, io_surface_tex);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
VERIFY_NO_ERROR;
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
bool isFlipped = false;
|
||||
|
||||
GLfloat tex_coords[8];
|
||||
|
||||
GLfloat texOriginX = 0;
|
||||
GLfloat texOriginY = 0;
|
||||
GLfloat texExtentX = width;
|
||||
GLfloat texExtentY = height;
|
||||
|
||||
// X
|
||||
tex_coords[0] = texOriginX;
|
||||
tex_coords[2] = texOriginX;
|
||||
tex_coords[4] = texExtentX;
|
||||
tex_coords[6] = texExtentX;
|
||||
|
||||
// Y
|
||||
if (!isFlipped) {
|
||||
tex_coords[1] = texOriginY;
|
||||
tex_coords[3] = texExtentY;
|
||||
tex_coords[5] = texExtentY;
|
||||
tex_coords[7] = texOriginY;
|
||||
} else {
|
||||
tex_coords[1] = texExtentY;
|
||||
tex_coords[3] = texOriginY;
|
||||
tex_coords[5] = texOriginY;
|
||||
tex_coords[7] = texExtentY;
|
||||
}
|
||||
|
||||
GLfloat verts[] = {
|
||||
0.0f, 0.0f, 0.0f, (float)height,
|
||||
(float)width, (float)height, (float)width, 0.0f,
|
||||
};
|
||||
|
||||
// Ought to cache the GL_ARRAY_BUFFER_BINDING,
|
||||
// GL_ELEMENT_ARRAY_BUFFER_BINDING, set buffer to 0, and reset
|
||||
GLint arrayBuffer, elementArrayBuffer;
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elementArrayBuffer);
|
||||
VERIFY_NO_ERROR;
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &arrayBuffer);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
VERIFY_NO_ERROR;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
VERIFY_NO_ERROR;
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, tex_coords);
|
||||
VERIFY_NO_ERROR;
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
VERIFY_NO_ERROR;
|
||||
glVertexPointer(2, GL_FLOAT, 0, verts);
|
||||
VERIFY_NO_ERROR;
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
|
||||
VERIFY_NO_ERROR;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// Restore OpenGL states
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
VERIFY_NO_ERROR;
|
||||
glPopMatrix();
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
VERIFY_NO_ERROR;
|
||||
glPopMatrix();
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
VERIFY_NO_ERROR;
|
||||
glPopMatrix();
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glPopClientAttrib();
|
||||
VERIFY_NO_ERROR;
|
||||
glPopAttrib();
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
if (IsTransparent()) {
|
||||
// Enable alpha blending.
|
||||
glDisable(GL_BLEND);
|
||||
VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
// 0 unbinds the FBO, reverting to the default buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glDeleteFramebuffers(1, &framebuffer);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
// Delete the rectangle texture
|
||||
glDeleteTextures(1, &io_surface_tex);
|
||||
VERIFY_NO_ERROR;
|
||||
|
||||
glDisable(GL_TEXTURE_RECTANGLE_ARB);
|
||||
VERIFY_NO_ERROR;
|
||||
#endif // !defined(OS_WIN)
|
||||
}
|
||||
|
||||
void OsrRenderer::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::PaintElementType type,
|
||||
const CefRenderHandler::RectList& dirtyRects,
|
||||
@@ -882,3 +1091,8 @@ void OsrRenderer::IncrementSpin(float spinDX, float spinDY) {
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
||||
#if !defined(OS_WIN)
|
||||
// End disable NSOpenGL deprecation warnings.
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user