diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-26 12:08:50 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-10-04 10:18:31 +0200 |
commit | 8a4ccf23faef731d04e4099afe513da30cc38f21 (patch) | |
tree | d46e29f066a5ff271dff6c5f88aaeba15810b82d /chromium/ui | |
parent | 048f48ceb9e7ee6e2cad198a71afed47a392139b (diff) | |
download | qtwebengine-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.gn | 9 | ||||
-rwxr-xr-x | chromium/ui/gl/generate_bindings.py | 68 | ||||
-rw-r--r-- | chromium/ui/gl/gl_bindings.cc | 14 | ||||
-rw-r--r-- | chromium/ui/gl/gl_bindings.h | 23 | ||||
-rw-r--r-- | chromium/ui/gl/gl_bindings_autogen_wgl.cc | 506 | ||||
-rw-r--r-- | chromium/ui/gl/gl_bindings_autogen_wgl.h | 160 | ||||
-rw-r--r-- | chromium/ui/gl/gl_context_wgl.cc | 158 | ||||
-rw-r--r-- | chromium/ui/gl/gl_context_wgl.h | 43 | ||||
-rw-r--r-- | chromium/ui/gl/gl_implementation.cc | 4 | ||||
-rw-r--r-- | chromium/ui/gl/gl_surface_wgl.cc | 433 | ||||
-rw-r--r-- | chromium/ui/gl/gl_surface_wgl.h | 95 | ||||
-rw-r--r-- | chromium/ui/gl/gl_wgl_api_implementation.cc | 145 | ||||
-rw-r--r-- | chromium/ui/gl/gl_wgl_api_implementation.h | 90 | ||||
-rw-r--r-- | chromium/ui/gl/init/gl_factory_win.cc | 20 | ||||
-rw-r--r-- | chromium/ui/gl/init/gl_initializer_win.cc | 76 |
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 |