• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #include "tests/cefclient/browser/osr_render_handler_win_gl.h"
6 
7 #include "include/base/cef_callback.h"
8 #include "include/wrapper/cef_closure_task.h"
9 #include "include/wrapper/cef_helpers.h"
10 #include "tests/shared/browser/util_win.h"
11 
12 namespace client {
13 
14 namespace {
15 
16 // Helper that calls wglMakeCurrent.
17 class ScopedGLContext {
18  public:
ScopedGLContext(HDC hdc,HGLRC hglrc,bool swap_buffers)19   ScopedGLContext(HDC hdc, HGLRC hglrc, bool swap_buffers)
20       : hdc_(hdc), swap_buffers_(swap_buffers) {
21     BOOL result = wglMakeCurrent(hdc, hglrc);
22     ALLOW_UNUSED_LOCAL(result);
23     DCHECK(result);
24   }
~ScopedGLContext()25   ~ScopedGLContext() {
26     BOOL result = wglMakeCurrent(nullptr, nullptr);
27     DCHECK(result);
28     if (swap_buffers_) {
29       result = SwapBuffers(hdc_);
30       DCHECK(result);
31     }
32   }
33 
34  private:
35   const HDC hdc_;
36   const bool swap_buffers_;
37 };
38 
39 }  // namespace
40 
OsrRenderHandlerWinGL(const OsrRendererSettings & settings,HWND hwnd)41 OsrRenderHandlerWinGL::OsrRenderHandlerWinGL(
42     const OsrRendererSettings& settings,
43     HWND hwnd)
44     : OsrRenderHandlerWin(settings, hwnd),
45       renderer_(settings),
46       hdc_(nullptr),
47       hrc_(nullptr),
48       painting_popup_(false) {}
49 
Initialize(CefRefPtr<CefBrowser> browser)50 void OsrRenderHandlerWinGL::Initialize(CefRefPtr<CefBrowser> browser) {
51   CEF_REQUIRE_UI_THREAD();
52   SetBrowser(browser);
53 }
54 
~OsrRenderHandlerWinGL()55 OsrRenderHandlerWinGL::~OsrRenderHandlerWinGL() {
56   CEF_REQUIRE_UI_THREAD();
57   DisableGL();
58 }
59 
SetSpin(float spinX,float spinY)60 void OsrRenderHandlerWinGL::SetSpin(float spinX, float spinY) {
61   CEF_REQUIRE_UI_THREAD();
62   renderer_.SetSpin(spinX, spinY);
63   Invalidate();
64 }
65 
IncrementSpin(float spinDX,float spinDY)66 void OsrRenderHandlerWinGL::IncrementSpin(float spinDX, float spinDY) {
67   CEF_REQUIRE_UI_THREAD();
68   renderer_.IncrementSpin(spinDX, spinDY);
69   Invalidate();
70 }
71 
IsOverPopupWidget(int x,int y) const72 bool OsrRenderHandlerWinGL::IsOverPopupWidget(int x, int y) const {
73   CEF_REQUIRE_UI_THREAD();
74   const CefRect& rc = renderer_.popup_rect();
75   int popup_right = rc.x + rc.width;
76   int popup_bottom = rc.y + rc.height;
77   return (x >= rc.x) && (x < popup_right) && (y >= rc.y) && (y < popup_bottom);
78 }
79 
GetPopupXOffset() const80 int OsrRenderHandlerWinGL::GetPopupXOffset() const {
81   CEF_REQUIRE_UI_THREAD();
82   return renderer_.original_popup_rect().x - renderer_.popup_rect().x;
83 }
84 
GetPopupYOffset() const85 int OsrRenderHandlerWinGL::GetPopupYOffset() const {
86   CEF_REQUIRE_UI_THREAD();
87   return renderer_.original_popup_rect().y - renderer_.popup_rect().y;
88 }
89 
OnPopupShow(CefRefPtr<CefBrowser> browser,bool show)90 void OsrRenderHandlerWinGL::OnPopupShow(CefRefPtr<CefBrowser> browser,
91                                         bool show) {
92   CEF_REQUIRE_UI_THREAD();
93 
94   if (!show) {
95     renderer_.ClearPopupRects();
96     browser->GetHost()->Invalidate(PET_VIEW);
97   }
98 
99   renderer_.OnPopupShow(browser, show);
100 }
101 
OnPopupSize(CefRefPtr<CefBrowser> browser,const CefRect & rect)102 void OsrRenderHandlerWinGL::OnPopupSize(CefRefPtr<CefBrowser> browser,
103                                         const CefRect& rect) {
104   CEF_REQUIRE_UI_THREAD();
105   renderer_.OnPopupSize(browser, rect);
106 }
107 
OnPaint(CefRefPtr<CefBrowser> browser,CefRenderHandler::PaintElementType type,const CefRenderHandler::RectList & dirtyRects,const void * buffer,int width,int height)108 void OsrRenderHandlerWinGL::OnPaint(
109     CefRefPtr<CefBrowser> browser,
110     CefRenderHandler::PaintElementType type,
111     const CefRenderHandler::RectList& dirtyRects,
112     const void* buffer,
113     int width,
114     int height) {
115   CEF_REQUIRE_UI_THREAD();
116 
117   if (painting_popup_) {
118     renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
119     return;
120   }
121   if (!hdc_) {
122     EnableGL();
123   }
124 
125   ScopedGLContext scoped_gl_context(hdc_, hrc_, true);
126   renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
127   if (type == PET_VIEW && !renderer_.popup_rect().IsEmpty()) {
128     painting_popup_ = true;
129     browser->GetHost()->Invalidate(PET_POPUP);
130     painting_popup_ = false;
131   }
132   renderer_.Render();
133 }
134 
OnAcceleratedPaint(CefRefPtr<CefBrowser> browser,CefRenderHandler::PaintElementType type,const CefRenderHandler::RectList & dirtyRects,void * share_handle)135 void OsrRenderHandlerWinGL::OnAcceleratedPaint(
136     CefRefPtr<CefBrowser> browser,
137     CefRenderHandler::PaintElementType type,
138     const CefRenderHandler::RectList& dirtyRects,
139     void* share_handle) {
140   // Not used with this implementation.
141   NOTREACHED();
142 }
143 
Render()144 void OsrRenderHandlerWinGL::Render() {
145   if (!hdc_) {
146     EnableGL();
147   }
148 
149   ScopedGLContext scoped_gl_context(hdc_, hrc_, true);
150   renderer_.Render();
151 }
152 
EnableGL()153 void OsrRenderHandlerWinGL::EnableGL() {
154   PIXELFORMATDESCRIPTOR pfd;
155   int format;
156 
157   // Get the device context.
158   hdc_ = GetDC(hwnd());
159 
160   // Set the pixel format for the DC.
161   ZeroMemory(&pfd, sizeof(pfd));
162   pfd.nSize = sizeof(pfd);
163   pfd.nVersion = 1;
164   pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
165   pfd.iPixelType = PFD_TYPE_RGBA;
166   pfd.cColorBits = 24;
167   pfd.cDepthBits = 16;
168   pfd.iLayerType = PFD_MAIN_PLANE;
169   format = ChoosePixelFormat(hdc_, &pfd);
170   SetPixelFormat(hdc_, format, &pfd);
171 
172   // Create and enable the render context.
173   hrc_ = wglCreateContext(hdc_);
174 
175   ScopedGLContext scoped_gl_context(hdc_, hrc_, false);
176   renderer_.Initialize();
177 }
178 
DisableGL()179 void OsrRenderHandlerWinGL::DisableGL() {
180   if (!hdc_) {
181     return;
182   }
183 
184   {
185     ScopedGLContext scoped_gl_context(hdc_, hrc_, false);
186     renderer_.Cleanup();
187   }
188 
189   if (IsWindow(hwnd())) {
190     // wglDeleteContext will make the context not current before deleting it.
191     BOOL result = wglDeleteContext(hrc_);
192     ALLOW_UNUSED_LOCAL(result);
193     DCHECK(result);
194     ReleaseDC(hwnd(), hdc_);
195   }
196 
197   hdc_ = nullptr;
198   hrc_ = nullptr;
199 }
200 
201 }  // namespace client
202