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
|