summaryrefslogtreecommitdiff
path: root/chromium/ui
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-11-26 12:08:50 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-04 10:18:31 +0200
commit8a4ccf23faef731d04e4099afe513da30cc38f21 (patch)
treed46e29f066a5ff271dff6c5f88aaeba15810b82d /chromium/ui
parent048f48ceb9e7ee6e2cad198a71afed47a392139b (diff)
downloadqtwebengine-chromium-8a4ccf23faef731d04e4099afe513da30cc38f21.tar.gz
[Revert] ui/gl: Remove WGL support on Windows
We still use it Change-Id: I4fbe6a55fcecdcd875c2a948170423d0c4380f5d Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/ui')
-rw-r--r--chromium/ui/gl/BUILD.gn9
-rwxr-xr-xchromium/ui/gl/generate_bindings.py68
-rw-r--r--chromium/ui/gl/gl_bindings.cc14
-rw-r--r--chromium/ui/gl/gl_bindings.h23
-rw-r--r--chromium/ui/gl/gl_bindings_autogen_wgl.cc506
-rw-r--r--chromium/ui/gl/gl_bindings_autogen_wgl.h160
-rw-r--r--chromium/ui/gl/gl_context_wgl.cc158
-rw-r--r--chromium/ui/gl/gl_context_wgl.h43
-rw-r--r--chromium/ui/gl/gl_implementation.cc4
-rw-r--r--chromium/ui/gl/gl_surface_wgl.cc433
-rw-r--r--chromium/ui/gl/gl_surface_wgl.h95
-rw-r--r--chromium/ui/gl/gl_wgl_api_implementation.cc145
-rw-r--r--chromium/ui/gl/gl_wgl_api_implementation.h90
-rw-r--r--chromium/ui/gl/init/gl_factory_win.cc20
-rw-r--r--chromium/ui/gl/init/gl_initializer_win.cc76
15 files changed, 1843 insertions, 1 deletions
diff --git a/chromium/ui/gl/BUILD.gn b/chromium/ui/gl/BUILD.gn
index 1c002f7482e..67cff458127 100644
--- a/chromium/ui/gl/BUILD.gn
+++ b/chromium/ui/gl/BUILD.gn
@@ -315,12 +315,20 @@ component("gl") {
"direct_composition_surface_win.h",
"gl_angle_util_win.cc",
"gl_angle_util_win.h",
+ "gl_bindings_autogen_wgl.cc",
+ "gl_bindings_autogen_wgl.h",
+ "gl_context_wgl.cc",
+ "gl_context_wgl.h",
"gl_fence_win.cc",
"gl_fence_win.h",
"gl_image_d3d.cc",
"gl_image_d3d.h",
"gl_image_dxgi.cc",
"gl_image_dxgi.h",
+ "gl_surface_wgl.cc",
+ "gl_surface_wgl.h",
+ "gl_wgl_api_implementation.cc",
+ "gl_wgl_api_implementation.h",
"hdr_metadata_helper_win.cc",
"hdr_metadata_helper_win.h",
"swap_chain_presenter.cc",
@@ -618,6 +626,7 @@ test("gl_unittests") {
"gl_image_d3d_unittest.cc",
"gl_image_dxgi_unittest.cc",
"hdr_metadata_helper_win_unittest.cc",
+ "wgl_api_unittest.cc",
]
}
diff --git a/chromium/ui/gl/generate_bindings.py b/chromium/ui/gl/generate_bindings.py
index 0713478139a..5d9b5ca6de8 100755
--- a/chromium/ui/gl/generate_bindings.py
+++ b/chromium/ui/gl/generate_bindings.py
@@ -22,6 +22,8 @@ HEADER_PATHS = [
]
UNCONDITIONALLY_BOUND_EXTENSIONS = set([
+ 'WGL_ARB_extensions_string',
+ 'WGL_EXT_extensions_string',
'GL_CHROMIUM_gles_depth_binding_hack', # crbug.com/448206
'GL_CHROMIUM_glgetstringi_hack', # crbug.com/470396
'GL_CHROMIUM_egl_khr_fence_sync_hack', # crbug.com/504758
@@ -2746,6 +2748,69 @@ EGL_FUNCTIONS = [
'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags' },
]
+WGL_FUNCTIONS = [
+{ 'return_type': 'BOOL',
+ 'names': ['wglChoosePixelFormatARB'],
+ 'arguments':
+ 'HDC dc, const int* int_attrib_list, const float* float_attrib_list, '
+ 'UINT max_formats, int* formats, UINT* num_formats', },
+{ 'return_type': 'BOOL',
+ 'names': ['wglCopyContext'],
+ 'arguments': 'HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask', },
+{ 'return_type': 'HGLRC',
+ 'names': ['wglCreateContext'],
+ 'arguments': 'HDC hdc', },
+{ 'return_type': 'HGLRC',
+ 'names': ['wglCreateContextAttribsARB'],
+ 'arguments': 'HDC hDC, HGLRC hShareContext, const int* attribList', },
+{ 'return_type': 'HGLRC',
+ 'names': ['wglCreateLayerContext'],
+ 'arguments': 'HDC hdc, int iLayerPlane', },
+{ 'return_type': 'HPBUFFERARB',
+ 'names': ['wglCreatePbufferARB'],
+ 'arguments': 'HDC hDC, int iPixelFormat, int iWidth, int iHeight, '
+ 'const int* piAttribList', },
+{ 'return_type': 'BOOL',
+ 'names': ['wglDeleteContext'],
+ 'arguments': 'HGLRC hglrc', },
+{ 'return_type': 'BOOL',
+ 'names': ['wglDestroyPbufferARB'],
+ 'arguments': 'HPBUFFERARB hPbuffer', },
+{ 'return_type': 'HGLRC',
+ 'names': ['wglGetCurrentContext'],
+ 'arguments': '', },
+{ 'return_type': 'HDC',
+ 'names': ['wglGetCurrentDC'],
+ 'arguments': '', },
+{ 'return_type': 'const char*',
+ 'names': ['wglGetExtensionsStringARB'],
+ 'arguments': 'HDC hDC', },
+{ 'return_type': 'const char*',
+ 'names': ['wglGetExtensionsStringEXT'],
+ 'arguments': '', },
+{ 'return_type': 'HDC',
+ 'names': ['wglGetPbufferDCARB'],
+ 'arguments': 'HPBUFFERARB hPbuffer', },
+{ 'return_type': 'BOOL',
+ 'names': ['wglMakeCurrent'],
+ 'arguments': 'HDC hdc, HGLRC hglrc', },
+{ 'return_type': 'BOOL',
+ 'names': ['wglQueryPbufferARB'],
+ 'arguments': 'HPBUFFERARB hPbuffer, int iAttribute, int* piValue', },
+{ 'return_type': 'int',
+ 'names': ['wglReleasePbufferDCARB'],
+ 'arguments': 'HPBUFFERARB hPbuffer, HDC hDC', },
+{ 'return_type': 'BOOL',
+ 'names': ['wglShareLists'],
+ 'arguments': 'HGLRC hglrc1, HGLRC hglrc2', },
+{ 'return_type': 'BOOL',
+ 'names': ['wglSwapIntervalEXT'],
+ 'arguments': 'int interval', },
+{ 'return_type': 'BOOL',
+ 'names': ['wglSwapLayerBuffers'],
+ 'arguments': 'HDC hdc, UINT fuPlanes', },
+]
+
GLX_FUNCTIONS = [
{ 'return_type': 'void',
'names': ['glXBindTexImageEXT'],
@@ -2939,6 +3004,7 @@ FUNCTION_SETS = [
'EGL_ANGLE_surface_d3d_texture_2d_share_handle',
],
],
+ [WGL_FUNCTIONS, 'wgl', ['noninclude/GL/wglext.h'], []],
[GLX_FUNCTIONS, 'glx', ['GL/glx.h', 'noninclude/GL/glxext.h'], []],
]
@@ -3739,7 +3805,7 @@ def ParseFunctionsFromHeader(header_file, extensions, versions):
version_start = re.compile(
r'#ifndef GL_(ES_|)VERSION((?:_[0-9])+)$')
extension_start = re.compile(
- r'#ifndef ((?:GL|EGL|GLX)_[A-Z]+_[a-zA-Z]\w+)')
+ r'#ifndef ((?:GL|EGL|WGL|GLX)_[A-Z]+_[a-zA-Z]\w+)')
extension_function = re.compile(r'.+\s+([a-z]+\w+)\s*\(')
typedef = re.compile(r'typedef .*')
macro_start = re.compile(r'^#(if|ifdef|ifndef).*')
diff --git a/chromium/ui/gl/gl_bindings.cc b/chromium/ui/gl/gl_bindings.cc
index 9890e646398..14a074e8b48 100644
--- a/chromium/ui/gl/gl_bindings.cc
+++ b/chromium/ui/gl/gl_bindings.cc
@@ -15,12 +15,26 @@
#include "ui/gfx/x/glx.h"
#endif
+#if defined(OS_WIN)
+#include "ui/gl/gl_surface_wgl.h"
+#endif
+
#if defined(USE_EGL)
#include "ui/gl/gl_surface_egl.h"
#endif
namespace gl {
+#if defined(OS_WIN)
+std::string DriverWGL::GetPlatformExtensions() {
+ const char* str = nullptr;
+ str = wglGetExtensionsStringARB(GLSurfaceWGL::GetDisplayDC());
+ if (str)
+ return str;
+ return wglGetExtensionsStringEXT();
+}
+#endif
+
#if defined(USE_EGL)
#if !defined(TOOLKIT_QT)
std::string DriverEGL::GetPlatformExtensions() {
diff --git a/chromium/ui/gl/gl_bindings.h b/chromium/ui/gl/gl_bindings.h
index acb2581aa20..d06155f64b4 100644
--- a/chromium/ui/gl/gl_bindings.h
+++ b/chromium/ui/gl/gl_bindings.h
@@ -532,6 +532,10 @@ typedef void (APIENTRY *EGLDEBUGPROCKHR)(
#include "gl_bindings_autogen_egl.h"
#endif
+#if defined(OS_WIN)
+#include "gl_bindings_autogen_wgl.h"
+#endif
+
#if defined(USE_GLX)
#include "gl_bindings_autogen_glx.h"
#endif
@@ -561,6 +565,20 @@ struct GL_EXPORT CurrentGL {
const GLVersionInfo* Version = nullptr;
};
+#if defined(OS_WIN)
+struct GL_EXPORT DriverWGL {
+ void InitializeStaticBindings();
+ void InitializeExtensionBindings();
+ void ClearBindings();
+
+ ProcsWGL fn;
+ ExtensionsWGL ext;
+
+ private:
+ static std::string GetPlatformExtensions();
+};
+#endif
+
#if defined(USE_EGL)
struct GL_EXPORT DriverEGL {
void InitializeStaticBindings();
@@ -602,6 +620,11 @@ GL_EXPORT extern EGLApi* g_current_egl_context;
GL_EXPORT extern DriverEGL g_driver_egl;
#endif
+#if defined(OS_WIN)
+GL_EXPORT extern WGLApi* g_current_wgl_context;
+GL_EXPORT extern DriverWGL g_driver_wgl;
+#endif
+
#if defined(USE_GLX)
GL_EXPORT extern GLXApi* g_current_glx_context;
GL_EXPORT extern DriverGLX g_driver_glx;
diff --git a/chromium/ui/gl/gl_bindings_autogen_wgl.cc b/chromium/ui/gl/gl_bindings_autogen_wgl.cc
new file mode 100644
index 00000000000..d76f0f43aab
--- /dev/null
+++ b/chromium/ui/gl/gl_bindings_autogen_wgl.cc
@@ -0,0 +1,506 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This file is auto-generated from
+// ui/gl/generate_bindings.py
+// It's formatted by clang-format using chromium coding style:
+// clang-format -i -style=chromium filename
+// DO NOT EDIT!
+
+#include <string>
+
+#include "base/trace_event/trace_event.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_enums.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_version_info.h"
+#include "ui/gl/gl_wgl_api_implementation.h"
+
+namespace gl {
+
+DriverWGL g_driver_wgl; // Exists in .bss
+
+void DriverWGL::InitializeStaticBindings() {
+ // Ensure struct has been zero-initialized.
+ char* this_bytes = reinterpret_cast<char*>(this);
+ DCHECK(this_bytes[0] == 0);
+ DCHECK(memcmp(this_bytes, this_bytes + 1, sizeof(*this) - 1) == 0);
+
+ fn.wglCopyContextFn =
+ reinterpret_cast<wglCopyContextProc>(GetGLProcAddress("wglCopyContext"));
+ fn.wglCreateContextFn = reinterpret_cast<wglCreateContextProc>(
+ GetGLProcAddress("wglCreateContext"));
+ fn.wglCreateLayerContextFn = reinterpret_cast<wglCreateLayerContextProc>(
+ GetGLProcAddress("wglCreateLayerContext"));
+ fn.wglDeleteContextFn = reinterpret_cast<wglDeleteContextProc>(
+ GetGLProcAddress("wglDeleteContext"));
+ fn.wglGetCurrentContextFn = reinterpret_cast<wglGetCurrentContextProc>(
+ GetGLProcAddress("wglGetCurrentContext"));
+ fn.wglGetCurrentDCFn = reinterpret_cast<wglGetCurrentDCProc>(
+ GetGLProcAddress("wglGetCurrentDC"));
+ fn.wglGetExtensionsStringARBFn =
+ reinterpret_cast<wglGetExtensionsStringARBProc>(
+ GetGLProcAddress("wglGetExtensionsStringARB"));
+ fn.wglGetExtensionsStringEXTFn =
+ reinterpret_cast<wglGetExtensionsStringEXTProc>(
+ GetGLProcAddress("wglGetExtensionsStringEXT"));
+ fn.wglMakeCurrentFn =
+ reinterpret_cast<wglMakeCurrentProc>(GetGLProcAddress("wglMakeCurrent"));
+ fn.wglShareListsFn =
+ reinterpret_cast<wglShareListsProc>(GetGLProcAddress("wglShareLists"));
+ fn.wglSwapLayerBuffersFn = reinterpret_cast<wglSwapLayerBuffersProc>(
+ GetGLProcAddress("wglSwapLayerBuffers"));
+}
+
+void DriverWGL::InitializeExtensionBindings() {
+ std::string platform_extensions(GetPlatformExtensions());
+ gfx::ExtensionSet extensions(gfx::MakeExtensionSet(platform_extensions));
+ ALLOW_UNUSED_LOCAL(extensions);
+
+ ext.b_WGL_ARB_create_context =
+ gfx::HasExtension(extensions, "WGL_ARB_create_context");
+ ext.b_WGL_ARB_extensions_string =
+ gfx::HasExtension(extensions, "WGL_ARB_extensions_string");
+ ext.b_WGL_ARB_pbuffer = gfx::HasExtension(extensions, "WGL_ARB_pbuffer");
+ ext.b_WGL_ARB_pixel_format =
+ gfx::HasExtension(extensions, "WGL_ARB_pixel_format");
+ ext.b_WGL_EXT_extensions_string =
+ gfx::HasExtension(extensions, "WGL_EXT_extensions_string");
+ ext.b_WGL_EXT_swap_control =
+ gfx::HasExtension(extensions, "WGL_EXT_swap_control");
+
+ if (ext.b_WGL_ARB_pixel_format) {
+ fn.wglChoosePixelFormatARBFn =
+ reinterpret_cast<wglChoosePixelFormatARBProc>(
+ GetGLProcAddress("wglChoosePixelFormatARB"));
+ }
+
+ if (ext.b_WGL_ARB_create_context) {
+ fn.wglCreateContextAttribsARBFn =
+ reinterpret_cast<wglCreateContextAttribsARBProc>(
+ GetGLProcAddress("wglCreateContextAttribsARB"));
+ }
+
+ if (ext.b_WGL_ARB_pbuffer) {
+ fn.wglCreatePbufferARBFn = reinterpret_cast<wglCreatePbufferARBProc>(
+ GetGLProcAddress("wglCreatePbufferARB"));
+ }
+
+ if (ext.b_WGL_ARB_pbuffer) {
+ fn.wglDestroyPbufferARBFn = reinterpret_cast<wglDestroyPbufferARBProc>(
+ GetGLProcAddress("wglDestroyPbufferARB"));
+ }
+
+ if (ext.b_WGL_ARB_pbuffer) {
+ fn.wglGetPbufferDCARBFn = reinterpret_cast<wglGetPbufferDCARBProc>(
+ GetGLProcAddress("wglGetPbufferDCARB"));
+ }
+
+ if (ext.b_WGL_ARB_pbuffer) {
+ fn.wglQueryPbufferARBFn = reinterpret_cast<wglQueryPbufferARBProc>(
+ GetGLProcAddress("wglQueryPbufferARB"));
+ }
+
+ if (ext.b_WGL_ARB_pbuffer) {
+ fn.wglReleasePbufferDCARBFn = reinterpret_cast<wglReleasePbufferDCARBProc>(
+ GetGLProcAddress("wglReleasePbufferDCARB"));
+ }
+
+ if (ext.b_WGL_EXT_swap_control) {
+ fn.wglSwapIntervalEXTFn = reinterpret_cast<wglSwapIntervalEXTProc>(
+ GetGLProcAddress("wglSwapIntervalEXT"));
+ }
+}
+
+void DriverWGL::ClearBindings() {
+ memset(this, 0, sizeof(*this));
+}
+
+BOOL WGLApiBase::wglChoosePixelFormatARBFn(HDC dc,
+ const int* int_attrib_list,
+ const float* float_attrib_list,
+ UINT max_formats,
+ int* formats,
+ UINT* num_formats) {
+ return driver_->fn.wglChoosePixelFormatARBFn(dc, int_attrib_list,
+ float_attrib_list, max_formats,
+ formats, num_formats);
+}
+
+BOOL WGLApiBase::wglCopyContextFn(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) {
+ return driver_->fn.wglCopyContextFn(hglrcSrc, hglrcDst, mask);
+}
+
+HGLRC WGLApiBase::wglCreateContextFn(HDC hdc) {
+ return driver_->fn.wglCreateContextFn(hdc);
+}
+
+HGLRC WGLApiBase::wglCreateContextAttribsARBFn(HDC hDC,
+ HGLRC hShareContext,
+ const int* attribList) {
+ return driver_->fn.wglCreateContextAttribsARBFn(hDC, hShareContext,
+ attribList);
+}
+
+HGLRC WGLApiBase::wglCreateLayerContextFn(HDC hdc, int iLayerPlane) {
+ return driver_->fn.wglCreateLayerContextFn(hdc, iLayerPlane);
+}
+
+HPBUFFERARB WGLApiBase::wglCreatePbufferARBFn(HDC hDC,
+ int iPixelFormat,
+ int iWidth,
+ int iHeight,
+ const int* piAttribList) {
+ return driver_->fn.wglCreatePbufferARBFn(hDC, iPixelFormat, iWidth, iHeight,
+ piAttribList);
+}
+
+BOOL WGLApiBase::wglDeleteContextFn(HGLRC hglrc) {
+ return driver_->fn.wglDeleteContextFn(hglrc);
+}
+
+BOOL WGLApiBase::wglDestroyPbufferARBFn(HPBUFFERARB hPbuffer) {
+ return driver_->fn.wglDestroyPbufferARBFn(hPbuffer);
+}
+
+HGLRC WGLApiBase::wglGetCurrentContextFn() {
+ return driver_->fn.wglGetCurrentContextFn();
+}
+
+HDC WGLApiBase::wglGetCurrentDCFn() {
+ return driver_->fn.wglGetCurrentDCFn();
+}
+
+const char* WGLApiBase::wglGetExtensionsStringARBFn(HDC hDC) {
+ return driver_->fn.wglGetExtensionsStringARBFn(hDC);
+}
+
+const char* WGLApiBase::wglGetExtensionsStringEXTFn() {
+ return driver_->fn.wglGetExtensionsStringEXTFn();
+}
+
+HDC WGLApiBase::wglGetPbufferDCARBFn(HPBUFFERARB hPbuffer) {
+ return driver_->fn.wglGetPbufferDCARBFn(hPbuffer);
+}
+
+BOOL WGLApiBase::wglMakeCurrentFn(HDC hdc, HGLRC hglrc) {
+ return driver_->fn.wglMakeCurrentFn(hdc, hglrc);
+}
+
+BOOL WGLApiBase::wglQueryPbufferARBFn(HPBUFFERARB hPbuffer,
+ int iAttribute,
+ int* piValue) {
+ return driver_->fn.wglQueryPbufferARBFn(hPbuffer, iAttribute, piValue);
+}
+
+int WGLApiBase::wglReleasePbufferDCARBFn(HPBUFFERARB hPbuffer, HDC hDC) {
+ return driver_->fn.wglReleasePbufferDCARBFn(hPbuffer, hDC);
+}
+
+BOOL WGLApiBase::wglShareListsFn(HGLRC hglrc1, HGLRC hglrc2) {
+ return driver_->fn.wglShareListsFn(hglrc1, hglrc2);
+}
+
+BOOL WGLApiBase::wglSwapIntervalEXTFn(int interval) {
+ return driver_->fn.wglSwapIntervalEXTFn(interval);
+}
+
+BOOL WGLApiBase::wglSwapLayerBuffersFn(HDC hdc, UINT fuPlanes) {
+ return driver_->fn.wglSwapLayerBuffersFn(hdc, fuPlanes);
+}
+
+BOOL TraceWGLApi::wglChoosePixelFormatARBFn(HDC dc,
+ const int* int_attrib_list,
+ const float* float_attrib_list,
+ UINT max_formats,
+ int* formats,
+ UINT* num_formats) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglChoosePixelFormatARB")
+ return wgl_api_->wglChoosePixelFormatARBFn(dc, int_attrib_list,
+ float_attrib_list, max_formats,
+ formats, num_formats);
+}
+
+BOOL TraceWGLApi::wglCopyContextFn(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglCopyContext")
+ return wgl_api_->wglCopyContextFn(hglrcSrc, hglrcDst, mask);
+}
+
+HGLRC TraceWGLApi::wglCreateContextFn(HDC hdc) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglCreateContext")
+ return wgl_api_->wglCreateContextFn(hdc);
+}
+
+HGLRC TraceWGLApi::wglCreateContextAttribsARBFn(HDC hDC,
+ HGLRC hShareContext,
+ const int* attribList) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu",
+ "TraceWGLAPI::wglCreateContextAttribsARB")
+ return wgl_api_->wglCreateContextAttribsARBFn(hDC, hShareContext, attribList);
+}
+
+HGLRC TraceWGLApi::wglCreateLayerContextFn(HDC hdc, int iLayerPlane) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglCreateLayerContext")
+ return wgl_api_->wglCreateLayerContextFn(hdc, iLayerPlane);
+}
+
+HPBUFFERARB TraceWGLApi::wglCreatePbufferARBFn(HDC hDC,
+ int iPixelFormat,
+ int iWidth,
+ int iHeight,
+ const int* piAttribList) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglCreatePbufferARB")
+ return wgl_api_->wglCreatePbufferARBFn(hDC, iPixelFormat, iWidth, iHeight,
+ piAttribList);
+}
+
+BOOL TraceWGLApi::wglDeleteContextFn(HGLRC hglrc) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglDeleteContext")
+ return wgl_api_->wglDeleteContextFn(hglrc);
+}
+
+BOOL TraceWGLApi::wglDestroyPbufferARBFn(HPBUFFERARB hPbuffer) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglDestroyPbufferARB")
+ return wgl_api_->wglDestroyPbufferARBFn(hPbuffer);
+}
+
+HGLRC TraceWGLApi::wglGetCurrentContextFn() {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglGetCurrentContext")
+ return wgl_api_->wglGetCurrentContextFn();
+}
+
+HDC TraceWGLApi::wglGetCurrentDCFn() {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglGetCurrentDC")
+ return wgl_api_->wglGetCurrentDCFn();
+}
+
+const char* TraceWGLApi::wglGetExtensionsStringARBFn(HDC hDC) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglGetExtensionsStringARB")
+ return wgl_api_->wglGetExtensionsStringARBFn(hDC);
+}
+
+const char* TraceWGLApi::wglGetExtensionsStringEXTFn() {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglGetExtensionsStringEXT")
+ return wgl_api_->wglGetExtensionsStringEXTFn();
+}
+
+HDC TraceWGLApi::wglGetPbufferDCARBFn(HPBUFFERARB hPbuffer) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglGetPbufferDCARB")
+ return wgl_api_->wglGetPbufferDCARBFn(hPbuffer);
+}
+
+BOOL TraceWGLApi::wglMakeCurrentFn(HDC hdc, HGLRC hglrc) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglMakeCurrent")
+ return wgl_api_->wglMakeCurrentFn(hdc, hglrc);
+}
+
+BOOL TraceWGLApi::wglQueryPbufferARBFn(HPBUFFERARB hPbuffer,
+ int iAttribute,
+ int* piValue) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglQueryPbufferARB")
+ return wgl_api_->wglQueryPbufferARBFn(hPbuffer, iAttribute, piValue);
+}
+
+int TraceWGLApi::wglReleasePbufferDCARBFn(HPBUFFERARB hPbuffer, HDC hDC) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglReleasePbufferDCARB")
+ return wgl_api_->wglReleasePbufferDCARBFn(hPbuffer, hDC);
+}
+
+BOOL TraceWGLApi::wglShareListsFn(HGLRC hglrc1, HGLRC hglrc2) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglShareLists")
+ return wgl_api_->wglShareListsFn(hglrc1, hglrc2);
+}
+
+BOOL TraceWGLApi::wglSwapIntervalEXTFn(int interval) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglSwapIntervalEXT")
+ return wgl_api_->wglSwapIntervalEXTFn(interval);
+}
+
+BOOL TraceWGLApi::wglSwapLayerBuffersFn(HDC hdc, UINT fuPlanes) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceWGLAPI::wglSwapLayerBuffers")
+ return wgl_api_->wglSwapLayerBuffersFn(hdc, fuPlanes);
+}
+
+BOOL LogWGLApi::wglChoosePixelFormatARBFn(HDC dc,
+ const int* int_attrib_list,
+ const float* float_attrib_list,
+ UINT max_formats,
+ int* formats,
+ UINT* num_formats) {
+ GL_SERVICE_LOG("wglChoosePixelFormatARB"
+ << "(" << dc << ", "
+ << static_cast<const void*>(int_attrib_list) << ", "
+ << static_cast<const void*>(float_attrib_list) << ", "
+ << max_formats << ", " << static_cast<const void*>(formats)
+ << ", " << static_cast<const void*>(num_formats) << ")");
+ BOOL result = wgl_api_->wglChoosePixelFormatARBFn(
+ dc, int_attrib_list, float_attrib_list, max_formats, formats,
+ num_formats);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+BOOL LogWGLApi::wglCopyContextFn(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) {
+ GL_SERVICE_LOG("wglCopyContext"
+ << "(" << hglrcSrc << ", " << hglrcDst << ", " << mask << ")");
+ BOOL result = wgl_api_->wglCopyContextFn(hglrcSrc, hglrcDst, mask);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+HGLRC LogWGLApi::wglCreateContextFn(HDC hdc) {
+ GL_SERVICE_LOG("wglCreateContext"
+ << "(" << hdc << ")");
+ HGLRC result = wgl_api_->wglCreateContextFn(hdc);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+HGLRC LogWGLApi::wglCreateContextAttribsARBFn(HDC hDC,
+ HGLRC hShareContext,
+ const int* attribList) {
+ GL_SERVICE_LOG("wglCreateContextAttribsARB"
+ << "(" << hDC << ", " << hShareContext << ", "
+ << static_cast<const void*>(attribList) << ")");
+ HGLRC result =
+ wgl_api_->wglCreateContextAttribsARBFn(hDC, hShareContext, attribList);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+HGLRC LogWGLApi::wglCreateLayerContextFn(HDC hdc, int iLayerPlane) {
+ GL_SERVICE_LOG("wglCreateLayerContext"
+ << "(" << hdc << ", " << iLayerPlane << ")");
+ HGLRC result = wgl_api_->wglCreateLayerContextFn(hdc, iLayerPlane);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+HPBUFFERARB LogWGLApi::wglCreatePbufferARBFn(HDC hDC,
+ int iPixelFormat,
+ int iWidth,
+ int iHeight,
+ const int* piAttribList) {
+ GL_SERVICE_LOG("wglCreatePbufferARB"
+ << "(" << hDC << ", " << iPixelFormat << ", " << iWidth << ", "
+ << iHeight << ", " << static_cast<const void*>(piAttribList)
+ << ")");
+ HPBUFFERARB result = wgl_api_->wglCreatePbufferARBFn(
+ hDC, iPixelFormat, iWidth, iHeight, piAttribList);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+BOOL LogWGLApi::wglDeleteContextFn(HGLRC hglrc) {
+ GL_SERVICE_LOG("wglDeleteContext"
+ << "(" << hglrc << ")");
+ BOOL result = wgl_api_->wglDeleteContextFn(hglrc);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+BOOL LogWGLApi::wglDestroyPbufferARBFn(HPBUFFERARB hPbuffer) {
+ GL_SERVICE_LOG("wglDestroyPbufferARB"
+ << "(" << hPbuffer << ")");
+ BOOL result = wgl_api_->wglDestroyPbufferARBFn(hPbuffer);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+HGLRC LogWGLApi::wglGetCurrentContextFn() {
+ GL_SERVICE_LOG("wglGetCurrentContext"
+ << "("
+ << ")");
+ HGLRC result = wgl_api_->wglGetCurrentContextFn();
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+HDC LogWGLApi::wglGetCurrentDCFn() {
+ GL_SERVICE_LOG("wglGetCurrentDC"
+ << "("
+ << ")");
+ HDC result = wgl_api_->wglGetCurrentDCFn();
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+const char* LogWGLApi::wglGetExtensionsStringARBFn(HDC hDC) {
+ GL_SERVICE_LOG("wglGetExtensionsStringARB"
+ << "(" << hDC << ")");
+ const char* result = wgl_api_->wglGetExtensionsStringARBFn(hDC);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+const char* LogWGLApi::wglGetExtensionsStringEXTFn() {
+ GL_SERVICE_LOG("wglGetExtensionsStringEXT"
+ << "("
+ << ")");
+ const char* result = wgl_api_->wglGetExtensionsStringEXTFn();
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+HDC LogWGLApi::wglGetPbufferDCARBFn(HPBUFFERARB hPbuffer) {
+ GL_SERVICE_LOG("wglGetPbufferDCARB"
+ << "(" << hPbuffer << ")");
+ HDC result = wgl_api_->wglGetPbufferDCARBFn(hPbuffer);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+BOOL LogWGLApi::wglMakeCurrentFn(HDC hdc, HGLRC hglrc) {
+ GL_SERVICE_LOG("wglMakeCurrent"
+ << "(" << hdc << ", " << hglrc << ")");
+ BOOL result = wgl_api_->wglMakeCurrentFn(hdc, hglrc);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+BOOL LogWGLApi::wglQueryPbufferARBFn(HPBUFFERARB hPbuffer,
+ int iAttribute,
+ int* piValue) {
+ GL_SERVICE_LOG("wglQueryPbufferARB"
+ << "(" << hPbuffer << ", " << iAttribute << ", "
+ << static_cast<const void*>(piValue) << ")");
+ BOOL result = wgl_api_->wglQueryPbufferARBFn(hPbuffer, iAttribute, piValue);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+int LogWGLApi::wglReleasePbufferDCARBFn(HPBUFFERARB hPbuffer, HDC hDC) {
+ GL_SERVICE_LOG("wglReleasePbufferDCARB"
+ << "(" << hPbuffer << ", " << hDC << ")");
+ int result = wgl_api_->wglReleasePbufferDCARBFn(hPbuffer, hDC);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+BOOL LogWGLApi::wglShareListsFn(HGLRC hglrc1, HGLRC hglrc2) {
+ GL_SERVICE_LOG("wglShareLists"
+ << "(" << hglrc1 << ", " << hglrc2 << ")");
+ BOOL result = wgl_api_->wglShareListsFn(hglrc1, hglrc2);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+BOOL LogWGLApi::wglSwapIntervalEXTFn(int interval) {
+ GL_SERVICE_LOG("wglSwapIntervalEXT"
+ << "(" << interval << ")");
+ BOOL result = wgl_api_->wglSwapIntervalEXTFn(interval);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+BOOL LogWGLApi::wglSwapLayerBuffersFn(HDC hdc, UINT fuPlanes) {
+ GL_SERVICE_LOG("wglSwapLayerBuffers"
+ << "(" << hdc << ", " << fuPlanes << ")");
+ BOOL result = wgl_api_->wglSwapLayerBuffersFn(hdc, fuPlanes);
+ GL_SERVICE_LOG("GL_RESULT: " << result);
+ return result;
+}
+
+} // namespace gl
diff --git a/chromium/ui/gl/gl_bindings_autogen_wgl.h b/chromium/ui/gl/gl_bindings_autogen_wgl.h
new file mode 100644
index 00000000000..c6b787d395f
--- /dev/null
+++ b/chromium/ui/gl/gl_bindings_autogen_wgl.h
@@ -0,0 +1,160 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This file is auto-generated from
+// ui/gl/generate_bindings.py
+// It's formatted by clang-format using chromium coding style:
+// clang-format -i -style=chromium filename
+// DO NOT EDIT!
+
+#ifndef UI_GL_GL_BINDINGS_AUTOGEN_WGL_H_
+#define UI_GL_GL_BINDINGS_AUTOGEN_WGL_H_
+
+#include <string>
+
+namespace gl {
+
+class GLContext;
+
+typedef BOOL(GL_BINDING_CALL* wglChoosePixelFormatARBProc)(
+ HDC dc,
+ const int* int_attrib_list,
+ const float* float_attrib_list,
+ UINT max_formats,
+ int* formats,
+ UINT* num_formats);
+typedef BOOL(GL_BINDING_CALL* wglCopyContextProc)(HGLRC hglrcSrc,
+ HGLRC hglrcDst,
+ UINT mask);
+typedef HGLRC(GL_BINDING_CALL* wglCreateContextProc)(HDC hdc);
+typedef HGLRC(GL_BINDING_CALL* wglCreateContextAttribsARBProc)(
+ HDC hDC,
+ HGLRC hShareContext,
+ const int* attribList);
+typedef HGLRC(GL_BINDING_CALL* wglCreateLayerContextProc)(HDC hdc,
+ int iLayerPlane);
+typedef HPBUFFERARB(GL_BINDING_CALL* wglCreatePbufferARBProc)(
+ HDC hDC,
+ int iPixelFormat,
+ int iWidth,
+ int iHeight,
+ const int* piAttribList);
+typedef BOOL(GL_BINDING_CALL* wglDeleteContextProc)(HGLRC hglrc);
+typedef BOOL(GL_BINDING_CALL* wglDestroyPbufferARBProc)(HPBUFFERARB hPbuffer);
+typedef HGLRC(GL_BINDING_CALL* wglGetCurrentContextProc)();
+typedef HDC(GL_BINDING_CALL* wglGetCurrentDCProc)();
+typedef const char*(GL_BINDING_CALL* wglGetExtensionsStringARBProc)(HDC hDC);
+typedef const char*(GL_BINDING_CALL* wglGetExtensionsStringEXTProc)();
+typedef HDC(GL_BINDING_CALL* wglGetPbufferDCARBProc)(HPBUFFERARB hPbuffer);
+typedef BOOL(GL_BINDING_CALL* wglMakeCurrentProc)(HDC hdc, HGLRC hglrc);
+typedef BOOL(GL_BINDING_CALL* wglQueryPbufferARBProc)(HPBUFFERARB hPbuffer,
+ int iAttribute,
+ int* piValue);
+typedef int(GL_BINDING_CALL* wglReleasePbufferDCARBProc)(HPBUFFERARB hPbuffer,
+ HDC hDC);
+typedef BOOL(GL_BINDING_CALL* wglShareListsProc)(HGLRC hglrc1, HGLRC hglrc2);
+typedef BOOL(GL_BINDING_CALL* wglSwapIntervalEXTProc)(int interval);
+typedef BOOL(GL_BINDING_CALL* wglSwapLayerBuffersProc)(HDC hdc, UINT fuPlanes);
+
+struct ExtensionsWGL {
+ bool b_WGL_ARB_create_context;
+ bool b_WGL_ARB_extensions_string;
+ bool b_WGL_ARB_pbuffer;
+ bool b_WGL_ARB_pixel_format;
+ bool b_WGL_EXT_extensions_string;
+ bool b_WGL_EXT_swap_control;
+};
+
+struct ProcsWGL {
+ wglChoosePixelFormatARBProc wglChoosePixelFormatARBFn;
+ wglCopyContextProc wglCopyContextFn;
+ wglCreateContextProc wglCreateContextFn;
+ wglCreateContextAttribsARBProc wglCreateContextAttribsARBFn;
+ wglCreateLayerContextProc wglCreateLayerContextFn;
+ wglCreatePbufferARBProc wglCreatePbufferARBFn;
+ wglDeleteContextProc wglDeleteContextFn;
+ wglDestroyPbufferARBProc wglDestroyPbufferARBFn;
+ wglGetCurrentContextProc wglGetCurrentContextFn;
+ wglGetCurrentDCProc wglGetCurrentDCFn;
+ wglGetExtensionsStringARBProc wglGetExtensionsStringARBFn;
+ wglGetExtensionsStringEXTProc wglGetExtensionsStringEXTFn;
+ wglGetPbufferDCARBProc wglGetPbufferDCARBFn;
+ wglMakeCurrentProc wglMakeCurrentFn;
+ wglQueryPbufferARBProc wglQueryPbufferARBFn;
+ wglReleasePbufferDCARBProc wglReleasePbufferDCARBFn;
+ wglShareListsProc wglShareListsFn;
+ wglSwapIntervalEXTProc wglSwapIntervalEXTFn;
+ wglSwapLayerBuffersProc wglSwapLayerBuffersFn;
+};
+
+class GL_EXPORT WGLApi {
+ public:
+ WGLApi();
+ virtual ~WGLApi();
+
+ virtual void SetDisabledExtensions(const std::string& disabled_extensions) {}
+
+ virtual BOOL wglChoosePixelFormatARBFn(HDC dc,
+ const int* int_attrib_list,
+ const float* float_attrib_list,
+ UINT max_formats,
+ int* formats,
+ UINT* num_formats) = 0;
+ virtual BOOL wglCopyContextFn(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) = 0;
+ virtual HGLRC wglCreateContextFn(HDC hdc) = 0;
+ virtual HGLRC wglCreateContextAttribsARBFn(HDC hDC,
+ HGLRC hShareContext,
+ const int* attribList) = 0;
+ virtual HGLRC wglCreateLayerContextFn(HDC hdc, int iLayerPlane) = 0;
+ virtual HPBUFFERARB wglCreatePbufferARBFn(HDC hDC,
+ int iPixelFormat,
+ int iWidth,
+ int iHeight,
+ const int* piAttribList) = 0;
+ virtual BOOL wglDeleteContextFn(HGLRC hglrc) = 0;
+ virtual BOOL wglDestroyPbufferARBFn(HPBUFFERARB hPbuffer) = 0;
+ virtual HGLRC wglGetCurrentContextFn() = 0;
+ virtual HDC wglGetCurrentDCFn() = 0;
+ virtual const char* wglGetExtensionsStringARBFn(HDC hDC) = 0;
+ virtual const char* wglGetExtensionsStringEXTFn() = 0;
+ virtual HDC wglGetPbufferDCARBFn(HPBUFFERARB hPbuffer) = 0;
+ virtual BOOL wglMakeCurrentFn(HDC hdc, HGLRC hglrc) = 0;
+ virtual BOOL wglQueryPbufferARBFn(HPBUFFERARB hPbuffer,
+ int iAttribute,
+ int* piValue) = 0;
+ virtual int wglReleasePbufferDCARBFn(HPBUFFERARB hPbuffer, HDC hDC) = 0;
+ virtual BOOL wglShareListsFn(HGLRC hglrc1, HGLRC hglrc2) = 0;
+ virtual BOOL wglSwapIntervalEXTFn(int interval) = 0;
+ virtual BOOL wglSwapLayerBuffersFn(HDC hdc, UINT fuPlanes) = 0;
+};
+
+} // namespace gl
+
+#define wglChoosePixelFormatARB \
+ ::gl::g_current_wgl_context->wglChoosePixelFormatARBFn
+#define wglCopyContext ::gl::g_current_wgl_context->wglCopyContextFn
+#define wglCreateContext ::gl::g_current_wgl_context->wglCreateContextFn
+#define wglCreateContextAttribsARB \
+ ::gl::g_current_wgl_context->wglCreateContextAttribsARBFn
+#define wglCreateLayerContext \
+ ::gl::g_current_wgl_context->wglCreateLayerContextFn
+#define wglCreatePbufferARB ::gl::g_current_wgl_context->wglCreatePbufferARBFn
+#define wglDeleteContext ::gl::g_current_wgl_context->wglDeleteContextFn
+#define wglDestroyPbufferARB ::gl::g_current_wgl_context->wglDestroyPbufferARBFn
+#define wglGetCurrentContext ::gl::g_current_wgl_context->wglGetCurrentContextFn
+#define wglGetCurrentDC ::gl::g_current_wgl_context->wglGetCurrentDCFn
+#define wglGetExtensionsStringARB \
+ ::gl::g_current_wgl_context->wglGetExtensionsStringARBFn
+#define wglGetExtensionsStringEXT \
+ ::gl::g_current_wgl_context->wglGetExtensionsStringEXTFn
+#define wglGetPbufferDCARB ::gl::g_current_wgl_context->wglGetPbufferDCARBFn
+#define wglMakeCurrent ::gl::g_current_wgl_context->wglMakeCurrentFn
+#define wglQueryPbufferARB ::gl::g_current_wgl_context->wglQueryPbufferARBFn
+#define wglReleasePbufferDCARB \
+ ::gl::g_current_wgl_context->wglReleasePbufferDCARBFn
+#define wglShareLists ::gl::g_current_wgl_context->wglShareListsFn
+#define wglSwapIntervalEXT ::gl::g_current_wgl_context->wglSwapIntervalEXTFn
+#define wglSwapLayerBuffers ::gl::g_current_wgl_context->wglSwapLayerBuffersFn
+
+#endif // UI_GL_GL_BINDINGS_AUTOGEN_WGL_H_
diff --git a/chromium/ui/gl/gl_context_wgl.cc b/chromium/ui/gl/gl_context_wgl.cc
new file mode 100644
index 00000000000..9e9633a496b
--- /dev/null
+++ b/chromium/ui/gl/gl_context_wgl.cc
@@ -0,0 +1,158 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file implements the GLContextWGL and PbufferGLContext classes.
+
+#include "ui/gl/gl_context_wgl.h"
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/trace_event/trace_event.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_surface_wgl.h"
+
+namespace gl {
+
+GLContextWGL::GLContextWGL(GLShareGroup* share_group)
+ : GLContextReal(share_group), context_(nullptr) {
+}
+
+bool GLContextWGL::Initialize(GLSurface* compatible_surface,
+ const GLContextAttribs& attribs) {
+ // webgl_compatibility_context and disabling bind_generates_resource are not
+ // supported.
+ DCHECK(!attribs.webgl_compatibility_context &&
+ attribs.bind_generates_resource);
+
+ // Get the handle of another initialized context in the share group _before_
+ // setting context_. Otherwise this context will be considered initialized
+ // and could potentially be returned by GetHandle.
+ HGLRC share_handle = static_cast<HGLRC>(share_group()->GetHandle());
+
+ HDC device_context = static_cast<HDC>(compatible_surface->GetHandle());
+ bool has_wgl_create_context_arb =
+ strstr(wglGetExtensionsStringARB(device_context),
+ "WGL_ARB_create_context") != nullptr;
+ bool create_core_profile = has_wgl_create_context_arb &&
+ !base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableES3GLContext);
+
+ if (create_core_profile) {
+ std::pair<int, int> attempt_versions[] = {
+ {4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0}, {3, 3}, {3, 2},
+ };
+
+ for (const auto& version : attempt_versions) {
+ const int attribs[] = {
+ WGL_CONTEXT_MAJOR_VERSION_ARB,
+ version.first,
+ WGL_CONTEXT_MINOR_VERSION_ARB,
+ version.second,
+ WGL_CONTEXT_PROFILE_MASK_ARB,
+ WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+ 0,
+ 0,
+ };
+
+ context_ =
+ wglCreateContextAttribsARB(device_context, share_handle, attribs);
+ if (context_) {
+ break;
+ }
+ }
+ }
+
+ if (!context_) {
+ context_ = wglCreateContext(device_context);
+ }
+ if (!context_) {
+ LOG(ERROR) << "Failed to create GL context.";
+ Destroy();
+ return false;
+ }
+
+ if (share_handle) {
+ if (!wglShareLists(share_handle, context_)) {
+ LOG(ERROR) << "Could not share GL contexts.";
+ Destroy();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void GLContextWGL::Destroy() {
+ if (context_) {
+ wglDeleteContext(context_);
+ context_ = nullptr;
+ }
+}
+
+bool GLContextWGL::MakeCurrentImpl(GLSurface* surface) {
+ DCHECK(context_);
+ if (IsCurrent(surface))
+ return true;
+
+ ScopedReleaseCurrent release_current;
+ TRACE_EVENT0("gpu", "GLContextWGL::MakeCurrent");
+
+ if (!wglMakeCurrent(static_cast<HDC>(surface->GetHandle()), context_)) {
+ LOG(ERROR) << "Unable to make gl context current.";
+ return false;
+ }
+
+ // Set this as soon as the context is current, since we might call into GL.
+ BindGLApi();
+
+ SetCurrent(surface);
+ InitializeDynamicBindings();
+
+ if (!surface->OnMakeCurrent(this)) {
+ LOG(ERROR) << "Could not make current.";
+ return false;
+ }
+
+ release_current.Cancel();
+ return true;
+}
+
+void GLContextWGL::ReleaseCurrent(GLSurface* surface) {
+ if (!IsCurrent(surface))
+ return;
+
+ SetCurrent(nullptr);
+ wglMakeCurrent(nullptr, nullptr);
+}
+
+bool GLContextWGL::IsCurrent(GLSurface* surface) {
+ bool native_context_is_current =
+ wglGetCurrentContext() == context_;
+
+ // If our context is current then our notion of which GLContext is
+ // current must be correct. On the other hand, third-party code
+ // using OpenGL might change the current context.
+ DCHECK(!native_context_is_current || (GetRealCurrent() == this));
+
+ if (!native_context_is_current)
+ return false;
+
+ if (surface) {
+ if (wglGetCurrentDC() != surface->GetHandle())
+ return false;
+ }
+
+ return true;
+}
+
+void* GLContextWGL::GetHandle() {
+ return context_;
+}
+
+GLContextWGL::~GLContextWGL() {
+ Destroy();
+}
+
+} // namespace gl
diff --git a/chromium/ui/gl/gl_context_wgl.h b/chromium/ui/gl/gl_context_wgl.h
new file mode 100644
index 00000000000..c792580efb2
--- /dev/null
+++ b/chromium/ui/gl/gl_context_wgl.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GL_GL_CONTEXT_WGL_H_
+#define UI_GL_GL_CONTEXT_WGL_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_export.h"
+
+namespace gl {
+
+class GLSurface;
+
+// This class is a wrapper around a GL context.
+class GL_EXPORT GLContextWGL : public GLContextReal {
+ public:
+ explicit GLContextWGL(GLShareGroup* share_group);
+
+ // Implement GLContext.
+ bool Initialize(GLSurface* compatible_surface,
+ const GLContextAttribs& attribs) override;
+ bool MakeCurrentImpl(GLSurface* surface) override;
+ void ReleaseCurrent(GLSurface* surface) override;
+ bool IsCurrent(GLSurface* surface) override;
+ void* GetHandle() override;
+
+ private:
+ ~GLContextWGL() override;
+ void Destroy();
+
+ HGLRC context_;
+
+ DISALLOW_COPY_AND_ASSIGN(GLContextWGL);
+};
+
+} // namespace gl
+
+#endif // UI_GL_GL_CONTEXT_WGL_H_
diff --git a/chromium/ui/gl/gl_implementation.cc b/chromium/ui/gl/gl_implementation.cc
index fd3ed002e16..81195cbf209 100644
--- a/chromium/ui/gl/gl_implementation.cc
+++ b/chromium/ui/gl/gl_implementation.cc
@@ -161,6 +161,10 @@ base::ThreadLocalPointer<CurrentGL>* g_current_gl_context_tls = NULL;
EGLApi* g_current_egl_context;
#endif
+#if defined(OS_WIN)
+WGLApi* g_current_wgl_context;
+#endif
+
#if defined(USE_GLX)
GLXApi* g_current_glx_context;
#endif
diff --git a/chromium/ui/gl/gl_surface_wgl.cc b/chromium/ui/gl/gl_surface_wgl.cc
new file mode 100644
index 00000000000..0bce93b5134
--- /dev/null
+++ b/chromium/ui/gl/gl_surface_wgl.cc
@@ -0,0 +1,433 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gl/gl_surface_wgl.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/logging.h"
+#include "base/trace_event/trace_event.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_gl_api_implementation.h"
+#include "ui/gl/gl_wgl_api_implementation.h"
+
+namespace gl {
+
+namespace {
+const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = {
+ sizeof(kPixelFormatDescriptor), // Size of structure.
+ 1, // Default version.
+ PFD_DRAW_TO_WINDOW | // Window drawing support.
+ PFD_SUPPORT_OPENGL | // OpenGL support.
+ PFD_DOUBLEBUFFER, // Double buffering support (not stereo).
+ PFD_TYPE_RGBA, // RGBA color mode (not indexed).
+ 24, // 24 bit color mode.
+ 0, 0, 0, 0, 0, 0, // Don't set RGB bits & shifts.
+ 8, 0, // 8 bit alpha
+ 0, // No accumulation buffer.
+ 0, 0, 0, 0, // Ignore accumulation bits.
+ 0, // no z-buffer.
+ 0, // no stencil buffer.
+ 0, // No aux buffer.
+ PFD_MAIN_PLANE, // Main drawing plane (not overlay).
+ 0, // Reserved.
+ 0, 0, 0, // Layer masks ignored.
+};
+
+LRESULT CALLBACK IntermediateWindowProc(HWND window,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ switch (message) {
+ case WM_ERASEBKGND:
+ // Prevent windows from erasing the background.
+ return 1;
+ case WM_PAINT:
+ // Do not paint anything.
+ PAINTSTRUCT paint;
+ if (BeginPaint(window, &paint))
+ EndPaint(window, &paint);
+ return 0;
+ default:
+ return DefWindowProc(window, message, w_param, l_param);
+ }
+}
+
+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_ = CreateWindowEx(WS_EX_NOPARENTNOTIFY,
+ 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_wgl_display;
+} // namespace
+
+// static
+bool GLSurfaceWGL::initialized_ = false;
+
+GLSurfaceWGL::GLSurfaceWGL() {
+}
+
+GLSurfaceWGL::~GLSurfaceWGL() {
+}
+
+void* GLSurfaceWGL::GetDisplay() {
+ return GetDisplayDC();
+}
+
+// static
+bool GLSurfaceWGL::InitializeOneOff() {
+ if (initialized_)
+ return true;
+
+ DCHECK(g_wgl_display == NULL);
+ std::unique_ptr<DisplayWGL> wgl_display(new DisplayWGL);
+ if (!wgl_display->Init())
+ return false;
+
+ g_wgl_display = wgl_display.release();
+ initialized_ = true;
+ return true;
+}
+
+// static
+bool GLSurfaceWGL::InitializeExtensionSettingsOneOff() {
+ if (!initialized_)
+ return false;
+ g_driver_wgl.InitializeExtensionBindings();
+ return true;
+}
+
+void GLSurfaceWGL::InitializeOneOffForTesting() {
+ if (g_wgl_display == NULL) {
+ g_wgl_display = new DisplayWGL;
+ }
+}
+
+HDC GLSurfaceWGL::GetDisplayDC() {
+ return g_wgl_display->device_context();
+}
+
+NativeViewGLSurfaceWGL::NativeViewGLSurfaceWGL(gfx::AcceleratedWidget window)
+ : window_(window), child_window_(NULL), device_context_(NULL) {
+ DCHECK(window);
+}
+
+NativeViewGLSurfaceWGL::~NativeViewGLSurfaceWGL() {
+ Destroy();
+}
+
+bool NativeViewGLSurfaceWGL::Initialize(GLSurfaceFormat format) {
+ DCHECK(!device_context_);
+
+ RECT rect;
+ if (!GetClientRect(window_, &rect)) {
+ LOG(ERROR) << "GetClientRect failed.\n";
+ Destroy();
+ return false;
+ }
+
+ // Create a child window. WGL has problems using a window handle owned by
+ // another process.
+ child_window_ = CreateWindowEx(
+ WS_EX_NOPARENTNOTIFY,
+ reinterpret_cast<wchar_t*>(g_wgl_display->window_class()), L"",
+ WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, 0, 0, rect.right - rect.left,
+ rect.bottom - rect.top, window_, NULL, NULL, NULL);
+ if (!child_window_) {
+ LOG(ERROR) << "CreateWindow failed.\n";
+ Destroy();
+ return false;
+ }
+
+ // The GL context will render to this window.
+ device_context_ = GetDC(child_window_);
+ if (!device_context_) {
+ LOG(ERROR) << "Unable to get device context for window.";
+ Destroy();
+ return false;
+ }
+
+ if (!SetPixelFormat(device_context_, g_wgl_display->pixel_format(),
+ &kPixelFormatDescriptor)) {
+ LOG(ERROR) << "Unable to set the pixel format for GL context.";
+ Destroy();
+ return false;
+ }
+
+ format_ = format;
+
+ return true;
+}
+
+void NativeViewGLSurfaceWGL::Destroy() {
+ if (child_window_ && device_context_)
+ ReleaseDC(child_window_, device_context_);
+
+ if (child_window_)
+ DestroyWindow(child_window_);
+
+ child_window_ = NULL;
+ device_context_ = NULL;
+}
+
+bool NativeViewGLSurfaceWGL::Resize(const gfx::Size& size,
+ float scale_factor,
+ const gfx::ColorSpace& color_space,
+ bool has_alpha) {
+ RECT rect;
+ if (!GetClientRect(window_, &rect)) {
+ LOG(ERROR) << "Failed to get parent window size.";
+ return false;
+ }
+ DCHECK(size.width() == (rect.right - rect.left) &&
+ size.height() == (rect.bottom - rect.top));
+ if (!MoveWindow(child_window_, 0, 0, size.width(), size.height(), FALSE)) {
+ LOG(ERROR) << "Failed to resize child window.";
+ return false;
+ }
+ return true;
+}
+
+bool NativeViewGLSurfaceWGL::Recreate() {
+ Destroy();
+ if (!Initialize(format_)) {
+ LOG(ERROR) << "Failed to create surface.";
+ return false;
+ }
+ return true;
+}
+
+bool NativeViewGLSurfaceWGL::IsOffscreen() {
+ return false;
+}
+
+gfx::SwapResult NativeViewGLSurfaceWGL::SwapBuffers(
+ PresentationCallback callback) {
+ // TODO(penghuang): Provide presentation feedback. https://crbug.com/776877
+ TRACE_EVENT2("gpu", "NativeViewGLSurfaceWGL:RealSwapBuffers",
+ "width", GetSize().width(),
+ "height", GetSize().height());
+
+ // Resize the child window to match the parent before swapping. Do not repaint
+ // it as it moves.
+ RECT rect;
+ if (!GetClientRect(window_, &rect))
+ return gfx::SwapResult::SWAP_FAILED;
+ if (!MoveWindow(child_window_,
+ 0,
+ 0,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ FALSE)) {
+ return gfx::SwapResult::SWAP_FAILED;
+ }
+
+ DCHECK(device_context_);
+ if (::SwapBuffers(device_context_) == TRUE) {
+ // TODO(penghuang): Provide more accurate values for presentation feedback.
+ constexpr int64_t kRefreshIntervalInMicroseconds =
+ base::Time::kMicrosecondsPerSecond / 60;
+ std::move(callback).Run(gfx::PresentationFeedback(
+ base::TimeTicks::Now(),
+ base::TimeDelta::FromMicroseconds(kRefreshIntervalInMicroseconds),
+ 0 /* flags */));
+ return gfx::SwapResult::SWAP_ACK;
+ } else {
+ std::move(callback).Run(gfx::PresentationFeedback::Failure());
+ return gfx::SwapResult::SWAP_FAILED;
+ }
+}
+
+gfx::Size NativeViewGLSurfaceWGL::GetSize() {
+ RECT rect;
+ BOOL result = GetClientRect(child_window_, &rect);
+ DCHECK(result);
+ return gfx::Size(rect.right - rect.left, rect.bottom - rect.top);
+}
+
+void* NativeViewGLSurfaceWGL::GetHandle() {
+ return device_context_;
+}
+
+GLSurfaceFormat NativeViewGLSurfaceWGL::GetFormat() {
+ return GLSurfaceFormat();
+}
+
+void NativeViewGLSurfaceWGL::SetVSyncEnabled(bool enabled) {
+ DCHECK(GLContext::GetCurrent() && GLContext::GetCurrent()->IsCurrent(this));
+ if (g_driver_wgl.ext.b_WGL_EXT_swap_control) {
+ wglSwapIntervalEXT(enabled ? 1 : 0);
+ } else {
+ LOG(WARNING) << "Could not disable vsync: driver does not "
+ "support WGL_EXT_swap_control";
+ }
+}
+
+PbufferGLSurfaceWGL::PbufferGLSurfaceWGL(const gfx::Size& size)
+ : size_(size),
+ device_context_(NULL),
+ pbuffer_(NULL) {
+ // Some implementations of Pbuffer do not support having a 0 size. For such
+ // cases use a (1, 1) surface.
+ if (size_.GetArea() == 0)
+ size_.SetSize(1, 1);
+}
+
+PbufferGLSurfaceWGL::~PbufferGLSurfaceWGL() {
+ Destroy();
+}
+
+bool PbufferGLSurfaceWGL::Initialize(GLSurfaceFormat format) {
+ DCHECK(!device_context_);
+
+ if (!g_driver_wgl.fn.wglCreatePbufferARBFn) {
+ LOG(ERROR) << "wglCreatePbufferARB not available.";
+ Destroy();
+ return false;
+ }
+
+ const int kNoAttributes[] = { 0 };
+ pbuffer_ = wglCreatePbufferARB(g_wgl_display->device_context(),
+ g_wgl_display->pixel_format(), size_.width(),
+ size_.height(), kNoAttributes);
+
+ if (!pbuffer_) {
+ LOG(ERROR) << "Unable to create pbuffer.";
+ Destroy();
+ return false;
+ }
+
+ device_context_ = wglGetPbufferDCARB(static_cast<HPBUFFERARB>(pbuffer_));
+ if (!device_context_) {
+ LOG(ERROR) << "Unable to get pbuffer device context.";
+ Destroy();
+ return false;
+ }
+
+ return true;
+}
+
+void PbufferGLSurfaceWGL::Destroy() {
+ if (pbuffer_ && device_context_)
+ wglReleasePbufferDCARB(static_cast<HPBUFFERARB>(pbuffer_), device_context_);
+
+ device_context_ = NULL;
+
+ if (pbuffer_) {
+ wglDestroyPbufferARB(static_cast<HPBUFFERARB>(pbuffer_));
+ pbuffer_ = NULL;
+ }
+}
+
+bool PbufferGLSurfaceWGL::IsOffscreen() {
+ return true;
+}
+
+gfx::SwapResult PbufferGLSurfaceWGL::SwapBuffers(
+ PresentationCallback callback) {
+ NOTREACHED() << "Attempted to call SwapBuffers on a pbuffer.";
+ return gfx::SwapResult::SWAP_FAILED;
+}
+
+gfx::Size PbufferGLSurfaceWGL::GetSize() {
+ return size_;
+}
+
+void* PbufferGLSurfaceWGL::GetHandle() {
+ return device_context_;
+}
+
+GLSurfaceFormat PbufferGLSurfaceWGL::GetFormat() {
+ return GLSurfaceFormat();
+}
+
+} // namespace gl
diff --git a/chromium/ui/gl/gl_surface_wgl.h b/chromium/ui/gl/gl_surface_wgl.h
new file mode 100644
index 00000000000..628b356ad42
--- /dev/null
+++ b/chromium/ui/gl/gl_surface_wgl.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GL_GL_SURFACE_WGL_H_
+#define UI_GL_GL_SURFACE_WGL_H_
+
+#include "base/macros.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gl/gl_export.h"
+#include "ui/gl/gl_surface.h"
+
+namespace gl {
+
+// Base interface for WGL surfaces.
+class GL_EXPORT GLSurfaceWGL : public GLSurface {
+ public:
+ GLSurfaceWGL();
+
+ // Implement GLSurface.
+ void* GetDisplay() override;
+
+ static bool InitializeOneOff();
+ static bool InitializeExtensionSettingsOneOff();
+ static void InitializeOneOffForTesting();
+ static HDC GetDisplayDC();
+
+ protected:
+ ~GLSurfaceWGL() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GLSurfaceWGL);
+ static bool initialized_;
+};
+
+// A surface used to render to a view.
+class GL_EXPORT NativeViewGLSurfaceWGL : public GLSurfaceWGL {
+ public:
+ explicit NativeViewGLSurfaceWGL(gfx::AcceleratedWidget window);
+
+ // Implement GLSurface.
+ bool Initialize(GLSurfaceFormat format) override;
+ void Destroy() override;
+ bool Resize(const gfx::Size& size,
+ float scale_factor,
+ const gfx::ColorSpace& color_space,
+ bool has_alpha) override;
+ bool Recreate() override;
+ bool IsOffscreen() override;
+ gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
+ gfx::Size GetSize() override;
+ void* GetHandle() override;
+ GLSurfaceFormat GetFormat() override;
+ void SetVSyncEnabled(bool enabled) override;
+
+ private:
+ ~NativeViewGLSurfaceWGL() override;
+
+ GLSurfaceFormat format_;
+
+ gfx::AcceleratedWidget window_;
+ gfx::AcceleratedWidget child_window_;
+ HDC device_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceWGL);
+};
+
+
+// A surface used to render to an offscreen pbuffer.
+class GL_EXPORT PbufferGLSurfaceWGL : public GLSurfaceWGL {
+ public:
+ explicit PbufferGLSurfaceWGL(const gfx::Size& size);
+
+ // Implement GLSurface.
+ bool Initialize(GLSurfaceFormat format) override;
+ void Destroy() override;
+ bool IsOffscreen() override;
+ gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
+ gfx::Size GetSize() override;
+ void* GetHandle() override;
+ GLSurfaceFormat GetFormat() override;
+
+ private:
+ ~PbufferGLSurfaceWGL() override;
+
+ gfx::Size size_;
+ HDC device_context_;
+ void* pbuffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PbufferGLSurfaceWGL);
+};
+
+} // namespace gl
+
+#endif // UI_GL_GL_SURFACE_WGL_H_
diff --git a/chromium/ui/gl/gl_wgl_api_implementation.cc b/chromium/ui/gl/gl_wgl_api_implementation.cc
new file mode 100644
index 00000000000..163310905b3
--- /dev/null
+++ b/chromium/ui/gl/gl_wgl_api_implementation.cc
@@ -0,0 +1,145 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gl/gl_wgl_api_implementation.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_implementation_wrapper.h"
+#include "ui/gl/gl_surface_wgl.h"
+
+namespace gl {
+
+RealWGLApi* g_real_wgl = nullptr;
+
+GL_IMPL_WRAPPER_TYPE(WGL) * g_wgl_wrapper = nullptr;
+
+void InitializeStaticGLBindingsWGL() {
+ g_driver_wgl.InitializeStaticBindings();
+ if (!g_wgl_wrapper) {
+ auto real_api = std::make_unique<RealWGLApi>();
+ real_api->Initialize(&g_driver_wgl);
+ g_wgl_wrapper = new GL_IMPL_WRAPPER_TYPE(WGL)(std::move(real_api));
+ }
+
+ g_current_wgl_context = g_wgl_wrapper->api();
+}
+
+void ClearBindingsWGL() {
+ delete g_wgl_wrapper;
+ g_wgl_wrapper = nullptr;
+
+ g_current_wgl_context = nullptr;
+ g_driver_wgl.ClearBindings();
+}
+
+WGLApi::WGLApi() {
+}
+
+WGLApi::~WGLApi() {
+}
+
+WGLApiBase::WGLApiBase() : driver_(nullptr) {}
+
+WGLApiBase::~WGLApiBase() {
+}
+
+void WGLApiBase::InitializeBase(DriverWGL* driver) {
+ driver_ = driver;
+}
+
+RealWGLApi::RealWGLApi() {
+}
+
+RealWGLApi::~RealWGLApi() {
+}
+
+void RealWGLApi::Initialize(DriverWGL* driver) {
+ InitializeBase(driver);
+}
+
+void RealWGLApi::SetDisabledExtensions(const std::string& disabled_extensions) {
+ disabled_exts_.clear();
+ filtered_ext_exts_ = "";
+ filtered_arb_exts_ = "";
+ if (!disabled_extensions.empty()) {
+ disabled_exts_ =
+ base::SplitString(disabled_extensions, ", ;",
+ base::KEEP_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY);
+ }
+}
+
+const char* RealWGLApi::wglGetExtensionsStringARBFn(HDC hDC) {
+ if (filtered_arb_exts_.size())
+ return filtered_arb_exts_.c_str();
+
+ if (!driver_->fn.wglGetExtensionsStringARBFn)
+ return nullptr;
+
+ const char* str = WGLApiBase::wglGetExtensionsStringARBFn(hDC);
+ if (!str)
+ return nullptr;
+
+ filtered_arb_exts_ = FilterGLExtensionList(str, disabled_exts_);
+ return filtered_arb_exts_.c_str();
+}
+
+const char* RealWGLApi::wglGetExtensionsStringEXTFn() {
+ if (filtered_ext_exts_.size())
+ return filtered_ext_exts_.c_str();
+
+ if (!driver_->fn.wglGetExtensionsStringEXTFn)
+ return nullptr;
+
+ const char* str = WGLApiBase::wglGetExtensionsStringEXTFn();
+ if (!str)
+ return nullptr;
+
+ filtered_ext_exts_ = FilterGLExtensionList(str, disabled_exts_);
+ return filtered_ext_exts_.c_str();
+}
+
+LogWGLApi::LogWGLApi(WGLApi* wgl_api) : wgl_api_(wgl_api) {}
+
+LogWGLApi::~LogWGLApi() {}
+
+void LogWGLApi::SetDisabledExtensions(const std::string& disabled_extensions) {
+ if (wgl_api_) {
+ wgl_api_->SetDisabledExtensions(disabled_extensions);
+ }
+}
+
+TraceWGLApi::~TraceWGLApi() {
+}
+
+void TraceWGLApi::SetDisabledExtensions(
+ const std::string& disabled_extensions) {
+ if (wgl_api_) {
+ wgl_api_->SetDisabledExtensions(disabled_extensions);
+ }
+}
+
+bool GetGLWindowSystemBindingInfoWGL(GLWindowSystemBindingInfo* info) {
+ const char* extensions = wglGetExtensionsStringEXT();
+ *info = GLWindowSystemBindingInfo();
+ if (extensions)
+ info->extensions = extensions;
+ return true;
+}
+
+void SetDisabledExtensionsWGL(const std::string& disabled_extensions) {
+ DCHECK(g_current_wgl_context);
+ DCHECK(GLContext::TotalGLContexts() == 0);
+ g_current_wgl_context->SetDisabledExtensions(disabled_extensions);
+}
+
+bool InitializeExtensionSettingsOneOffWGL() {
+ return GLSurfaceWGL::InitializeExtensionSettingsOneOff();
+}
+
+} // namespace gl
diff --git a/chromium/ui/gl/gl_wgl_api_implementation.h b/chromium/ui/gl/gl_wgl_api_implementation.h
new file mode 100644
index 00000000000..3bc8d65614c
--- /dev/null
+++ b/chromium/ui/gl/gl_wgl_api_implementation.h
@@ -0,0 +1,90 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GL_GL_WGL_API_IMPLEMENTATION_H_
+#define UI_GL_GL_WGL_API_IMPLEMENTATION_H_
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_export.h"
+
+namespace gl {
+
+struct GLWindowSystemBindingInfo;
+
+GL_EXPORT void InitializeStaticGLBindingsWGL();
+GL_EXPORT void ClearBindingsWGL();
+GL_EXPORT bool GetGLWindowSystemBindingInfoWGL(GLWindowSystemBindingInfo* info);
+GL_EXPORT void SetDisabledExtensionsWGL(const std::string& disabled_extensions);
+GL_EXPORT bool InitializeExtensionSettingsOneOffWGL();
+
+class GL_EXPORT WGLApiBase : public WGLApi {
+ public:
+ // Include the auto-generated part of this class. We split this because
+ // it means we can easily edit the non-auto generated parts right here in
+ // this file instead of having to edit some template or the code generator.
+ #include "gl_bindings_api_autogen_wgl.h"
+
+ protected:
+ WGLApiBase();
+ ~WGLApiBase() override;
+ void InitializeBase(DriverWGL* driver);
+
+ DriverWGL* driver_;
+};
+
+class GL_EXPORT RealWGLApi : public WGLApiBase {
+ public:
+ RealWGLApi();
+ ~RealWGLApi() override;
+ void Initialize(DriverWGL* driver);
+ void SetDisabledExtensions(const std::string& disabled_extensions) override;
+
+ const char* wglGetExtensionsStringARBFn(HDC hDC) override;
+ const char* wglGetExtensionsStringEXTFn() override;
+ private:
+
+ std::vector<std::string> disabled_exts_;
+ std::string filtered_arb_exts_;
+ std::string filtered_ext_exts_;
+};
+
+// Logs debug information for every WGL call.
+class GL_EXPORT LogWGLApi : public WGLApi {
+ public:
+ LogWGLApi(WGLApi* wgl_api);
+ ~LogWGLApi() override;
+ void SetDisabledExtensions(const std::string& disabled_extensions) override;
+
+ // Include the auto-generated part of this class. We split this because
+ // it means we can easily edit the non-auto generated parts right here in
+ // this file instead of having to edit some template or the code generator.
+ #include "gl_bindings_api_autogen_wgl.h"
+
+ private:
+ WGLApi* wgl_api_;
+};
+
+// Inserts a TRACE for every WGL call.
+class GL_EXPORT TraceWGLApi : public WGLApi {
+ public:
+ TraceWGLApi(WGLApi* wgl_api) : wgl_api_(wgl_api) { }
+ ~TraceWGLApi() override;
+ void SetDisabledExtensions(const std::string& disabled_extensions) override;
+
+ // Include the auto-generated part of this class. We split this because
+ // it means we can easily edit the non-auto generated parts right here in
+ // this file instead of having to edit some template or the code generator.
+ #include "gl_bindings_api_autogen_wgl.h"
+
+ private:
+ WGLApi* wgl_api_;
+};
+
+} // namespace gl
+
+#endif // UI_GL_GL_WGL_API_IMPLEMENTATION_H_
diff --git a/chromium/ui/gl/init/gl_factory_win.cc b/chromium/ui/gl/init/gl_factory_win.cc
index 109d564d22d..5d604b09a91 100644
--- a/chromium/ui/gl/init/gl_factory_win.cc
+++ b/chromium/ui/gl/init/gl_factory_win.cc
@@ -10,12 +10,15 @@
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_context_egl.h"
#include "ui/gl/gl_context_stub.h"
+#include "ui/gl/gl_context_wgl.h"
#include "ui/gl/gl_egl_api_implementation.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_share_group.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/gl_surface_stub.h"
+#include "ui/gl/gl_surface_wgl.h"
+#include "ui/gl/gl_wgl_api_implementation.h"
#include "ui/gl/vsync_provider_win.h"
namespace gl {
@@ -24,6 +27,7 @@ namespace init {
std::vector<GLImplementation> GetAllowedGLImplementations() {
std::vector<GLImplementation> impls;
impls.push_back(kGLImplementationEGLANGLE);
+ impls.push_back(kGLImplementationDesktopGL);
impls.push_back(kGLImplementationSwiftShaderGL);
return impls;
}
@@ -31,6 +35,8 @@ std::vector<GLImplementation> GetAllowedGLImplementations() {
bool GetGLWindowSystemBindingInfo(const GLVersionInfo& gl_info,
GLWindowSystemBindingInfo* info) {
switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL:
+ return GetGLWindowSystemBindingInfoWGL(info);
case kGLImplementationEGLANGLE:
return GetGLWindowSystemBindingInfoEGL(info);
default:
@@ -47,6 +53,9 @@ scoped_refptr<GLContext> CreateGLContext(GLShareGroup* share_group,
case kGLImplementationEGLANGLE:
return InitializeGLContext(new GLContextEGL(share_group),
compatible_surface, attribs);
+ case kGLImplementationDesktopGL:
+ return InitializeGLContext(new GLContextWGL(share_group),
+ compatible_surface, attribs);
case kGLImplementationMockGL:
return new GLContextStub(share_group);
case kGLImplementationStubGL: {
@@ -70,6 +79,9 @@ scoped_refptr<GLSurface> CreateViewGLSurface(gfx::AcceleratedWidget window) {
return InitializeGLSurface(base::MakeRefCounted<NativeViewGLSurfaceEGL>(
window, std::make_unique<VSyncProviderWin>(window)));
}
+ case kGLImplementationDesktopGL:
+ return InitializeGLSurface(
+ base::MakeRefCounted<NativeViewGLSurfaceWGL>(window));
case kGLImplementationMockGL:
case kGLImplementationStubGL:
return new GLSurfaceStub;
@@ -92,6 +104,9 @@ scoped_refptr<GLSurface> CreateOffscreenGLSurfaceWithFormat(
return InitializeGLSurfaceWithFormat(new PbufferGLSurfaceEGL(size),
format);
}
+ case kGLImplementationDesktopGL:
+ return InitializeGLSurfaceWithFormat(
+ new PbufferGLSurfaceWGL(size), format);
case kGLImplementationMockGL:
case kGLImplementationStubGL:
return new GLSurfaceStub;
@@ -106,6 +121,9 @@ void SetDisabledExtensionsPlatform(const std::string& disabled_extensions) {
GLImplementation implementation = GetGLImplementation();
DCHECK_NE(kGLImplementationNone, implementation);
switch (implementation) {
+ case kGLImplementationDesktopGL:
+ SetDisabledExtensionsWGL(disabled_extensions);
+ break;
case kGLImplementationEGLANGLE:
SetDisabledExtensionsEGL(disabled_extensions);
break;
@@ -122,6 +140,8 @@ bool InitializeExtensionSettingsOneOffPlatform() {
GLImplementation implementation = GetGLImplementation();
DCHECK_NE(kGLImplementationNone, implementation);
switch (implementation) {
+ case kGLImplementationDesktopGL:
+ return InitializeExtensionSettingsOneOffWGL();
case kGLImplementationEGLANGLE:
return InitializeExtensionSettingsOneOffEGL();
case kGLImplementationSwiftShaderGL:
diff --git a/chromium/ui/gl/init/gl_initializer_win.cc b/chromium/ui/gl/init/gl_initializer_win.cc
index c9ee4d4829f..e1a033c9efd 100644
--- a/chromium/ui/gl/init/gl_initializer_win.cc
+++ b/chromium/ui/gl/init/gl_initializer_win.cc
@@ -20,6 +20,8 @@
#include "ui/gl/gl_egl_api_implementation.h"
#include "ui/gl/gl_gl_api_implementation.h"
#include "ui/gl/gl_surface_egl.h"
+#include "ui/gl/gl_surface_wgl.h"
+#include "ui/gl/gl_wgl_api_implementation.h"
#include "ui/gl/vsync_provider_win.h"
namespace gl {
@@ -138,6 +140,71 @@ bool InitializeStaticEGLInternal(GLImplementationParts implementation) {
return true;
}
+bool InitializeStaticWGLInternal() {
+ base::NativeLibrary library =
+ base::LoadNativeLibrary(base::FilePath(L"opengl32.dll"), nullptr);
+ if (!library) {
+ DVLOG(1) << "opengl32.dll not found";
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(library,
+ "wglGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "wglGetProcAddress not found.";
+ base::UnloadNativeLibrary(library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(library);
+ SetGLImplementation(kGLImplementationDesktopGL);
+
+ // Initialize GL surface and get some functions needed for the context
+ // creation below.
+ if (!GLSurfaceWGL::InitializeOneOff()) {
+ LOG(ERROR) << "GLSurfaceWGL::InitializeOneOff failed.";
+ return false;
+ }
+ wglCreateContextProc wglCreateContextFn =
+ reinterpret_cast<wglCreateContextProc>(
+ GetGLProcAddress("wglCreateContext"));
+ wglDeleteContextProc wglDeleteContextFn =
+ reinterpret_cast<wglDeleteContextProc>(
+ GetGLProcAddress("wglDeleteContext"));
+ wglMakeCurrentProc wglMakeCurrentFn =
+ reinterpret_cast<wglMakeCurrentProc>(GetGLProcAddress("wglMakeCurrent"));
+
+ // Create a temporary GL context to bind to entry points. This is needed
+ // because wglGetProcAddress is specified to return nullptr 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 nullptr 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 = wglCreateContextFn(GLSurfaceWGL::GetDisplayDC());
+ if (!gl_context) {
+ LOG(ERROR) << "Failed to create temporary context.";
+ return false;
+ }
+ if (!wglMakeCurrentFn(GLSurfaceWGL::GetDisplayDC(), gl_context)) {
+ LOG(ERROR) << "Failed to make temporary GL context current.";
+ wglDeleteContextFn(gl_context);
+ return false;
+ }
+
+ InitializeStaticGLBindingsGL();
+ InitializeStaticGLBindingsWGL();
+
+ wglMakeCurrent(nullptr, nullptr);
+ wglDeleteContext(gl_context);
+
+ return true;
+}
+
} // namespace
#if !defined(TOOLKIT_QT)
@@ -145,6 +212,12 @@ bool InitializeGLOneOffPlatform() {
VSyncProviderWin::InitializeOneOff();
switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL:
+ if (!GLSurfaceWGL::InitializeOneOff()) {
+ LOG(ERROR) << "GLSurfaceWGL::InitializeOneOff failed.";
+ return false;
+ }
+ break;
case kGLImplementationSwiftShaderGL:
case kGLImplementationEGLANGLE:
if (!GLSurfaceEGL::InitializeOneOff(EGLDisplayPlatform(GetDC(nullptr)))) {
@@ -178,6 +251,8 @@ bool InitializeStaticGLBindings(GLImplementationParts implementation) {
case kGLImplementationSwiftShaderGL:
case kGLImplementationEGLANGLE:
return InitializeStaticEGLInternal(implementation);
+ case kGLImplementationDesktopGL:
+ return InitializeStaticWGLInternal();
case kGLImplementationMockGL:
case kGLImplementationStubGL:
SetGLImplementationParts(implementation);
@@ -194,6 +269,7 @@ void ShutdownGLPlatform() {
GLSurfaceEGL::ShutdownOneOff();
ClearBindingsEGL();
ClearBindingsGL();
+ ClearBindingsWGL();
}
} // namespace init