From ed15d7c193dea47b1a0c007bfe35d6277fb1c786 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 29 Aug 2022 17:00:37 -0400 Subject: [PATCH] OpenGL: Create ContextExternal for use without EGL Allows passing in appropriate callbacks for managing the OpenGL context, as opposed to relying on Dawn+EGL for OpenGL context management. --- include/dawn/native/OpenGLBackend.h | 4 ++ src/dawn/native/CMakeLists.txt | 2 + src/dawn/native/opengl/AdapterGL.cpp | 24 +++++++++--- src/dawn/native/opengl/AdapterGL.h | 9 ++++- src/dawn/native/opengl/BackendGL.cpp | 3 +- src/dawn/native/opengl/ContextExternal.cpp | 39 ++++++++++++++++++++ src/dawn/native/opengl/ContextExternal.h | 43 ++++++++++++++++++++++ src/dawn/native/opengl/OpenGLVersion.cpp | 8 ++++ 8 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 src/dawn/native/opengl/ContextExternal.cpp create mode 100644 src/dawn/native/opengl/ContextExternal.h diff --git a/include/dawn/native/OpenGLBackend.h b/include/dawn/native/OpenGLBackend.h index cceaab85e7..dfec71b9b5 100644 --- a/include/dawn/native/OpenGLBackend.h +++ b/include/dawn/native/OpenGLBackend.h @@ -26,6 +26,10 @@ struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptio explicit AdapterDiscoveryOptions(WGPUBackendType type); void* (*getProc)(const char*); + // Context + void (*makeCurrent)(void*); + void (*destroy)(void*); + void* userData; }; // TODO(crbug.com/dawn/810): This struct can be removed once Chrome is no longer using it. diff --git a/src/dawn/native/CMakeLists.txt b/src/dawn/native/CMakeLists.txt index 9f95fa49a9..09ac90a224 100644 --- a/src/dawn/native/CMakeLists.txt +++ b/src/dawn/native/CMakeLists.txt @@ -444,6 +444,8 @@ if (DAWN_ENABLE_OPENGL) "opengl/ComputePipelineGL.h" "opengl/ContextEGL.cpp" "opengl/ContextEGL.h" + "opengl/ContextExternal.cpp" + "opengl/ContextExternal.h" "opengl/DeviceGL.cpp" "opengl/DeviceGL.h" "opengl/EGLFunctions.cpp" diff --git a/src/dawn/native/opengl/AdapterGL.cpp b/src/dawn/native/opengl/AdapterGL.cpp index 7a4f336078..0f3022ea54 100644 --- a/src/dawn/native/opengl/AdapterGL.cpp +++ b/src/dawn/native/opengl/AdapterGL.cpp @@ -21,6 +21,7 @@ #include "dawn/common/GPUInfo.h" #include "dawn/native/Instance.h" #include "dawn/native/opengl/ContextEGL.h" +#include "dawn/native/opengl/ContextExternal.h" #include "dawn/native/opengl/DeviceGL.h" namespace dawn::native::opengl { @@ -53,12 +54,21 @@ uint32_t GetVendorIdFromVendors(const char* vendor) { } // anonymous namespace -Adapter::Adapter(InstanceBase* instance, wgpu::BackendType backendType) - : AdapterBase(instance, backendType) {} +Adapter::Adapter(InstanceBase* instance, + wgpu::BackendType backendType, + void (*makeCurrent)(void*), + void (*destroy)(void*), + void* userData) + : AdapterBase(instance, backendType), + mMakeCurrent(makeCurrent), + mDestroy(destroy), + mUserData(userData) {} MaybeError Adapter::InitializeGLFunctions(void* (*getProc)(const char*)) { - // Use getProc to populate the dispatch table - mEGLFunctions.Init(getProc); + if (mMakeCurrent == nullptr) { + // Use getProc to populate the dispatch table + mEGLFunctions.Init(getProc); + } return mFunctions.Initialize(getProc); } @@ -153,7 +163,11 @@ ResultOrError> Adapter::CreateDeviceImpl(const DeviceDescriptor* EGLenum api = GetBackendType() == wgpu::BackendType::OpenGL ? EGL_OPENGL_API : EGL_OPENGL_ES_API; std::unique_ptr context; - DAWN_TRY_ASSIGN(context, ContextEGL::Create(mEGLFunctions, api)); + if (mMakeCurrent != nullptr) { + DAWN_TRY_ASSIGN(context, ContextExternal::Create(mMakeCurrent, mDestroy, mUserData)); + } else { + DAWN_TRY_ASSIGN(context, ContextEGL::Create(mEGLFunctions, api)); + } return Device::Create(this, descriptor, mFunctions, std::move(context)); } diff --git a/src/dawn/native/opengl/AdapterGL.h b/src/dawn/native/opengl/AdapterGL.h index 6e354b2d03..f0f0950851 100644 --- a/src/dawn/native/opengl/AdapterGL.h +++ b/src/dawn/native/opengl/AdapterGL.h @@ -23,7 +23,11 @@ namespace dawn::native::opengl { class Adapter : public AdapterBase { public: - Adapter(InstanceBase* instance, wgpu::BackendType backendType); + Adapter(InstanceBase* instance, + wgpu::BackendType backendType, + void (*makeCurrent)(void*), + void (*destroy)(void*), + void* userData); MaybeError InitializeGLFunctions(void* (*getProc)(const char*)); @@ -40,6 +44,9 @@ class Adapter : public AdapterBase { OpenGLFunctions mFunctions; EGLFunctions mEGLFunctions; + void (*mMakeCurrent)(void*); + void (*mDestroy)(void*); + void* mUserData; }; } // namespace dawn::native::opengl diff --git a/src/dawn/native/opengl/BackendGL.cpp b/src/dawn/native/opengl/BackendGL.cpp index ac4e374e0d..dc5edbe885 100644 --- a/src/dawn/native/opengl/BackendGL.cpp +++ b/src/dawn/native/opengl/BackendGL.cpp @@ -96,7 +96,8 @@ ResultOrError>> Backend::DiscoverAdapters( DAWN_INVALID_IF(options->getProc == nullptr, "AdapterDiscoveryOptions::getProc must be set"); Ref adapter = AcquireRef( - new Adapter(GetInstance(), static_cast(optionsBase->backendType))); + new Adapter(GetInstance(), static_cast(optionsBase->backendType), + options->makeCurrent, options->destroy, options->userData)); DAWN_TRY(adapter->InitializeGLFunctions(options->getProc)); DAWN_TRY(adapter->Initialize()); diff --git a/src/dawn/native/opengl/ContextExternal.cpp b/src/dawn/native/opengl/ContextExternal.cpp new file mode 100644 index 0000000000..9cc1f2f982 --- /dev/null +++ b/src/dawn/native/opengl/ContextExternal.cpp @@ -0,0 +1,39 @@ +// Copyright 2022 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "dawn/native/opengl/ContextExternal.h" + +#include + +namespace dawn::native::opengl { + +ResultOrError> ContextExternal::Create(void (*makeCurrent)(void*), + void (*destroy)(void*), + void* userData) { + return std::unique_ptr(new ContextExternal(makeCurrent, destroy, userData)); +} + +void ContextExternal::MakeCurrent() { + if (mMakeCurrent) { + mMakeCurrent(mUserData); + } +} + +ContextExternal::~ContextExternal() { + if (mDestroy) { + mDestroy(mUserData); + } +} + +} // namespace dawn::native::opengl diff --git a/src/dawn/native/opengl/ContextExternal.h b/src/dawn/native/opengl/ContextExternal.h new file mode 100644 index 0000000000..d36538d4ee --- /dev/null +++ b/src/dawn/native/opengl/ContextExternal.h @@ -0,0 +1,43 @@ +// Copyright 2022 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_DAWN_NATIVE_OPENGL_CONTEXTEXTERNAL_H_ +#define SRC_DAWN_NATIVE_OPENGL_CONTEXTEXTERNAL_H_ + +#include + +#include "dawn/native/opengl/DeviceGL.h" + +namespace dawn::native::opengl { + +class ContextExternal : public Device::Context { + public: + static ResultOrError> Create(void (*makeCurrent)(void*), + void (*destroy)(void*), + void* userData); + void MakeCurrent() override; + ~ContextExternal() override; + + private: + ContextExternal(void (*makeCurrent)(void*), void (*destroy)(void*), void* userData) + : mMakeCurrent(makeCurrent), mDestroy(destroy), mUserData(userData) {} + + void (*mMakeCurrent)(void*); + void (*mDestroy)(void*); + void* mUserData; +}; + +} // namespace dawn::native::opengl + +#endif // SRC_DAWN_NATIVE_OPENGL_CONTEXTEXTERNAL_H_ diff --git a/src/dawn/native/opengl/OpenGLVersion.cpp b/src/dawn/native/opengl/OpenGLVersion.cpp index 80857064bd..110522a638 100644 --- a/src/dawn/native/opengl/OpenGLVersion.cpp +++ b/src/dawn/native/opengl/OpenGLVersion.cpp @@ -25,8 +25,16 @@ MaybeError OpenGLVersion::Initialize(GetProcAddress getProc) { if (getString == nullptr) { return DAWN_INTERNAL_ERROR("Couldn't load glGetString"); } + PFNGLGETERRORPROC getError = reinterpret_cast(getProc("glGetError")); + if (getError == nullptr) { + return DAWN_INTERNAL_ERROR("Couldn't load glGetError"); + } const char* version = reinterpret_cast(getString(GL_VERSION)); + if (version == nullptr) { + GLenum error = getError(); + return DAWN_INTERNAL_ERROR("glGetString failed: {}"); + } if (strstr(version, "OpenGL ES") != nullptr) { // ES spec states that the GL_VERSION string will be in the following format: