mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-01 03:47:05 +01:00
260dd0ca24
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`
196 lines
5.0 KiB
C++
196 lines
5.0 KiB
C++
// Copyright 2018 The Chromium Embedded Framework 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 "tests/cefclient/browser/osr_render_handler_win_gl.h"
|
|
|
|
#include "include/base/cef_callback.h"
|
|
#include "include/wrapper/cef_closure_task.h"
|
|
#include "include/wrapper/cef_helpers.h"
|
|
#include "tests/shared/browser/util_win.h"
|
|
|
|
namespace client {
|
|
|
|
namespace {
|
|
|
|
// Helper that calls wglMakeCurrent.
|
|
class ScopedGLContext {
|
|
public:
|
|
ScopedGLContext(HDC hdc, HGLRC hglrc, bool swap_buffers)
|
|
: hdc_(hdc), swap_buffers_(swap_buffers) {
|
|
[[maybe_unused]] BOOL result = wglMakeCurrent(hdc, hglrc);
|
|
DCHECK(result);
|
|
}
|
|
~ScopedGLContext() {
|
|
BOOL result = wglMakeCurrent(nullptr, nullptr);
|
|
DCHECK(result);
|
|
if (swap_buffers_) {
|
|
result = SwapBuffers(hdc_);
|
|
DCHECK(result);
|
|
}
|
|
}
|
|
|
|
private:
|
|
const HDC hdc_;
|
|
const bool swap_buffers_;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
OsrRenderHandlerWinGL::OsrRenderHandlerWinGL(
|
|
const OsrRendererSettings& settings,
|
|
HWND hwnd)
|
|
: OsrRenderHandlerWin(settings, hwnd), renderer_(settings) {}
|
|
|
|
void OsrRenderHandlerWinGL::Initialize(CefRefPtr<CefBrowser> browser) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
SetBrowser(browser);
|
|
}
|
|
|
|
OsrRenderHandlerWinGL::~OsrRenderHandlerWinGL() {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
DisableGL();
|
|
}
|
|
|
|
void OsrRenderHandlerWinGL::SetSpin(float spinX, float spinY) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
renderer_.SetSpin(spinX, spinY);
|
|
Invalidate();
|
|
}
|
|
|
|
void OsrRenderHandlerWinGL::IncrementSpin(float spinDX, float spinDY) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
renderer_.IncrementSpin(spinDX, spinDY);
|
|
Invalidate();
|
|
}
|
|
|
|
bool OsrRenderHandlerWinGL::IsOverPopupWidget(int x, int y) const {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
const CefRect& rc = renderer_.popup_rect();
|
|
int popup_right = rc.x + rc.width;
|
|
int popup_bottom = rc.y + rc.height;
|
|
return (x >= rc.x) && (x < popup_right) && (y >= rc.y) && (y < popup_bottom);
|
|
}
|
|
|
|
int OsrRenderHandlerWinGL::GetPopupXOffset() const {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
return renderer_.original_popup_rect().x - renderer_.popup_rect().x;
|
|
}
|
|
|
|
int OsrRenderHandlerWinGL::GetPopupYOffset() const {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
return renderer_.original_popup_rect().y - renderer_.popup_rect().y;
|
|
}
|
|
|
|
void OsrRenderHandlerWinGL::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
|
bool show) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
|
|
if (!show) {
|
|
renderer_.ClearPopupRects();
|
|
browser->GetHost()->Invalidate(PET_VIEW);
|
|
}
|
|
|
|
renderer_.OnPopupShow(browser, show);
|
|
}
|
|
|
|
void OsrRenderHandlerWinGL::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
|
const CefRect& rect) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
renderer_.OnPopupSize(browser, rect);
|
|
}
|
|
|
|
void OsrRenderHandlerWinGL::OnPaint(
|
|
CefRefPtr<CefBrowser> browser,
|
|
CefRenderHandler::PaintElementType type,
|
|
const CefRenderHandler::RectList& dirtyRects,
|
|
const void* buffer,
|
|
int width,
|
|
int height) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
|
|
if (painting_popup_) {
|
|
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
|
|
return;
|
|
}
|
|
if (!hdc_) {
|
|
EnableGL();
|
|
}
|
|
|
|
ScopedGLContext scoped_gl_context(hdc_, hrc_, true);
|
|
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
|
|
if (type == PET_VIEW && !renderer_.popup_rect().IsEmpty()) {
|
|
painting_popup_ = true;
|
|
browser->GetHost()->Invalidate(PET_POPUP);
|
|
painting_popup_ = false;
|
|
}
|
|
renderer_.Render();
|
|
}
|
|
|
|
void OsrRenderHandlerWinGL::OnAcceleratedPaint(
|
|
CefRefPtr<CefBrowser> browser,
|
|
CefRenderHandler::PaintElementType type,
|
|
const CefRenderHandler::RectList& dirtyRects,
|
|
const CefAcceleratedPaintInfo& info) {
|
|
// Not used with this implementation.
|
|
NOTREACHED();
|
|
}
|
|
|
|
void OsrRenderHandlerWinGL::Render() {
|
|
if (!hdc_) {
|
|
EnableGL();
|
|
}
|
|
|
|
ScopedGLContext scoped_gl_context(hdc_, hrc_, true);
|
|
renderer_.Render();
|
|
}
|
|
|
|
void OsrRenderHandlerWinGL::EnableGL() {
|
|
PIXELFORMATDESCRIPTOR pfd;
|
|
int format;
|
|
|
|
// Get the device context.
|
|
hdc_ = GetDC(hwnd());
|
|
|
|
// Set the pixel format for the DC.
|
|
ZeroMemory(&pfd, sizeof(pfd));
|
|
pfd.nSize = sizeof(pfd);
|
|
pfd.nVersion = 1;
|
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
|
pfd.cColorBits = 24;
|
|
pfd.cDepthBits = 16;
|
|
pfd.iLayerType = PFD_MAIN_PLANE;
|
|
format = ChoosePixelFormat(hdc_, &pfd);
|
|
SetPixelFormat(hdc_, format, &pfd);
|
|
|
|
// Create and enable the render context.
|
|
hrc_ = wglCreateContext(hdc_);
|
|
|
|
ScopedGLContext scoped_gl_context(hdc_, hrc_, false);
|
|
renderer_.Initialize();
|
|
}
|
|
|
|
void OsrRenderHandlerWinGL::DisableGL() {
|
|
if (!hdc_) {
|
|
return;
|
|
}
|
|
|
|
{
|
|
ScopedGLContext scoped_gl_context(hdc_, hrc_, false);
|
|
renderer_.Cleanup();
|
|
}
|
|
|
|
if (IsWindow(hwnd())) {
|
|
// wglDeleteContext will make the context not current before deleting it.
|
|
[[maybe_unused]] BOOL result = wglDeleteContext(hrc_);
|
|
DCHECK(result);
|
|
ReleaseDC(hwnd(), hdc_);
|
|
}
|
|
|
|
hdc_ = nullptr;
|
|
hrc_ = nullptr;
|
|
}
|
|
|
|
} // namespace client
|