| 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 |