summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/gfx/gl/generate_bindings.py19
-rw-r--r--ui/gfx/gl/gl_implementation.cc59
-rw-r--r--ui/gfx/gl/gl_implementation.h21
-rw-r--r--ui/gfx/gl/gl_implementation_linux.cc18
-rw-r--r--ui/gfx/gl/gl_implementation_mac.cc13
-rw-r--r--ui/gfx/gl/gl_implementation_win.cc48
-rw-r--r--ui/gfx/gl/gl_surface.cc54
-rw-r--r--ui/gfx/gl/gl_surface.h1
-rw-r--r--ui/gfx/gl/gl_surface_linux.cc21
-rw-r--r--ui/gfx/gl/gl_surface_mac.cc21
-rw-r--r--ui/gfx/gl/gl_surface_wgl.cc214
-rw-r--r--ui/gfx/gl/gl_surface_win.cc22
12 files changed, 270 insertions, 241 deletions
diff --git a/ui/gfx/gl/generate_bindings.py b/ui/gfx/gl/generate_bindings.py
index 548e7ec..2e1a1e0 100644
--- a/ui/gfx/gl/generate_bindings.py
+++ b/ui/gfx/gl/generate_bindings.py
@@ -499,6 +499,7 @@ def GenerateHeader(file, functions, set_name, used_extension_functions):
file.write('void InitializeGLExtensionBindings%s(GLContext* context);\n' %
set_name.upper())
file.write('void InitializeDebugGLBindings%s();\n' % set_name.upper())
+ file.write('void ClearGLBindings%s();\n' % set_name.upper())
# Write typedefs for function pointer types. Always use the GL name for the
# typedef.
@@ -671,6 +672,24 @@ def GenerateSource(file, functions, set_name, used_extension_functions):
file.write(' }\n')
file.write('}\n')
+ # Write function to clear all function pointers.
+ file.write('\n')
+ file.write('void ClearGLBindings%s() {\n' % set_name.upper())
+ # Clear the availability of GL extensions.
+ for extension, ext_functions in used_extension_functions:
+ file.write(' g_%s = false;\n' % extension)
+ # Clear GL bindings.
+ file.write('\n')
+ for [return_type, names, arguments] in functions:
+ file.write(' g_%s = NULL;\n' % names[0])
+ # Clear debug GL bindings.
+ file.write('\n')
+ for [return_type, names, arguments] in functions:
+ file.write(' g_debug_%s = NULL;\n' % names[0])
+ file.write(' g_debugBindingsInitialized = false;\n')
+ file.write('}\n')
+
+ file.write('\n')
file.write('} // namespace gfx\n')
diff --git a/ui/gfx/gl/gl_implementation.cc b/ui/gfx/gl/gl_implementation.cc
index e334093..0f5df21 100644
--- a/ui/gfx/gl/gl_implementation.cc
+++ b/ui/gfx/gl/gl_implementation.cc
@@ -30,7 +30,6 @@ typedef std::vector<base::NativeLibrary> LibraryArray;
GLImplementation g_gl_implementation = kGLImplementationNone;
LibraryArray* g_libraries;
GLGetProcAddressProc g_get_proc_address;
-bool g_using_swiftshader;
void CleanupNativeLibraries(void* unused) {
if (g_libraries) {
@@ -77,56 +76,6 @@ const char* GetGLImplementationName(GLImplementation implementation) {
return "unknown";
}
-bool InitializeRequestedGLBindings(
- const GLImplementation* allowed_implementations_begin,
- const GLImplementation* allowed_implementations_end,
- GLImplementation default_implementation) {
- bool fallback_to_osmesa = false;
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) {
- std::string requested_implementation_name =
- CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL);
- GLImplementation requested_implementation;
- if (requested_implementation_name == "any") {
- requested_implementation = default_implementation;
- fallback_to_osmesa = true;
- } else if (requested_implementation_name == "swiftshader") {
- g_using_swiftshader = true;
- requested_implementation = kGLImplementationEGLGLES2;
- } else {
- requested_implementation =
- GetNamedGLImplementation(requested_implementation_name);
- }
- if (std::find(allowed_implementations_begin,
- allowed_implementations_end,
- requested_implementation) == allowed_implementations_end) {
- LOG(ERROR) << "Requested GL implementation is not available.";
- return false;
- }
-
- InitializeGLBindings(requested_implementation);
- } else {
- InitializeGLBindings(default_implementation);
- }
-
- if (GetGLImplementation() == kGLImplementationNone && fallback_to_osmesa)
- InitializeGLBindings(kGLImplementationOSMesaGL);
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableGPUServiceLogging)) {
- InitializeDebugGLBindings();
- }
-
- if (GetGLImplementation() == kGLImplementationNone) {
- LOG(ERROR) << "Could not initialize GL.";
- return false;
- } else {
- DVLOG(1) << "Using "
- << GetGLImplementationName(GetGLImplementation())
- << " GL implementation.";
- return true;
- }
-}
-
void SetGLImplementation(GLImplementation implementation) {
g_gl_implementation = implementation;
}
@@ -140,10 +89,6 @@ bool HasDesktopGLFeatures() {
kGLImplementationOSMesaGL == g_gl_implementation;
}
-bool UsingSwiftShader() {
- return g_using_swiftshader;
-}
-
void AddGLNativeLibrary(base::NativeLibrary library) {
DCHECK(library);
@@ -155,6 +100,10 @@ void AddGLNativeLibrary(base::NativeLibrary library) {
g_libraries->push_back(library);
}
+void UnloadGLNativeLibraries() {
+ CleanupNativeLibraries(NULL);
+}
+
void SetGLGetProcAddressProc(GLGetProcAddressProc proc) {
DCHECK(proc);
g_get_proc_address = proc;
diff --git a/ui/gfx/gl/gl_implementation.h b/ui/gfx/gl/gl_implementation.h
index f675914..cfbb33a 100644
--- a/ui/gfx/gl/gl_implementation.h
+++ b/ui/gfx/gl/gl_implementation.h
@@ -7,6 +7,7 @@
#pragma once
#include <string>
+#include <vector>
#include "base/native_library.h"
#include "build/build_config.h"
@@ -26,6 +27,8 @@ enum GLImplementation {
kGLImplementationMockGL
};
+void GetAllowedGLImplementations(std::vector<GLImplementation>* impls);
+
#if defined(OS_WIN)
typedef void* (WINAPI *GLGetProcAddressProc)(const char* name);
#else
@@ -42,6 +45,8 @@ GL_EXPORT bool InitializeGLExtensionBindings(GLImplementation implementation,
// Initialize Debug logging wrappers for GL bindings.
void InitializeDebugGLBindings();
+void ClearGLBindings();
+
// Set the current GL implementation.
void SetGLImplementation(GLImplementation implementation);
@@ -53,25 +58,17 @@ GL_EXPORT GLImplementation GetGLImplementation();
GL_EXPORT bool HasDesktopGLFeatures();
// Get the GL implementation with a given name.
-GLImplementation GetNamedGLImplementation(const std::wstring& name);
+GLImplementation GetNamedGLImplementation(const std::string& name);
// Get the name of a GL implementation.
const char* GetGLImplementationName(GLImplementation implementation);
-// Get whether the current GL implementation is swiftshader.
-bool UsingSwiftShader();
-
-// Initialize the preferred GL binding from the given list. The preferred GL
-// bindings depend on command line switches passed by the user and which GL
-// implementation is the default on a given platform.
-bool InitializeRequestedGLBindings(
- const GLImplementation* allowed_implementations_begin,
- const GLImplementation* allowed_implementations_end,
- GLImplementation default_implementation);
-
// Add a native library to those searched for GL entry points.
void AddGLNativeLibrary(base::NativeLibrary library);
+// Unloads all native libraries.
+void UnloadGLNativeLibraries();
+
// Set an additional function that will be called to find GL entry points.
void SetGLGetProcAddressProc(GLGetProcAddressProc proc);
diff --git a/ui/gfx/gl/gl_implementation_linux.cc b/ui/gfx/gl/gl_implementation_linux.cc
index 1085fc4..eed0a15 100644
--- a/ui/gfx/gl/gl_implementation_linux.cc
+++ b/ui/gfx/gl/gl_implementation_linux.cc
@@ -56,6 +56,12 @@ base::LazyInstance<base::Lock,
} // namespace anonymous
+void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
+ impls->push_back(kGLImplementationDesktopGL);
+ impls->push_back(kGLImplementationEGLGLES2);
+ impls->push_back(kGLImplementationOSMesaGL);
+}
+
bool InitializeGLBindings(GLImplementation implementation) {
#if (defined(TOOLKIT_VIEWS) && !defined(OS_CHROMEOS)) || defined(TOUCH_UI)
base::AutoLock locked(g_lock.Get());
@@ -215,4 +221,16 @@ void InitializeDebugGLBindings() {
#endif
}
+void ClearGLBindings() {
+ ClearGLBindingsEGL();
+ ClearGLBindingsGL();
+#if !defined(USE_WAYLAND)
+ ClearGLBindingsGLX();
+ ClearGLBindingsOSMESA();
+#endif
+ SetGLImplementation(kGLImplementationNone);
+
+ UnloadGLNativeLibraries();
+}
+
} // namespace gfx
diff --git a/ui/gfx/gl/gl_implementation_mac.cc b/ui/gfx/gl/gl_implementation_mac.cc
index 24d2c4d..a3574fa 100644
--- a/ui/gfx/gl/gl_implementation_mac.cc
+++ b/ui/gfx/gl/gl_implementation_mac.cc
@@ -18,6 +18,11 @@ const char kOpenGLFrameworkPath[] =
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL";
} // namespace anonymous
+void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
+ impls->push_back(kGLImplementationDesktopGL);
+ impls->push_back(kGLImplementationOSMesaGL);
+}
+
bool InitializeGLBindings(GLImplementation implementation) {
// Prevent reinitialization with a different implementation. Once the gpu
// unit tests have initialized with kGLImplementationMock, we don't want to
@@ -121,4 +126,12 @@ void InitializeDebugGLBindings() {
InitializeDebugGLBindingsOSMESA();
}
+void ClearGLBindings() {
+ ClearGLBindingsGL();
+ ClearGLBindingsOSMESA();
+ SetGLImplementation(kGLImplementationNone);
+
+ UnloadGLNativeLibraries();
+}
+
} // namespace gfx
diff --git a/ui/gfx/gl/gl_implementation_win.cc b/ui/gfx/gl/gl_implementation_win.cc
index bbd6b72..e98da61 100644
--- a/ui/gfx/gl/gl_implementation_win.cc
+++ b/ui/gfx/gl/gl_implementation_win.cc
@@ -27,6 +27,9 @@ namespace gfx {
namespace {
+typedef std::vector<base::NativeLibrary> LibraryArray;
+LibraryArray* g_d3dx_libraries;
+
void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
glClearDepthf(static_cast<GLclampf>(depth));
}
@@ -36,6 +39,17 @@ void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
}
+void UnloadD3DXLibraries(void* unused) {
+ if (g_d3dx_libraries) {
+ for (LibraryArray::iterator it = g_d3dx_libraries->begin();
+ it != g_d3dx_libraries->end(); ++it) {
+ base::UnloadNativeLibrary(*it);
+ }
+ delete g_d3dx_libraries;
+ g_d3dx_libraries = NULL;
+ }
+}
+
bool LoadD3DXLibrary(const FilePath& module_path,
const FilePath::StringType& name) {
base::NativeLibrary library = base::LoadNativeLibrary(FilePath(name), NULL);
@@ -47,14 +61,22 @@ bool LoadD3DXLibrary(const FilePath& module_path,
}
}
- base::AtExitManager::RegisterTask(
- base::Bind(base::UnloadNativeLibrary, library));
-
+ if (!g_d3dx_libraries) {
+ g_d3dx_libraries = new LibraryArray;
+ base::AtExitManager::RegisterCallback(UnloadD3DXLibraries, NULL);
+ }
+ g_d3dx_libraries->push_back(library);
return true;
}
} // namespace anonymous
+void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
+ impls->push_back(kGLImplementationEGLGLES2);
+ impls->push_back(kGLImplementationDesktopGL);
+ impls->push_back(kGLImplementationOSMesaGL);
+}
+
bool InitializeGLBindings(GLImplementation implementation) {
// Prevent reinitialization with a different implementation. Once the gpu
// unit tests have initialized with kGLImplementationMock, we don't want to
@@ -116,9 +138,10 @@ bool InitializeGLBindings(GLImplementation implementation) {
D3DX_SDK_VERSION));
FilePath gles_path;
-
- if (UsingSwiftShader()) {
- const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ bool using_swift_shader =
+ command_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader";
+ if (using_swift_shader) {
if (!command_line->HasSwitch(switches::kSwiftShaderPath))
return false;
gles_path =
@@ -148,7 +171,7 @@ bool InitializeGLBindings(GLImplementation implementation) {
}
#if defined(ENABLE_SWIFTSHADER)
- if (UsingSwiftShader()) {
+ if (using_swift_shader) {
SetupSoftwareRenderer(gles_library);
}
#endif
@@ -251,4 +274,15 @@ void InitializeDebugGLBindings() {
InitializeDebugGLBindingsWGL();
}
+void ClearGLBindings() {
+ ClearGLBindingsEGL();
+ ClearGLBindingsGL();
+ ClearGLBindingsOSMESA();
+ ClearGLBindingsWGL();
+ SetGLImplementation(kGLImplementationNone);
+
+ UnloadGLNativeLibraries();
+ UnloadD3DXLibraries(NULL);
+}
+
} // namespace gfx
diff --git a/ui/gfx/gl/gl_surface.cc b/ui/gfx/gl/gl_surface.cc
index 7ada5eb8..34d4464 100644
--- a/ui/gfx/gl/gl_surface.cc
+++ b/ui/gfx/gl/gl_surface.cc
@@ -4,10 +4,15 @@
#include "ui/gfx/gl/gl_surface.h"
+#include <algorithm>
+#include <vector>
+
+#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/threading/thread_local.h"
#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/gl/gl_implementation.h"
namespace gfx {
@@ -18,6 +23,55 @@ base::LazyInstance<
current_surface_(base::LINKER_INITIALIZED);
} // namespace
+// static
+bool GLSurface::InitializeOneOff() {
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+ std::vector<GLImplementation> allowed_impls;
+ GetAllowedGLImplementations(&allowed_impls);
+ DCHECK(!allowed_impls.empty());
+
+ // The default implementation is always the first one in list.
+ GLImplementation impl = allowed_impls[0];
+ bool fallback_to_osmesa = false;
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) {
+ std::string requested_implementation_name =
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL);
+ if (requested_implementation_name == "any") {
+ fallback_to_osmesa = true;
+ } else if (requested_implementation_name == "swiftshader") {
+ impl = kGLImplementationEGLGLES2;
+ } else {
+ impl = GetNamedGLImplementation(requested_implementation_name);
+ if (std::find(allowed_impls.begin(),
+ allowed_impls.end(),
+ impl) == allowed_impls.end()) {
+ LOG(ERROR) << "Requested GL implementation is not available.";
+ return false;
+ }
+ }
+ }
+
+ initialized = InitializeGLBindings(impl) && InitializeOneOffInternal();
+ if (!initialized && fallback_to_osmesa) {
+ ClearGLBindings();
+ initialized = InitializeGLBindings(kGLImplementationOSMesaGL) &&
+ InitializeOneOffInternal();
+ }
+
+ if (initialized) {
+ DVLOG(1) << "Using "
+ << GetGLImplementationName(GetGLImplementation())
+ << " GL implementation.";
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableGPUServiceLogging))
+ InitializeDebugGLBindings();
+ }
+ return initialized;
+}
+
GLSurface::GLSurface() {
}
diff --git a/ui/gfx/gl/gl_surface.h b/ui/gfx/gl/gl_surface.h
index 6cc3e22..5843a9c 100644
--- a/ui/gfx/gl/gl_surface.h
+++ b/ui/gfx/gl/gl_surface.h
@@ -88,6 +88,7 @@ class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> {
protected:
virtual ~GLSurface();
+ static bool InitializeOneOffInternal();
static void SetCurrent(GLSurface* surface);
private:
diff --git a/ui/gfx/gl/gl_surface_linux.cc b/ui/gfx/gl/gl_surface_linux.cc
index 86cc2ec..3abb81c 100644
--- a/ui/gfx/gl/gl_surface_linux.cc
+++ b/ui/gfx/gl/gl_surface_linux.cc
@@ -48,25 +48,7 @@ class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa);
};
-bool GLSurface::InitializeOneOff() {
- static bool initialized = false;
- if (initialized)
- return true;
-
- static const GLImplementation kAllowedGLImplementations[] = {
- kGLImplementationDesktopGL,
- kGLImplementationEGLGLES2,
- kGLImplementationOSMesaGL
- };
-
- if (!InitializeRequestedGLBindings(
- kAllowedGLImplementations,
- kAllowedGLImplementations + arraysize(kAllowedGLImplementations),
- kGLImplementationDesktopGL)) {
- LOG(ERROR) << "InitializeRequestedGLBindings failed.";
- return false;
- }
-
+bool GLSurface::InitializeOneOffInternal() {
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL:
if (!GLSurfaceGLX::InitializeOneOff()) {
@@ -90,7 +72,6 @@ bool GLSurface::InitializeOneOff() {
break;
}
- initialized = true;
return true;
}
diff --git a/ui/gfx/gl/gl_surface_mac.cc b/ui/gfx/gl/gl_surface_mac.cc
index 1a60be2..0f6cdd4 100644
--- a/ui/gfx/gl/gl_surface_mac.cc
+++ b/ui/gfx/gl/gl_surface_mac.cc
@@ -15,24 +15,7 @@
namespace gfx {
-bool GLSurface::InitializeOneOff() {
- static bool initialized = false;
- if (initialized)
- return true;
-
- static const GLImplementation kAllowedGLImplementations[] = {
- kGLImplementationDesktopGL,
- kGLImplementationOSMesaGL
- };
-
- if (!InitializeRequestedGLBindings(
- kAllowedGLImplementations,
- kAllowedGLImplementations + arraysize(kAllowedGLImplementations),
- kGLImplementationDesktopGL)) {
- LOG(ERROR) << "InitializeRequestedGLBindings failed.";
- return false;
- }
-
+bool GLSurface::InitializeOneOffInternal() {
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL:
if (!GLSurfaceCGL::InitializeOneOff()) {
@@ -43,8 +26,6 @@ bool GLSurface::InitializeOneOff() {
default:
break;
}
-
- initialized = true;
return true;
}
diff --git a/ui/gfx/gl/gl_surface_wgl.cc b/ui/gfx/gl/gl_surface_wgl.cc
index 9c774d4..49a628f 100644
--- a/ui/gfx/gl/gl_surface_wgl.cc
+++ b/ui/gfx/gl/gl_surface_wgl.cc
@@ -6,15 +6,10 @@
#include "base/logging.h"
#include "ui/gfx/gl/gl_bindings.h"
-#include "ui/gfx/gl/gl_implementation.h"
namespace gfx {
-static ATOM g_class_registration;
-static HWND g_window;
-HDC g_display_dc;
-static int g_pixel_format = 0;
-
+namespace {
const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = {
sizeof(kPixelFormatDescriptor), // Size of structure.
1, // Default version.
@@ -35,10 +30,10 @@ const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = {
0, 0, 0, // Layer masks ignored.
};
-static LRESULT CALLBACK IntermediateWindowProc(HWND window,
- UINT message,
- WPARAM w_param,
- LPARAM l_param) {
+LRESULT CALLBACK IntermediateWindowProc(HWND window,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
switch (message) {
case WM_ERASEBKGND:
// Prevent windows from erasing the background.
@@ -54,6 +49,98 @@ static LRESULT CALLBACK IntermediateWindowProc(HWND window,
}
}
+class DisplayWGL {
+ public:
+ DisplayWGL()
+ : module_handle_(0),
+ window_class_(0),
+ window_handle_(0),
+ device_context_(0),
+ pixel_format_(0) {
+ }
+
+ ~DisplayWGL() {
+ if (window_handle_)
+ DestroyWindow(window_handle_);
+ if (window_class_)
+ UnregisterClass(reinterpret_cast<wchar_t*>(window_class_),
+ module_handle_);
+ }
+
+ bool Init() {
+ // We must initialize a GL context before we can bind to extension entry
+ // points. This requires the device context for a window.
+ if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ reinterpret_cast<wchar_t*>(IntermediateWindowProc),
+ &module_handle_)) {
+ LOG(ERROR) << "GetModuleHandleEx failed.";
+ return false;
+ }
+
+ WNDCLASS intermediate_class;
+ intermediate_class.style = CS_OWNDC;
+ intermediate_class.lpfnWndProc = IntermediateWindowProc;
+ intermediate_class.cbClsExtra = 0;
+ intermediate_class.cbWndExtra = 0;
+ intermediate_class.hInstance = module_handle_;
+ intermediate_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ intermediate_class.hCursor = LoadCursor(NULL, IDC_ARROW);
+ intermediate_class.hbrBackground = NULL;
+ intermediate_class.lpszMenuName = NULL;
+ intermediate_class.lpszClassName = L"Intermediate GL Window";
+ window_class_ = RegisterClass(&intermediate_class);
+ if (!window_class_) {
+ LOG(ERROR) << "RegisterClass failed.";
+ return false;
+ }
+
+ window_handle_ = CreateWindow(
+ reinterpret_cast<wchar_t*>(window_class_),
+ L"",
+ WS_OVERLAPPEDWINDOW,
+ 0, 0,
+ 100, 100,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (!window_handle_) {
+ LOG(ERROR) << "CreateWindow failed.";
+ return false;
+ }
+
+ device_context_ = GetDC(window_handle_);
+ pixel_format_ = ChoosePixelFormat(device_context_,
+ &kPixelFormatDescriptor);
+ if (pixel_format_ == 0) {
+ LOG(ERROR) << "Unable to get the pixel format for GL context.";
+ return false;
+ }
+ if (!SetPixelFormat(device_context_,
+ pixel_format_,
+ &kPixelFormatDescriptor)) {
+ LOG(ERROR) << "Unable to set the pixel format for temporary GL context.";
+ return false;
+ }
+
+ return true;
+ }
+
+ ATOM window_class() const { return window_class_; }
+ HDC device_context() const { return device_context_; }
+ int pixel_format() const { return pixel_format_; }
+
+ private:
+ HINSTANCE module_handle_;
+ ATOM window_class_;
+ HWND window_handle_;
+ HDC device_context_;
+ int pixel_format_;
+};
+DisplayWGL* g_display;
+} // namespace
+
GLSurfaceWGL::GLSurfaceWGL() {
}
@@ -61,7 +148,7 @@ GLSurfaceWGL::~GLSurfaceWGL() {
}
void* GLSurfaceWGL::GetDisplay() {
- return g_display_dc;
+ return GetDisplayDC();
}
bool GLSurfaceWGL::InitializeOneOff() {
@@ -69,105 +156,20 @@ bool GLSurfaceWGL::InitializeOneOff() {
if (initialized)
return true;
- // We must initialize a GL context before we can bind to extension entry
- // points. This requires the device context for a window.
- HINSTANCE module_handle;
- if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
- GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- reinterpret_cast<wchar_t*>(IntermediateWindowProc),
- &module_handle)) {
- LOG(ERROR) << "GetModuleHandleEx failed.";
- return false;
- }
-
- WNDCLASS intermediate_class;
- intermediate_class.style = CS_OWNDC;
- intermediate_class.lpfnWndProc = IntermediateWindowProc;
- intermediate_class.cbClsExtra = 0;
- intermediate_class.cbWndExtra = 0;
- intermediate_class.hInstance = module_handle;
- intermediate_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- intermediate_class.hCursor = LoadCursor(NULL, IDC_ARROW);
- intermediate_class.hbrBackground = NULL;
- intermediate_class.lpszMenuName = NULL;
- intermediate_class.lpszClassName = L"Intermediate GL Window";
-
- g_class_registration = ::RegisterClass(&intermediate_class);
- if (!g_class_registration) {
- LOG(ERROR) << "RegisterClass failed.";
- return false;
- }
-
- g_window = CreateWindow(
- reinterpret_cast<wchar_t*>(g_class_registration),
- L"",
- WS_OVERLAPPEDWINDOW,
- 0, 0,
- 100, 100,
- NULL,
- NULL,
- NULL,
- NULL);
-
- if (!g_window) {
- UnregisterClass(reinterpret_cast<wchar_t*>(g_class_registration),
- module_handle);
- LOG(ERROR) << "CreateWindow failed.";
+ DCHECK(g_display == NULL);
+ g_display = new DisplayWGL;
+ if (!g_display->Init()) {
+ delete g_display;
+ g_display = NULL;
return false;
}
- g_display_dc = GetDC(g_window);
-
- g_pixel_format = ChoosePixelFormat(g_display_dc,
- &kPixelFormatDescriptor);
-
- if (g_pixel_format == 0) {
- LOG(ERROR) << "Unable to get the pixel format for GL context.";
- UnregisterClass(reinterpret_cast<wchar_t*>(g_class_registration),
- module_handle);
- return false;
- }
-
- if (!SetPixelFormat(g_display_dc,
- g_pixel_format,
- &kPixelFormatDescriptor)) {
- LOG(ERROR) << "Unable to set the pixel format for temporary GL context.";
- UnregisterClass(reinterpret_cast<wchar_t*>(g_class_registration),
- module_handle);
- return false;
- }
-
- // Create a temporary GL context to bind to extension entry points.
- HGLRC gl_context = wglCreateContext(g_display_dc);
- if (!gl_context) {
- LOG(ERROR) << "Failed to create temporary context.";
- UnregisterClass(reinterpret_cast<wchar_t*>(g_class_registration),
- module_handle);
- return false;
- }
-
- if (!wglMakeCurrent(g_display_dc, gl_context)) {
- LOG(ERROR) << "Failed to make temporary GL context current.";
- wglDeleteContext(gl_context);
- UnregisterClass(reinterpret_cast<wchar_t*>(g_class_registration),
- module_handle);
- return false;
- }
-
- // Get bindings to extension functions that cannot be acquired without a
- // current context.
- InitializeGLBindingsGL();
- InitializeGLBindingsWGL();
-
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(gl_context);
-
initialized = true;
return true;
}
HDC GLSurfaceWGL::GetDisplayDC() {
- return g_display_dc;
+ return g_display->device_context();
}
NativeViewGLSurfaceWGL::NativeViewGLSurfaceWGL(gfx::PluginWindowHandle window)
@@ -194,7 +196,7 @@ bool NativeViewGLSurfaceWGL::Initialize() {
// Create a child window. WGL has problems using a window handle owned by
// another process.
child_window_ = CreateWindow(
- reinterpret_cast<wchar_t*>(g_class_registration),
+ reinterpret_cast<wchar_t*>(g_display->window_class()),
L"",
WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE,
0, 0,
@@ -219,7 +221,7 @@ bool NativeViewGLSurfaceWGL::Initialize() {
}
if (!SetPixelFormat(device_context_,
- g_pixel_format,
+ g_display->pixel_format(),
&kPixelFormatDescriptor)) {
LOG(ERROR) << "Unable to set the pixel format for GL context.";
Destroy();
@@ -293,8 +295,8 @@ bool PbufferGLSurfaceWGL::Initialize() {
}
const int kNoAttributes[] = { 0 };
- pbuffer_ = wglCreatePbufferARB(g_display_dc,
- g_pixel_format,
+ pbuffer_ = wglCreatePbufferARB(g_display->device_context(),
+ g_display->pixel_format(),
size_.width(), size_.height(),
kNoAttributes);
diff --git a/ui/gfx/gl/gl_surface_win.cc b/ui/gfx/gl/gl_surface_win.cc
index 77810af..e6abf55 100644
--- a/ui/gfx/gl/gl_surface_win.cc
+++ b/ui/gfx/gl/gl_surface_win.cc
@@ -42,25 +42,7 @@ class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
// Helper routine that does one-off initialization like determining the
// pixel format and initializing the GL bindings.
-bool GLSurface::InitializeOneOff() {
- static bool initialized = false;
- if (initialized)
- return true;
-
- static const GLImplementation kAllowedGLImplementations[] = {
- kGLImplementationEGLGLES2,
- kGLImplementationDesktopGL,
- kGLImplementationOSMesaGL
- };
-
- if (!InitializeRequestedGLBindings(
- kAllowedGLImplementations,
- kAllowedGLImplementations + arraysize(kAllowedGLImplementations),
- kGLImplementationEGLGLES2)) {
- LOG(ERROR) << "InitializeRequestedGLBindings failed.";
- return false;
- }
-
+bool GLSurface::InitializeOneOffInternal() {
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL:
if (!GLSurfaceWGL::InitializeOneOff()) {
@@ -75,8 +57,6 @@ bool GLSurface::InitializeOneOff() {
}
break;
}
-
- initialized = true;
return true;
}