Index: ui/gl/gl_implementation_win.cc |
diff --git a/ui/gl/gl_implementation_win.cc b/ui/gl/gl_implementation_win.cc |
index 87328a306f8f4783a4535073ff5a4f215f263e17..79cb14bbbcc3eefed324074530b55295b465dd9c 100644 |
--- a/ui/gl/gl_implementation_win.cc |
+++ b/ui/gl/gl_implementation_win.cc |
@@ -17,10 +17,12 @@ |
#include "base/threading/thread_restrictions.h" |
#include "base/win/windows_version.h" |
#include "ui/gl/gl_bindings.h" |
+#include "ui/gl/gl_context_stub_with_extensions.h" |
#include "ui/gl/gl_egl_api_implementation.h" |
#include "ui/gl/gl_gl_api_implementation.h" |
#include "ui/gl/gl_implementation.h" |
#include "ui/gl/gl_osmesa_api_implementation.h" |
+#include "ui/gl/gl_surface_wgl.h" |
#include "ui/gl/gl_wgl_api_implementation.h" |
#if defined(ENABLE_SWIFTSHADER) |
@@ -106,7 +108,7 @@ void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) { |
impls->push_back(kGLImplementationOSMesaGL); |
} |
-bool InitializeGLBindings(GLImplementation implementation) { |
+bool InitializeStaticGLBindings(GLImplementation implementation) { |
// Prevent reinitialization with a different implementation. Once the gpu |
// unit tests have initialized with kGLImplementationMock, we don't want to |
// later switch to another GL implementation. |
@@ -148,8 +150,8 @@ bool InitializeGLBindings(GLImplementation implementation) { |
AddGLNativeLibrary(library); |
SetGLImplementation(kGLImplementationOSMesaGL); |
- InitializeGLBindingsGL(); |
- InitializeGLBindingsOSMESA(); |
+ InitializeStaticGLBindingsGL(); |
+ InitializeStaticGLBindingsOSMESA(); |
break; |
} |
case kGLImplementationEGLGLES2: { |
@@ -234,8 +236,8 @@ bool InitializeGLBindings(GLImplementation implementation) { |
AddGLNativeLibrary(gles_library); |
SetGLImplementation(kGLImplementationEGLGLES2); |
- InitializeGLBindingsGL(); |
- InitializeGLBindingsEGL(); |
+ InitializeStaticGLBindingsGL(); |
+ InitializeStaticGLBindingsEGL(); |
// These two functions take single precision float rather than double |
// precision float parameters in GLES. |
@@ -244,8 +246,6 @@ bool InitializeGLBindings(GLImplementation implementation) { |
break; |
} |
case kGLImplementationDesktopGL: { |
- // When using Windows OpenGL, first try wglGetProcAddress and then |
- // Windows GetProcAddress. |
base::NativeLibrary library = base::LoadNativeLibrary( |
base::FilePath(L"opengl32.dll"), NULL); |
if (!library) { |
@@ -267,14 +267,41 @@ bool InitializeGLBindings(GLImplementation implementation) { |
AddGLNativeLibrary(library); |
SetGLImplementation(kGLImplementationDesktopGL); |
- InitializeGLBindingsGL(); |
- InitializeGLBindingsWGL(); |
+ // Initialize WGL bindings to be able to create a context. |
+ InitializeStaticGLBindingsWGL(); |
no sievers
2014/01/14 23:16:01
How about only looking up the symbol for wglCreate
oetuaho-nv
2014/01/15 15:50:25
True. Done.
|
+ |
+ // Create a temporary GL context to bind to entry points. This is needed |
+ // because wglGetProcAddress is specified to return NULL for all queries |
+ // if a context is not current in MSDN documentation, and the static |
+ // bindings may contain functions that need to be queried with |
+ // wglGetProcAddress. OpenGL wiki further warns that other error values |
+ // than NULL could also be returned from wglGetProcAddress on some |
+ // implementations, so we need to clear the WGL bindings and reinitialize |
+ // them after the context creation. |
+ HGLRC gl_context = wglCreateContext(GLSurfaceWGL::GetDisplayDC()); |
+ if (!gl_context) { |
+ LOG(ERROR) << "Failed to create temporary context."; |
+ return false; |
+ } |
+ if (!wglMakeCurrent(GLSurfaceWGL::GetDisplayDC(), gl_context)) { |
+ LOG(ERROR) << "Failed to make temporary GL context current."; |
+ wglDeleteContext(gl_context); |
+ return false; |
+ } |
+ |
+ ClearGLBindingsWGL(); |
+ InitializeStaticGLBindingsGL(); |
+ InitializeStaticGLBindingsWGL(); |
+ |
+ wglMakeCurrent(NULL, NULL); |
+ wglDeleteContext(gl_context); |
+ |
break; |
} |
case kGLImplementationMockGL: { |
SetGLGetProcAddressProc(GetMockGLProcAddress); |
SetGLImplementation(kGLImplementationMockGL); |
- InitializeGLBindingsGL(); |
+ InitializeStaticGLBindingsGL(); |
break; |
} |
default: |
@@ -284,23 +311,29 @@ bool InitializeGLBindings(GLImplementation implementation) { |
return true; |
} |
-bool InitializeGLExtensionBindings(GLImplementation implementation, |
+bool InitializeDynamicGLBindings(GLImplementation implementation, |
GLContext* context) { |
switch (implementation) { |
case kGLImplementationOSMesaGL: |
- InitializeGLExtensionBindingsGL(context); |
- InitializeGLExtensionBindingsOSMESA(context); |
+ InitializeDynamicGLBindingsGL(context); |
+ InitializeDynamicGLBindingsOSMESA(context); |
break; |
case kGLImplementationEGLGLES2: |
- InitializeGLExtensionBindingsGL(context); |
- InitializeGLExtensionBindingsEGL(context); |
+ InitializeDynamicGLBindingsGL(context); |
+ InitializeDynamicGLBindingsEGL(context); |
break; |
case kGLImplementationDesktopGL: |
- InitializeGLExtensionBindingsGL(context); |
- InitializeGLExtensionBindingsWGL(context); |
+ InitializeDynamicGLBindingsGL(context); |
+ InitializeDynamicGLBindingsWGL(context); |
break; |
case kGLImplementationMockGL: |
- InitializeGLExtensionBindingsGL(context); |
+ if (!context) { |
+ scoped_refptr<GLContextStubWithExtensions> mock_context( |
+ new GLContextStubWithExtensions()); |
+ mock_context->SetGLVersionString("3.0"); |
+ InitializeDynamicGLBindingsGL(mock_context.get()); |
+ } else |
+ InitializeDynamicGLBindingsGL(context); |
break; |
default: |
return false; |