diff --git a/tests/cefclient/cefclient_osr_widget_win.cpp b/tests/cefclient/cefclient_osr_widget_win.cpp index e10716ed7..b49b5a91c 100644 --- a/tests/cefclient/cefclient_osr_widget_win.cpp +++ b/tests/cefclient/cefclient_osr_widget_win.cpp @@ -18,14 +18,13 @@ CefRefPtr OSRWindow::Create(OSRBrowserProvider* browser_provider, // static CefRefPtr OSRWindow::From( - CefRefPtr renderHandler) { + CefRefPtr renderHandler) { return static_cast(renderHandler.get()); } bool OSRWindow::CreateWidget(HWND hWndParent, const RECT& rect, HINSTANCE hInst, LPCTSTR className) { ASSERT(hWnd_ == NULL && hDC_ == NULL && hRC_ == NULL); - Reset(); RegisterOSRClass(hInst, className); hWnd_ = ::CreateWindow(className, 0, @@ -37,19 +36,20 @@ bool OSRWindow::CreateWidget(HWND hWndParent, const RECT& rect, return false; SetWindowLongPtr(hWnd_, GWLP_USERDATA, reinterpret_cast(this)); + + // Reference released in OnDestroyed(). AddRef(); - // Enable GL drawing for the window. - EnableGL(); return true; } void OSRWindow::DestroyWidget() { - if (::IsWindow(hWnd_)) { - DisableGL(); + if (IsWindow(hWnd_)) DestroyWindow(hWnd_); - } - Reset(); +} + +void OSRWindow::OnBeforeClose(CefRefPtr browser) { + DisableGL(); } bool OSRWindow::GetRootScreenRect(CefRefPtr browser, @@ -108,6 +108,9 @@ void OSRWindow::OnPaint(CefRefPtr browser, const RectList& dirtyRects, const void* buffer, int width, int height) { + if (!hDC_) + EnableGL(); + wglMakeCurrent(hDC_, hRC_); renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height); renderer_.Render(); @@ -127,8 +130,10 @@ void OSRWindow::OnCursorChange(CefRefPtr browser, OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, bool transparent) : renderer_(transparent), - browser_provider_(browser_provider) { - Reset(); + browser_provider_(browser_provider), + hWnd_(NULL), + hDC_(NULL), + hRC_(NULL) { } OSRWindow::~OSRWindow() { @@ -136,6 +141,8 @@ OSRWindow::~OSRWindow() { } void OSRWindow::EnableGL() { + ASSERT(CefCurrentlyOn(TID_UI)); + PIXELFORMATDESCRIPTOR pfd; int format; @@ -162,18 +169,29 @@ void OSRWindow::EnableGL() { } void OSRWindow::DisableGL() { - renderer_.Cleanup(); - wglMakeCurrent(NULL, NULL); - wglDeleteContext(hRC_); - ReleaseDC(hWnd_, hDC_); -} + ASSERT(CefCurrentlyOn(TID_UI)); + + if (!hDC_) + return; + + renderer_.Cleanup(); + + if (IsWindow(hWnd_)) { + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hRC_); + ReleaseDC(hWnd_, hDC_); + } -void OSRWindow::Reset() { - hWnd_ = NULL; hDC_ = NULL; hRC_ = NULL; } +void OSRWindow::OnDestroyed() { + SetWindowLongPtr(hWnd_, GWLP_USERDATA, 0L); + hWnd_ = NULL; + Release(); +} + ATOM OSRWindow::RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className) { WNDCLASSEX wcex; @@ -208,10 +226,8 @@ LRESULT CALLBACK OSRWindow::WndProc(HWND hWnd, UINT message, switch (message) { case WM_DESTROY: - if (window) { - SetWindowLongPtr(hWnd, GWLP_USERDATA, 0L); - window->Release(); - } + if (window) + window->OnDestroyed(); return 0; case WM_LBUTTONDOWN: diff --git a/tests/cefclient/cefclient_osr_widget_win.h b/tests/cefclient/cefclient_osr_widget_win.h index 654576a47..99d7a2678 100644 --- a/tests/cefclient/cefclient_osr_widget_win.h +++ b/tests/cefclient/cefclient_osr_widget_win.h @@ -7,6 +7,7 @@ #pragma once #include "include/cef_render_handler.h" +#include "tests/cefclient/client_handler.h" #include "tests/cefclient/osrenderer.h" class OSRBrowserProvider { @@ -17,14 +18,15 @@ class OSRBrowserProvider { virtual ~OSRBrowserProvider() {} }; -class OSRWindow : public CefRenderHandler { +class OSRWindow : public ClientHandler::RenderHandler { public: // Create a new OSRWindow instance. |browser_provider| must outlive this // object. static CefRefPtr Create(OSRBrowserProvider* browser_provider, bool transparent); - static CefRefPtr From(CefRefPtr renderHandler); + static CefRefPtr From( + CefRefPtr renderHandler); // Create the underlying window. bool CreateWidget(HWND hWndParent, const RECT& rect, @@ -37,6 +39,9 @@ class OSRWindow : public CefRenderHandler { return hWnd_; } + // ClientHandler::RenderHandler methods + virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; + // CefRenderHandler methods virtual bool GetRootScreenRect(CefRefPtr browser, CefRect& rect) OVERRIDE; @@ -66,7 +71,7 @@ class OSRWindow : public CefRenderHandler { void EnableGL(); void DisableGL(); - void Reset(); + void OnDestroyed(); static ATOM RegisterOSRClass(HINSTANCE hInstance, LPCTSTR className); static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); diff --git a/tests/cefclient/cefclient_win.cpp b/tests/cefclient/cefclient_win.cpp index b697a43b5..ae4f82664 100644 --- a/tests/cefclient/cefclient_win.cpp +++ b/tests/cefclient/cefclient_win.cpp @@ -545,12 +545,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, break; 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); return 0; } diff --git a/tests/cefclient/client_handler.cpp b/tests/cefclient/client_handler.cpp index 8bd848bfe..3a4c426cb 100644 --- a/tests/cefclient/client_handler.cpp +++ b/tests/cefclient/client_handler.cpp @@ -281,6 +281,11 @@ void ClientHandler::OnBeforeClose(CefRefPtr browser) { if (m_BrowserId == browser->GetIdentifier()) { // Free the browser pointer so that the browser can be destroyed m_Browser = NULL; + + if (m_OSRHandler.get()) { + m_OSRHandler->OnBeforeClose(browser); + m_OSRHandler = NULL; + } } else if (browser->IsPopup()) { // Remove the record for DevTools popup windows. std::set::iterator it = diff --git a/tests/cefclient/client_handler.h b/tests/cefclient/client_handler.h index f702360b9..4f048bc3a 100644 --- a/tests/cefclient/client_handler.h +++ b/tests/cefclient/client_handler.h @@ -64,6 +64,12 @@ class ClientHandler : public CefClient, } }; + // Interface implemented to handle off-screen rendering. + class RenderHandler : public CefRenderHandler { + public: + virtual void OnBeforeClose(CefRefPtr browser) =0; + }; + typedef std::set > RequestDelegateSet; ClientHandler(); @@ -216,10 +222,10 @@ class ClientHandler : public CefClient, void SetMainHwnd(CefWindowHandle hwnd); CefWindowHandle GetMainHwnd() { return m_MainHwnd; } void SetEditHwnd(CefWindowHandle hwnd); - void SetOSRHandler(CefRefPtr handler) { + void SetOSRHandler(CefRefPtr handler) { m_OSRHandler = handler; } - CefRefPtr GetOSRHandler() { return m_OSRHandler; } + CefRefPtr GetOSRHandler() { return m_OSRHandler; } void SetButtonHwnds(CefWindowHandle backHwnd, CefWindowHandle forwardHwnd, CefWindowHandle reloadHwnd, @@ -298,7 +304,7 @@ class ClientHandler : public CefClient, CefWindowHandle m_StopHwnd; CefWindowHandle m_ReloadHwnd; - CefRefPtr m_OSRHandler; + CefRefPtr m_OSRHandler; // Support for logging. std::string m_LogFile;