OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file implements the NativeViewGLContext and PbufferGLContext classes. | 5 // This file implements the NativeViewGLContext and PbufferGLContext classes. |
6 | 6 |
7 #include <GL/glew.h> | |
8 #include <GL/osmew.h> | |
9 #include <GL/wglew.h> | |
10 #include <windows.h> | |
11 | |
12 #include <algorithm> | 7 #include <algorithm> |
13 | 8 |
14 #include "base/logging.h" | 9 #include "base/logging.h" |
15 #include "base/scoped_ptr.h" | 10 #include "base/scoped_ptr.h" |
| 11 #include "app/gfx/gl/gl_bindings.h" |
16 #include "app/gfx/gl/gl_context.h" | 12 #include "app/gfx/gl/gl_context.h" |
| 13 #include "app/gfx/gl/gl_context_egl.h" |
17 #include "app/gfx/gl/gl_context_osmesa.h" | 14 #include "app/gfx/gl/gl_context_osmesa.h" |
| 15 #include "app/gfx/gl/gl_context_stub.h" |
| 16 #include "app/gfx/gl/gl_implementation.h" |
18 | 17 |
19 namespace gfx { | 18 namespace gfx { |
20 | 19 |
21 typedef HGLRC GLContextHandle; | 20 typedef HGLRC GLContextHandle; |
22 typedef HPBUFFERARB PbufferHandle; | 21 typedef HPBUFFERARB PbufferHandle; |
23 | 22 |
24 const wchar_t kNativeViewGLClass[] = L"NativeViewGLWindow"; | 23 const wchar_t kNativeViewGLClass[] = L"NativeViewGLWindow"; |
25 | 24 |
26 // This class is a wrapper around a GL context that renders directly to a | 25 // This class is a wrapper around a GL context that renders directly to a |
27 // window. | 26 // window. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 // rendering. | 92 // rendering. |
94 class PbufferGLContext : public GLContext { | 93 class PbufferGLContext : public GLContext { |
95 public: | 94 public: |
96 PbufferGLContext() | 95 PbufferGLContext() |
97 : context_(NULL), | 96 : context_(NULL), |
98 device_context_(NULL), | 97 device_context_(NULL), |
99 pbuffer_(NULL) { | 98 pbuffer_(NULL) { |
100 } | 99 } |
101 | 100 |
102 // Initializes the GL context. | 101 // Initializes the GL context. |
103 bool Initialize(void* shared_handle); | 102 bool Initialize(GLContext* shared_context); |
104 | 103 |
105 virtual void Destroy(); | 104 virtual void Destroy(); |
106 virtual bool MakeCurrent(); | 105 virtual bool MakeCurrent(); |
107 virtual bool IsCurrent(); | 106 virtual bool IsCurrent(); |
108 virtual bool IsOffscreen(); | 107 virtual bool IsOffscreen(); |
109 virtual void SwapBuffers(); | 108 virtual void SwapBuffers(); |
110 virtual gfx::Size GetSize(); | 109 virtual gfx::Size GetSize(); |
111 virtual void* GetHandle(); | 110 virtual void* GetHandle(); |
112 | 111 |
113 private: | 112 private: |
114 GLContextHandle context_; | 113 GLContextHandle context_; |
115 HDC device_context_; | 114 HDC device_context_; |
116 PbufferHandle pbuffer_; | 115 PbufferHandle pbuffer_; |
117 | 116 |
118 DISALLOW_COPY_AND_ASSIGN(PbufferGLContext); | 117 DISALLOW_COPY_AND_ASSIGN(PbufferGLContext); |
119 }; | 118 }; |
120 | 119 |
| 120 static HWND g_window; |
121 static int g_regular_pixel_format = 0; | 121 static int g_regular_pixel_format = 0; |
122 static int g_multisampled_pixel_format = 0; | 122 static int g_multisampled_pixel_format = 0; |
123 | 123 |
| 124 // When using ANGLE we still need a window for D3D. This context creates the |
| 125 // D3D device. |
| 126 static BaseEGLContext* g_default_context; |
| 127 |
124 const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { | 128 const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { |
125 sizeof(kPixelFormatDescriptor), // Size of structure. | 129 sizeof(kPixelFormatDescriptor), // Size of structure. |
126 1, // Default version. | 130 1, // Default version. |
127 PFD_DRAW_TO_WINDOW | // Window drawing support. | 131 PFD_DRAW_TO_WINDOW | // Window drawing support. |
128 PFD_SUPPORT_OPENGL | // OpenGL support. | 132 PFD_SUPPORT_OPENGL | // OpenGL support. |
129 PFD_DOUBLEBUFFER, // Double buffering support (not stereo). | 133 PFD_DOUBLEBUFFER, // Double buffering support (not stereo). |
130 PFD_TYPE_RGBA, // RGBA color mode (not indexed). | 134 PFD_TYPE_RGBA, // RGBA color mode (not indexed). |
131 24, // 24 bit color mode. | 135 24, // 24 bit color mode. |
132 0, 0, 0, 0, 0, 0, // Don't set RGB bits & shifts. | 136 0, 0, 0, 0, 0, 0, // Don't set RGB bits & shifts. |
133 8, 0, // 8 bit alpha | 137 8, 0, // 8 bit alpha |
(...skipping 14 matching lines...) Expand all Loading... |
148 return ::DefWindowProc(window, message, w_param, l_param); | 152 return ::DefWindowProc(window, message, w_param, l_param); |
149 } | 153 } |
150 | 154 |
151 // Helper routine that does one-off initialization like determining the | 155 // Helper routine that does one-off initialization like determining the |
152 // pixel format and initializing glew. | 156 // pixel format and initializing glew. |
153 static bool InitializeOneOff() { | 157 static bool InitializeOneOff() { |
154 static bool initialized = false; | 158 static bool initialized = false; |
155 if (initialized) | 159 if (initialized) |
156 return true; | 160 return true; |
157 | 161 |
158 osmewInit(); | 162 if (!InitializeGLBindings(kGLImplementationOSMesaGL)) { |
159 if (!OSMesaCreateContext) { | 163 if (!InitializeGLBindings(kGLImplementationEGLGLES2)) { |
160 // We must initialize a GL context before we can determine the multi- | 164 if (!InitializeGLBindings(kGLImplementationDesktopGL)) { |
161 // sampling supported on the current hardware, so we create an intermediate | 165 LOG(ERROR) << "Could not initialize GL."; |
162 // window and context here. | |
163 HINSTANCE module_handle; | |
164 if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | | |
165 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, | |
166 reinterpret_cast<wchar_t*>(IntermediateWindowProc), | |
167 &module_handle)) { | |
168 return false; | |
169 } | |
170 | |
171 WNDCLASS intermediate_class; | |
172 intermediate_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; | |
173 intermediate_class.lpfnWndProc = IntermediateWindowProc; | |
174 intermediate_class.cbClsExtra = 0; | |
175 intermediate_class.cbWndExtra = 0; | |
176 intermediate_class.hInstance = module_handle; | |
177 intermediate_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); | |
178 intermediate_class.hCursor = LoadCursor(NULL, IDC_ARROW); | |
179 intermediate_class.hbrBackground = NULL; | |
180 intermediate_class.lpszMenuName = NULL; | |
181 intermediate_class.lpszClassName = L"Intermediate GL Window"; | |
182 | |
183 ATOM class_registration = ::RegisterClass(&intermediate_class); | |
184 if (!class_registration) { | |
185 return false; | |
186 } | |
187 | |
188 HWND intermediate_window = ::CreateWindow( | |
189 reinterpret_cast<wchar_t*>(class_registration), | |
190 L"", | |
191 WS_OVERLAPPEDWINDOW, | |
192 0, 0, | |
193 CW_USEDEFAULT, CW_USEDEFAULT, | |
194 NULL, | |
195 NULL, | |
196 NULL, | |
197 NULL); | |
198 | |
199 if (!intermediate_window) { | |
200 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), | |
201 module_handle); | |
202 return false; | |
203 } | |
204 | |
205 HDC intermediate_dc = ::GetDC(intermediate_window); | |
206 g_regular_pixel_format = ::ChoosePixelFormat(intermediate_dc, | |
207 &kPixelFormatDescriptor); | |
208 if (g_regular_pixel_format == 0) { | |
209 DLOG(ERROR) << "Unable to get the pixel format for GL context."; | |
210 ::ReleaseDC(intermediate_window, intermediate_dc); | |
211 ::DestroyWindow(intermediate_window); | |
212 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), | |
213 module_handle); | |
214 return false; | |
215 } | |
216 if (!::SetPixelFormat(intermediate_dc, g_regular_pixel_format, | |
217 &kPixelFormatDescriptor)) { | |
218 DLOG(ERROR) << "Unable to set the pixel format for GL context."; | |
219 ::ReleaseDC(intermediate_window, intermediate_dc); | |
220 ::DestroyWindow(intermediate_window); | |
221 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), | |
222 module_handle); | |
223 return false; | |
224 } | |
225 | |
226 // Create a temporary GL context to query for multisampled pixel formats. | |
227 HGLRC gl_context = ::wglCreateContext(intermediate_dc); | |
228 if (::wglMakeCurrent(intermediate_dc, gl_context)) { | |
229 // GL context was successfully created and applied to the window's DC. | |
230 // Startup GLEW, the GL extensions wrangler. | |
231 if (InitializeGLEW()) { | |
232 DLOG(INFO) << "Initialized GLEW " << glewGetString(GLEW_VERSION); | |
233 } else { | |
234 ::wglMakeCurrent(intermediate_dc, NULL); | |
235 ::wglDeleteContext(gl_context); | |
236 ::ReleaseDC(intermediate_window, intermediate_dc); | |
237 ::DestroyWindow(intermediate_window); | |
238 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), | |
239 module_handle); | |
240 return false; | 166 return false; |
241 } | 167 } |
| 168 } |
| 169 } |
242 | 170 |
243 // If the multi-sample extensions are present, query the api to determine | 171 |
244 // the pixel format. | 172 // We must initialize a GL context before we can determine the multi- |
245 if (WGLEW_ARB_pixel_format && WGLEW_ARB_multisample) { | 173 // sampling supported on the current hardware, so we create an intermediate |
| 174 // window and context here. |
| 175 HINSTANCE module_handle; |
| 176 if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | |
| 177 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, |
| 178 reinterpret_cast<wchar_t*>(IntermediateWindowProc), |
| 179 &module_handle)) { |
| 180 return false; |
| 181 } |
| 182 |
| 183 WNDCLASS intermediate_class; |
| 184 intermediate_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; |
| 185 intermediate_class.lpfnWndProc = IntermediateWindowProc; |
| 186 intermediate_class.cbClsExtra = 0; |
| 187 intermediate_class.cbWndExtra = 0; |
| 188 intermediate_class.hInstance = module_handle; |
| 189 intermediate_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); |
| 190 intermediate_class.hCursor = LoadCursor(NULL, IDC_ARROW); |
| 191 intermediate_class.hbrBackground = NULL; |
| 192 intermediate_class.lpszMenuName = NULL; |
| 193 intermediate_class.lpszClassName = L"Intermediate GL Window"; |
| 194 |
| 195 ATOM class_registration = ::RegisterClass(&intermediate_class); |
| 196 if (!class_registration) { |
| 197 return false; |
| 198 } |
| 199 |
| 200 g_window = ::CreateWindow( |
| 201 reinterpret_cast<wchar_t*>(class_registration), |
| 202 L"", |
| 203 WS_OVERLAPPEDWINDOW, |
| 204 0, 0, |
| 205 100, 100, |
| 206 NULL, |
| 207 NULL, |
| 208 NULL, |
| 209 NULL); |
| 210 |
| 211 if (!g_window) { |
| 212 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), |
| 213 module_handle); |
| 214 return false; |
| 215 } |
| 216 |
| 217 // Early out if OSMesa offscreen renderer or EGL is present. |
| 218 if (GetGLImplementation() != kGLImplementationDesktopGL) { |
| 219 initialized = true; |
| 220 return true; |
| 221 } |
| 222 |
| 223 HDC intermediate_dc = ::GetDC(g_window); |
| 224 g_regular_pixel_format = ::ChoosePixelFormat(intermediate_dc, |
| 225 &kPixelFormatDescriptor); |
| 226 if (g_regular_pixel_format == 0) { |
| 227 DLOG(ERROR) << "Unable to get the pixel format for GL context."; |
| 228 ::ReleaseDC(g_window, intermediate_dc); |
| 229 ::DestroyWindow(g_window); |
| 230 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), |
| 231 module_handle); |
| 232 return false; |
| 233 } |
| 234 if (!::SetPixelFormat(intermediate_dc, g_regular_pixel_format, |
| 235 &kPixelFormatDescriptor)) { |
| 236 DLOG(ERROR) << "Unable to set the pixel format for GL context."; |
| 237 ::ReleaseDC(g_window, intermediate_dc); |
| 238 ::DestroyWindow(g_window); |
| 239 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), |
| 240 module_handle); |
| 241 return false; |
| 242 } |
| 243 |
| 244 // Create a temporary GL context to query for multisampled pixel formats. |
| 245 HGLRC gl_context = wglCreateContext(intermediate_dc); |
| 246 if (wglMakeCurrent(intermediate_dc, gl_context)) { |
| 247 // Get bindings to extension functions that cannot be acquired without a |
| 248 // current context. |
| 249 InitializeGLBindingsGL(); |
| 250 InitializeGLBindingsWGL(); |
| 251 |
| 252 // If the multi-sample extensions are present, query the api to determine |
| 253 // the pixel format. |
| 254 if (wglGetExtensionsStringARB) { |
| 255 std::string extensions = |
| 256 std::string(wglGetExtensionsStringARB(intermediate_dc)); |
| 257 extensions += std::string(" "); |
| 258 if (extensions.find("WGL_ARB_pixel_format ")) { |
246 int pixel_attributes[] = { | 259 int pixel_attributes[] = { |
247 WGL_SAMPLES_ARB, 4, | 260 WGL_SAMPLES_ARB, 4, |
248 WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, | 261 WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, |
249 WGL_SUPPORT_OPENGL_ARB, GL_TRUE, | 262 WGL_SUPPORT_OPENGL_ARB, GL_TRUE, |
250 WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, | 263 WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, |
251 WGL_COLOR_BITS_ARB, 24, | 264 WGL_COLOR_BITS_ARB, 24, |
252 WGL_ALPHA_BITS_ARB, 8, | 265 WGL_ALPHA_BITS_ARB, 8, |
253 WGL_DEPTH_BITS_ARB, 24, | 266 WGL_DEPTH_BITS_ARB, 24, |
254 WGL_STENCIL_BITS_ARB, 8, | 267 WGL_STENCIL_BITS_ARB, 8, |
255 WGL_DOUBLE_BUFFER_ARB, GL_TRUE, | 268 WGL_DOUBLE_BUFFER_ARB, GL_TRUE, |
256 WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, | 269 WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, |
257 0, 0}; | 270 0, 0}; |
258 | 271 |
259 float pixel_attributes_f[] = {0, 0}; | 272 float pixel_attributes_f[] = {0, 0}; |
260 unsigned int num_formats; | 273 unsigned int num_formats; |
261 | 274 |
262 // Query for the highest sampling rate supported, starting at 4x. | 275 // Query for the highest sampling rate supported, starting at 4x. |
263 static const int kSampleCount[] = {4, 2}; | 276 static const int kSampleCount[] = {4, 2}; |
264 static const int kNumSamples = 2; | 277 static const int kNumSamples = 2; |
265 for (int sample = 0; sample < kNumSamples; ++sample) { | 278 for (int sample = 0; sample < kNumSamples; ++sample) { |
266 pixel_attributes[1] = kSampleCount[sample]; | 279 pixel_attributes[1] = kSampleCount[sample]; |
267 if (GL_TRUE == ::wglChoosePixelFormatARB(intermediate_dc, | 280 if (GL_TRUE == wglChoosePixelFormatARB(intermediate_dc, |
268 pixel_attributes, | 281 pixel_attributes, |
269 pixel_attributes_f, | 282 pixel_attributes_f, |
270 1, | 283 1, |
271 &g_multisampled_pixel_format, | 284 &g_multisampled_pixel_format, |
272 &num_formats)) { | 285 &num_formats)) { |
273 break; | 286 break; |
274 } | 287 } |
275 } | 288 } |
276 } | 289 } |
277 } | 290 } |
278 | |
279 ::wglMakeCurrent(intermediate_dc, NULL); | |
280 ::wglDeleteContext(gl_context); | |
281 ::ReleaseDC(intermediate_window, intermediate_dc); | |
282 ::DestroyWindow(intermediate_window); | |
283 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), | |
284 module_handle); | |
285 } | 291 } |
286 | 292 |
| 293 wglMakeCurrent(intermediate_dc, NULL); |
| 294 wglDeleteContext(gl_context); |
| 295 ReleaseDC(g_window, intermediate_dc); |
| 296 UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), |
| 297 module_handle); |
| 298 |
287 initialized = true; | 299 initialized = true; |
288 | |
289 return true; | 300 return true; |
290 } | 301 } |
291 | 302 |
292 HWND NativeViewGLContext::CreateContentWindow(HWND parent) { | 303 HWND NativeViewGLContext::CreateContentWindow(HWND parent) { |
293 WNDCLASS window_class = {0}; | 304 WNDCLASS window_class = {0}; |
294 if (!GetClassInfo(GetModuleHandle(0), kNativeViewGLClass, &window_class)) { | 305 if (!GetClassInfo(GetModuleHandle(0), kNativeViewGLClass, &window_class)) { |
295 window_class.style = CS_OWNDC; | 306 window_class.style = CS_OWNDC; |
296 window_class.hInstance = GetModuleHandle(0); | 307 window_class.hInstance = GetModuleHandle(0); |
297 window_class.lpfnWndProc = DefWindowProc; | 308 window_class.lpfnWndProc = DefWindowProc; |
298 window_class.lpszClassName = kNativeViewGLClass; | 309 window_class.lpszClassName = kNativeViewGLClass; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 DLOG(ERROR) << "Failed to create GL context."; | 356 DLOG(ERROR) << "Failed to create GL context."; |
346 Destroy(); | 357 Destroy(); |
347 return false; | 358 return false; |
348 } | 359 } |
349 | 360 |
350 if (!MakeCurrent()) { | 361 if (!MakeCurrent()) { |
351 Destroy(); | 362 Destroy(); |
352 return false; | 363 return false; |
353 } | 364 } |
354 | 365 |
355 if (!InitializeGLEW()) { | |
356 Destroy(); | |
357 return false; | |
358 } | |
359 | |
360 if (!InitializeCommon()) { | 366 if (!InitializeCommon()) { |
361 Destroy(); | 367 Destroy(); |
362 return false; | 368 return false; |
363 } | 369 } |
364 | 370 |
365 return true; | 371 return true; |
366 } | 372 } |
367 | 373 |
368 void NativeViewGLContext::Destroy() { | 374 void NativeViewGLContext::Destroy() { |
369 if (context_) { | 375 if (context_) { |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 return osmesa_context_.GetSize(); | 509 return osmesa_context_.GetSize(); |
504 } | 510 } |
505 | 511 |
506 void* OSMesaViewGLContext::GetHandle() { | 512 void* OSMesaViewGLContext::GetHandle() { |
507 return osmesa_context_.GetHandle(); | 513 return osmesa_context_.GetHandle(); |
508 } | 514 } |
509 | 515 |
510 void OSMesaViewGLContext::UpdateSize() { | 516 void OSMesaViewGLContext::UpdateSize() { |
511 // Change back buffer size to that of window. | 517 // Change back buffer size to that of window. |
512 RECT rect; | 518 RECT rect; |
513 GetWindowRect(window_, &rect); | 519 GetClientRect(window_, &rect); |
514 gfx::Size window_size = gfx::Size( | 520 gfx::Size window_size = gfx::Size( |
515 std::max(1, static_cast<int>(rect.right - rect.left)), | 521 std::max(1, static_cast<int>(rect.right - rect.left)), |
516 std::max(1, static_cast<int>(rect.bottom - rect.top))); | 522 std::max(1, static_cast<int>(rect.bottom - rect.top))); |
517 osmesa_context_.Resize(window_size); | 523 osmesa_context_.Resize(window_size); |
518 } | 524 } |
519 | 525 |
520 GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window, | 526 GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window, |
521 bool multisampled) { | 527 bool multisampled) { |
522 if (!InitializeOneOff()) | 528 if (!InitializeOneOff()) |
523 return NULL; | 529 return NULL; |
524 | 530 |
525 if (OSMesaCreateContext) { | 531 switch (GetGLImplementation()) { |
526 scoped_ptr<OSMesaViewGLContext> context(new OSMesaViewGLContext(window)); | 532 case kGLImplementationOSMesaGL: { |
| 533 scoped_ptr<OSMesaViewGLContext> context(new OSMesaViewGLContext(window)); |
| 534 if (!context->Initialize()) |
| 535 return NULL; |
527 | 536 |
528 if (!context->Initialize()) | 537 return context.release(); |
| 538 } |
| 539 case kGLImplementationEGLGLES2: { |
| 540 scoped_ptr<NativeViewEGLContext> context( |
| 541 new NativeViewEGLContext(window)); |
| 542 if (!context->Initialize()) |
| 543 return NULL; |
| 544 |
| 545 return context.release(); |
| 546 } |
| 547 case kGLImplementationDesktopGL: { |
| 548 scoped_ptr<NativeViewGLContext> context(new NativeViewGLContext(window)); |
| 549 if (!context->Initialize(multisampled)) |
| 550 return NULL; |
| 551 |
| 552 return context.release(); |
| 553 } |
| 554 case kGLImplementationMockGL: |
| 555 return new StubGLContext; |
| 556 default: |
| 557 NOTREACHED(); |
529 return NULL; | 558 return NULL; |
530 | |
531 return context.release(); | |
532 } else { | |
533 scoped_ptr<NativeViewGLContext> context(new NativeViewGLContext(window)); | |
534 | |
535 if (!context->Initialize(multisampled)) | |
536 return NULL; | |
537 | |
538 return context.release(); | |
539 } | 559 } |
540 } | 560 } |
541 | 561 |
542 bool PbufferGLContext::Initialize(void* shared_handle) { | 562 bool PbufferGLContext::Initialize(GLContext* shared_context) { |
543 // Create a device context compatible with the primary display. | 563 // Create a device context compatible with the primary display. |
544 HDC display_device_context = ::CreateDC(L"DISPLAY", NULL, NULL, NULL); | 564 HDC display_device_context = ::CreateDC(L"DISPLAY", NULL, NULL, NULL); |
545 | 565 |
546 // Create a 1 x 1 pbuffer suitable for use with the device. This is just | 566 // Create a 1 x 1 pbuffer suitable for use with the device. This is just |
547 // a stepping stone towards creating a frame buffer object. It doesn't | 567 // a stepping stone towards creating a frame buffer object. It doesn't |
548 // matter what size it is. | 568 // matter what size it is. |
549 const int kNoAttributes[] = { 0 }; | 569 const int kNoAttributes[] = { 0 }; |
550 pbuffer_ = ::wglCreatePbufferARB(display_device_context, | 570 pbuffer_ = wglCreatePbufferARB(display_device_context, |
551 g_regular_pixel_format, | 571 g_regular_pixel_format, |
552 1, 1, | 572 1, 1, |
553 kNoAttributes); | 573 kNoAttributes); |
554 ::DeleteDC(display_device_context); | 574 ::DeleteDC(display_device_context); |
555 if (!pbuffer_) { | 575 if (!pbuffer_) { |
556 DLOG(ERROR) << "Unable to create pbuffer."; | 576 DLOG(ERROR) << "Unable to create pbuffer."; |
557 Destroy(); | 577 Destroy(); |
558 return false; | 578 return false; |
559 } | 579 } |
560 | 580 |
561 device_context_ = ::wglGetPbufferDCARB(pbuffer_); | 581 device_context_ = wglGetPbufferDCARB(pbuffer_); |
562 if (!device_context_) { | 582 if (!device_context_) { |
563 DLOG(ERROR) << "Unable to get pbuffer device context."; | 583 DLOG(ERROR) << "Unable to get pbuffer device context."; |
564 Destroy(); | 584 Destroy(); |
565 return false; | 585 return false; |
566 } | 586 } |
567 | 587 |
568 context_ = ::wglCreateContext(device_context_); | 588 context_ = wglCreateContext(device_context_); |
569 if (!context_) { | 589 if (!context_) { |
570 DLOG(ERROR) << "Failed to create GL context."; | 590 DLOG(ERROR) << "Failed to create GL context."; |
571 Destroy(); | 591 Destroy(); |
572 return false; | 592 return false; |
573 } | 593 } |
574 | 594 |
575 if (shared_handle) { | 595 if (shared_context) { |
576 if (!wglShareLists(static_cast<GLContextHandle>(shared_handle), context_)) { | 596 if (!wglShareLists( |
| 597 static_cast<GLContextHandle>(shared_context->GetHandle()), context_)) { |
577 DLOG(ERROR) << "Could not share GL contexts."; | 598 DLOG(ERROR) << "Could not share GL contexts."; |
578 Destroy(); | 599 Destroy(); |
579 return false; | 600 return false; |
580 } | 601 } |
581 } | 602 } |
582 | 603 |
583 if (!MakeCurrent()) { | 604 if (!MakeCurrent()) { |
584 Destroy(); | 605 Destroy(); |
585 return false; | 606 return false; |
586 } | 607 } |
587 | 608 |
588 if (!InitializeGLEW()) { | |
589 Destroy(); | |
590 return false; | |
591 } | |
592 | |
593 if (!InitializeCommon()) { | 609 if (!InitializeCommon()) { |
594 Destroy(); | 610 Destroy(); |
595 return false; | 611 return false; |
596 } | 612 } |
597 | 613 |
598 return true; | 614 return true; |
599 } | 615 } |
600 | 616 |
601 void PbufferGLContext::Destroy() { | 617 void PbufferGLContext::Destroy() { |
602 if (context_) { | 618 if (context_) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 | 658 |
643 gfx::Size PbufferGLContext::GetSize() { | 659 gfx::Size PbufferGLContext::GetSize() { |
644 NOTREACHED() << "Should not be requesting size of this pbuffer."; | 660 NOTREACHED() << "Should not be requesting size of this pbuffer."; |
645 return gfx::Size(1, 1); | 661 return gfx::Size(1, 1); |
646 } | 662 } |
647 | 663 |
648 void* PbufferGLContext::GetHandle() { | 664 void* PbufferGLContext::GetHandle() { |
649 return context_; | 665 return context_; |
650 } | 666 } |
651 | 667 |
652 GLContext* GLContext::CreateOffscreenGLContext(void* shared_handle) { | 668 GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) { |
653 if (!InitializeOneOff()) | 669 if (!InitializeOneOff()) |
654 return NULL; | 670 return NULL; |
655 | 671 |
656 if (OSMesaCreateContext) { | 672 switch (GetGLImplementation()) { |
657 scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext); | 673 case kGLImplementationOSMesaGL: { |
| 674 scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext); |
| 675 if (!context->Initialize(shared_context)) |
| 676 return NULL; |
658 | 677 |
659 if (!context->Initialize(shared_handle)) | 678 return context.release(); |
| 679 } |
| 680 case kGLImplementationEGLGLES2: { |
| 681 if (!shared_context) { |
| 682 if (!g_default_context) { |
| 683 scoped_ptr<NativeViewEGLContext> default_context( |
| 684 new NativeViewEGLContext(g_window)); |
| 685 if (!default_context->Initialize()) |
| 686 return NULL; |
| 687 |
| 688 g_default_context = default_context.release(); |
| 689 } |
| 690 shared_context = g_default_context; |
| 691 } |
| 692 |
| 693 scoped_ptr<SecondaryEGLContext> context( |
| 694 new SecondaryEGLContext()); |
| 695 if (!context->Initialize(shared_context)) |
| 696 return NULL; |
| 697 |
| 698 return context.release(); |
| 699 } |
| 700 case kGLImplementationDesktopGL: { |
| 701 scoped_ptr<PbufferGLContext> context(new PbufferGLContext); |
| 702 if (!context->Initialize(shared_context)) |
| 703 return NULL; |
| 704 |
| 705 return context.release(); |
| 706 } |
| 707 case kGLImplementationMockGL: |
| 708 return new StubGLContext; |
| 709 default: |
| 710 NOTREACHED(); |
660 return NULL; | 711 return NULL; |
661 | |
662 return context.release(); | |
663 } else { | |
664 scoped_ptr<PbufferGLContext> context(new PbufferGLContext); | |
665 if (!context->Initialize(shared_handle)) | |
666 return NULL; | |
667 | |
668 return context.release(); | |
669 } | 712 } |
670 } | 713 } |
671 | 714 |
672 } // namespace gfx | 715 } // namespace gfx |
OLD | NEW |