Make off-screen rendering example work with multi-threaded message loop mode (issue #804).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@938 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt
2012-12-04 01:16:13 +00:00
parent c3bbaac18f
commit 2a17f00844
5 changed files with 59 additions and 33 deletions

View File

@ -18,14 +18,13 @@ CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
// static // static
CefRefPtr<OSRWindow> OSRWindow::From( CefRefPtr<OSRWindow> OSRWindow::From(
CefRefPtr<CefRenderHandler> renderHandler) { CefRefPtr<ClientHandler::RenderHandler> renderHandler) {
return static_cast<OSRWindow*>(renderHandler.get()); return static_cast<OSRWindow*>(renderHandler.get());
} }
bool OSRWindow::CreateWidget(HWND hWndParent, const RECT& rect, bool OSRWindow::CreateWidget(HWND hWndParent, const RECT& rect,
HINSTANCE hInst, LPCTSTR className) { HINSTANCE hInst, LPCTSTR className) {
ASSERT(hWnd_ == NULL && hDC_ == NULL && hRC_ == NULL); ASSERT(hWnd_ == NULL && hDC_ == NULL && hRC_ == NULL);
Reset();
RegisterOSRClass(hInst, className); RegisterOSRClass(hInst, className);
hWnd_ = ::CreateWindow(className, 0, hWnd_ = ::CreateWindow(className, 0,
@ -37,19 +36,20 @@ bool OSRWindow::CreateWidget(HWND hWndParent, const RECT& rect,
return false; return false;
SetWindowLongPtr(hWnd_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); SetWindowLongPtr(hWnd_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
// Reference released in OnDestroyed().
AddRef(); AddRef();
// Enable GL drawing for the window.
EnableGL();
return true; return true;
} }
void OSRWindow::DestroyWidget() { void OSRWindow::DestroyWidget() {
if (::IsWindow(hWnd_)) { if (IsWindow(hWnd_))
DisableGL();
DestroyWindow(hWnd_); DestroyWindow(hWnd_);
} }
Reset();
void OSRWindow::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
DisableGL();
} }
bool OSRWindow::GetRootScreenRect(CefRefPtr<CefBrowser> browser, bool OSRWindow::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
@ -108,6 +108,9 @@ void OSRWindow::OnPaint(CefRefPtr<CefBrowser> browser,
const RectList& dirtyRects, const RectList& dirtyRects,
const void* buffer, const void* buffer,
int width, int height) { int width, int height) {
if (!hDC_)
EnableGL();
wglMakeCurrent(hDC_, hRC_); wglMakeCurrent(hDC_, hRC_);
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height); renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
renderer_.Render(); renderer_.Render();
@ -127,8 +130,10 @@ void OSRWindow::OnCursorChange(CefRefPtr<CefBrowser> browser,
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, bool transparent) OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, bool transparent)
: renderer_(transparent), : renderer_(transparent),
browser_provider_(browser_provider) { browser_provider_(browser_provider),
Reset(); hWnd_(NULL),
hDC_(NULL),
hRC_(NULL) {
} }
OSRWindow::~OSRWindow() { OSRWindow::~OSRWindow() {
@ -136,6 +141,8 @@ OSRWindow::~OSRWindow() {
} }
void OSRWindow::EnableGL() { void OSRWindow::EnableGL() {
ASSERT(CefCurrentlyOn(TID_UI));
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
int format; int format;
@ -162,18 +169,29 @@ void OSRWindow::EnableGL() {
} }
void OSRWindow::DisableGL() { void OSRWindow::DisableGL() {
renderer_.Cleanup(); ASSERT(CefCurrentlyOn(TID_UI));
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC_); if (!hDC_)
ReleaseDC(hWnd_, hDC_); return;
}
renderer_.Cleanup();
if (IsWindow(hWnd_)) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC_);
ReleaseDC(hWnd_, hDC_);
}
void OSRWindow::Reset() {
hWnd_ = NULL;
hDC_ = NULL; hDC_ = NULL;
hRC_ = NULL; hRC_ = NULL;
} }
void OSRWindow::OnDestroyed() {
SetWindowLongPtr(hWnd_, GWLP_USERDATA, 0L);
hWnd_ = NULL;
Release();
}
ATOM OSRWindow::RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className) { ATOM OSRWindow::RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className) {
WNDCLASSEX wcex; WNDCLASSEX wcex;
@ -208,10 +226,8 @@ LRESULT CALLBACK OSRWindow::WndProc(HWND hWnd, UINT message,
switch (message) { switch (message) {
case WM_DESTROY: case WM_DESTROY:
if (window) { if (window)
SetWindowLongPtr(hWnd, GWLP_USERDATA, 0L); window->OnDestroyed();
window->Release();
}
return 0; return 0;
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:

View File

@ -7,6 +7,7 @@
#pragma once #pragma once
#include "include/cef_render_handler.h" #include "include/cef_render_handler.h"
#include "tests/cefclient/client_handler.h"
#include "tests/cefclient/osrenderer.h" #include "tests/cefclient/osrenderer.h"
class OSRBrowserProvider { class OSRBrowserProvider {
@ -17,14 +18,15 @@ class OSRBrowserProvider {
virtual ~OSRBrowserProvider() {} virtual ~OSRBrowserProvider() {}
}; };
class OSRWindow : public CefRenderHandler { class OSRWindow : public ClientHandler::RenderHandler {
public: public:
// Create a new OSRWindow instance. |browser_provider| must outlive this // Create a new OSRWindow instance. |browser_provider| must outlive this
// object. // object.
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider, static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
bool transparent); bool transparent);
static CefRefPtr<OSRWindow> From(CefRefPtr<CefRenderHandler> renderHandler); static CefRefPtr<OSRWindow> From(
CefRefPtr<ClientHandler::RenderHandler> renderHandler);
// Create the underlying window. // Create the underlying window.
bool CreateWidget(HWND hWndParent, const RECT& rect, bool CreateWidget(HWND hWndParent, const RECT& rect,
@ -37,6 +39,9 @@ class OSRWindow : public CefRenderHandler {
return hWnd_; return hWnd_;
} }
// ClientHandler::RenderHandler methods
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefRenderHandler methods // CefRenderHandler methods
virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser, virtual bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE; CefRect& rect) OVERRIDE;
@ -66,7 +71,7 @@ class OSRWindow : public CefRenderHandler {
void EnableGL(); void EnableGL();
void DisableGL(); void DisableGL();
void Reset(); void OnDestroyed();
static ATOM RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className); static ATOM RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam); LPARAM lParam);

View File

@ -545,12 +545,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
break; break;
case WM_DESTROY: case WM_DESTROY:
// The frame window has exited
if (g_handler->GetOSRHandler().get()) {
OSRWindow::From(g_handler->GetOSRHandler())->DestroyWidget();
g_handler->SetOSRHandler(NULL);
}
PostQuitMessage(0); PostQuitMessage(0);
return 0; return 0;
} }

View File

@ -281,6 +281,11 @@ void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
if (m_BrowserId == browser->GetIdentifier()) { if (m_BrowserId == browser->GetIdentifier()) {
// Free the browser pointer so that the browser can be destroyed // Free the browser pointer so that the browser can be destroyed
m_Browser = NULL; m_Browser = NULL;
if (m_OSRHandler.get()) {
m_OSRHandler->OnBeforeClose(browser);
m_OSRHandler = NULL;
}
} else if (browser->IsPopup()) { } else if (browser->IsPopup()) {
// Remove the record for DevTools popup windows. // Remove the record for DevTools popup windows.
std::set<std::string>::iterator it = std::set<std::string>::iterator it =

View File

@ -64,6 +64,12 @@ class ClientHandler : public CefClient,
} }
}; };
// Interface implemented to handle off-screen rendering.
class RenderHandler : public CefRenderHandler {
public:
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) =0;
};
typedef std::set<CefRefPtr<RequestDelegate> > RequestDelegateSet; typedef std::set<CefRefPtr<RequestDelegate> > RequestDelegateSet;
ClientHandler(); ClientHandler();
@ -216,10 +222,10 @@ class ClientHandler : public CefClient,
void SetMainHwnd(CefWindowHandle hwnd); void SetMainHwnd(CefWindowHandle hwnd);
CefWindowHandle GetMainHwnd() { return m_MainHwnd; } CefWindowHandle GetMainHwnd() { return m_MainHwnd; }
void SetEditHwnd(CefWindowHandle hwnd); void SetEditHwnd(CefWindowHandle hwnd);
void SetOSRHandler(CefRefPtr<CefRenderHandler> handler) { void SetOSRHandler(CefRefPtr<RenderHandler> handler) {
m_OSRHandler = handler; m_OSRHandler = handler;
} }
CefRefPtr<CefRenderHandler> GetOSRHandler() { return m_OSRHandler; } CefRefPtr<RenderHandler> GetOSRHandler() { return m_OSRHandler; }
void SetButtonHwnds(CefWindowHandle backHwnd, void SetButtonHwnds(CefWindowHandle backHwnd,
CefWindowHandle forwardHwnd, CefWindowHandle forwardHwnd,
CefWindowHandle reloadHwnd, CefWindowHandle reloadHwnd,
@ -298,7 +304,7 @@ class ClientHandler : public CefClient,
CefWindowHandle m_StopHwnd; CefWindowHandle m_StopHwnd;
CefWindowHandle m_ReloadHwnd; CefWindowHandle m_ReloadHwnd;
CefRefPtr<CefRenderHandler> m_OSRHandler; CefRefPtr<RenderHandler> m_OSRHandler;
// Support for logging. // Support for logging.
std::string m_LogFile; std::string m_LogFile;