Implement EGL error handling.
Implement a CheckEGL function (a la CheckVkSuccess/CheckHRESULT) that transforms EGL errors to Dawn errors. Use DAWN_TRY and ResultOrError and friends. Change-Id: I51fcd6e084c2f824f7d71185e0e1ad0e0ff56e34 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94561 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
eab404cb17
commit
c2d830700a
|
@ -575,6 +575,8 @@ source_set("sources") {
|
||||||
"opengl/SwapChainGL.h",
|
"opengl/SwapChainGL.h",
|
||||||
"opengl/TextureGL.cpp",
|
"opengl/TextureGL.cpp",
|
||||||
"opengl/TextureGL.h",
|
"opengl/TextureGL.h",
|
||||||
|
"opengl/UtilsEGL.cpp",
|
||||||
|
"opengl/UtilsEGL.h",
|
||||||
"opengl/UtilsGL.cpp",
|
"opengl/UtilsGL.cpp",
|
||||||
"opengl/UtilsGL.h",
|
"opengl/UtilsGL.h",
|
||||||
"opengl/opengl_platform.h",
|
"opengl/opengl_platform.h",
|
||||||
|
|
|
@ -453,6 +453,8 @@ if (DAWN_ENABLE_OPENGL)
|
||||||
"opengl/SwapChainGL.h"
|
"opengl/SwapChainGL.h"
|
||||||
"opengl/TextureGL.cpp"
|
"opengl/TextureGL.cpp"
|
||||||
"opengl/TextureGL.h"
|
"opengl/TextureGL.h"
|
||||||
|
"opengl/UtilsEGL.cpp"
|
||||||
|
"opengl/UtilsEGL.h"
|
||||||
"opengl/UtilsGL.cpp"
|
"opengl/UtilsGL.cpp"
|
||||||
"opengl/UtilsGL.h"
|
"opengl/UtilsGL.h"
|
||||||
"opengl/opengl_platform.h"
|
"opengl/opengl_platform.h"
|
||||||
|
|
|
@ -152,9 +152,8 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
|
||||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
||||||
EGLenum api =
|
EGLenum api =
|
||||||
GetBackendType() == wgpu::BackendType::OpenGL ? EGL_OPENGL_API : EGL_OPENGL_ES_API;
|
GetBackendType() == wgpu::BackendType::OpenGL ? EGL_OPENGL_API : EGL_OPENGL_ES_API;
|
||||||
|
std::unique_ptr<Device::Context> context;
|
||||||
std::unique_ptr<Device::Context> context = ContextEGL::Create(mEGLFunctions, api);
|
DAWN_TRY_ASSIGN(context, ContextEGL::Create(mEGLFunctions, api));
|
||||||
|
|
||||||
return Device::Create(this, descriptor, mFunctions, std::move(context));
|
return Device::Create(this, descriptor, mFunctions, std::move(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,8 +57,8 @@ std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||||
egl.Init(options.getProc);
|
egl.Init(options.getProc);
|
||||||
|
|
||||||
EGLenum api = GetType() == wgpu::BackendType::OpenGLES ? EGL_OPENGL_ES_API : EGL_OPENGL_API;
|
EGLenum api = GetType() == wgpu::BackendType::OpenGLES ? EGL_OPENGL_ES_API : EGL_OPENGL_API;
|
||||||
std::unique_ptr<Device::Context> context = ContextEGL::Create(egl, api);
|
std::unique_ptr<ContextEGL> context;
|
||||||
if (!context) {
|
if (GetInstance()->ConsumedError(ContextEGL::Create(egl, api), &context)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,22 +17,29 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "dawn/native/opengl/UtilsEGL.h"
|
||||||
|
|
||||||
namespace dawn::native::opengl {
|
namespace dawn::native::opengl {
|
||||||
|
|
||||||
std::unique_ptr<ContextEGL> ContextEGL::Create(const EGLFunctions& egl, EGLenum api) {
|
ResultOrError<std::unique_ptr<ContextEGL>> ContextEGL::Create(const EGLFunctions& egl,
|
||||||
|
EGLenum api) {
|
||||||
EGLDisplay display = egl.GetCurrentDisplay();
|
EGLDisplay display = egl.GetCurrentDisplay();
|
||||||
|
|
||||||
if (display == EGL_NO_DISPLAY) {
|
if (display == EGL_NO_DISPLAY) {
|
||||||
display = egl.GetDisplay(EGL_DEFAULT_DISPLAY);
|
display = egl.GetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (display == EGL_NO_DISPLAY) {
|
DAWN_INVALID_IF(display == EGL_NO_DISPLAY, "eglGetDisplay");
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
EGLint renderableType = api == EGL_OPENGL_ES_API ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_BIT;
|
EGLint renderableType = api == EGL_OPENGL_ES_API ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_BIT;
|
||||||
|
|
||||||
egl.Initialize(display, nullptr, nullptr);
|
EGLint major, minor;
|
||||||
|
|
||||||
|
DAWN_TRY(CheckEGL(egl, egl.Initialize(display, &major, &minor), "eglInitialize"));
|
||||||
|
|
||||||
|
// We use EGLImage unconditionally, which only became core in 1.5.
|
||||||
|
DAWN_INVALID_IF(major < 1 || (major == 1 && minor < 5),
|
||||||
|
"EGL version (%u.%u) must be at least 1.5", major, minor);
|
||||||
|
|
||||||
// Since we're creating a surfaceless context, the only thing we really care
|
// Since we're creating a surfaceless context, the only thing we really care
|
||||||
// about is the RENDERABLE_TYPE.
|
// about is the RENDERABLE_TYPE.
|
||||||
|
@ -40,15 +47,13 @@ std::unique_ptr<ContextEGL> ContextEGL::Create(const EGLFunctions& egl, EGLenum
|
||||||
|
|
||||||
EGLint num_config;
|
EGLint num_config;
|
||||||
EGLConfig config;
|
EGLConfig config;
|
||||||
if (egl.ChooseConfig(display, config_attribs, &config, 1, &num_config) == EGL_FALSE) {
|
DAWN_TRY(CheckEGL(egl, egl.ChooseConfig(display, config_attribs, &config, 1, &num_config),
|
||||||
return nullptr;
|
"eglChooseConfig"));
|
||||||
}
|
|
||||||
|
|
||||||
if (!egl.BindAPI(api)) {
|
DAWN_INVALID_IF(num_config == 0, "eglChooseConfig returned zero configs");
|
||||||
return nullptr;
|
|
||||||
}
|
DAWN_TRY(CheckEGL(egl, egl.BindAPI(api), "eglBindAPI"));
|
||||||
|
|
||||||
EGLint major, minor;
|
|
||||||
if (api == EGL_OPENGL_ES_API) {
|
if (api == EGL_OPENGL_ES_API) {
|
||||||
major = 3;
|
major = 3;
|
||||||
minor = 1;
|
minor = 1;
|
||||||
|
@ -60,9 +65,7 @@ std::unique_ptr<ContextEGL> ContextEGL::Create(const EGLFunctions& egl, EGLenum
|
||||||
EGL_CONTEXT_MAJOR_VERSION, major, EGL_CONTEXT_MINOR_VERSION, minor, EGL_NONE, EGL_NONE,
|
EGL_CONTEXT_MAJOR_VERSION, major, EGL_CONTEXT_MINOR_VERSION, minor, EGL_NONE, EGL_NONE,
|
||||||
};
|
};
|
||||||
EGLContext context = egl.CreateContext(display, config, EGL_NO_CONTEXT, attrib_list);
|
EGLContext context = egl.CreateContext(display, config, EGL_NO_CONTEXT, attrib_list);
|
||||||
if (!context) {
|
DAWN_TRY(CheckEGL(egl, context != EGL_NO_CONTEXT, "eglCreateContext"));
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::unique_ptr<ContextEGL>(new ContextEGL(egl, display, context));
|
return std::unique_ptr<ContextEGL>(new ContextEGL(egl, display, context));
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@ namespace dawn::native::opengl {
|
||||||
|
|
||||||
class ContextEGL : public Device::Context {
|
class ContextEGL : public Device::Context {
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<ContextEGL> Create(const EGLFunctions& functions, EGLenum api);
|
static ResultOrError<std::unique_ptr<ContextEGL>> Create(const EGLFunctions& functions,
|
||||||
|
EGLenum api);
|
||||||
void MakeCurrent() override;
|
void MakeCurrent() override;
|
||||||
~ContextEGL() override;
|
~ContextEGL() override;
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ void EGLFunctions::Init(void* (*getProc)(const char*)) {
|
||||||
GetCurrentSurface =
|
GetCurrentSurface =
|
||||||
reinterpret_cast<PFNEGLGETCURRENTSURFACEPROC>(GetProcAddress("eglGetCurrentSurface"));
|
reinterpret_cast<PFNEGLGETCURRENTSURFACEPROC>(GetProcAddress("eglGetCurrentSurface"));
|
||||||
GetDisplay = reinterpret_cast<PFNEGLGETDISPLAYPROC>(GetProcAddress("eglGetDisplay"));
|
GetDisplay = reinterpret_cast<PFNEGLGETDISPLAYPROC>(GetProcAddress("eglGetDisplay"));
|
||||||
|
GetError = reinterpret_cast<PFNEGLGETERRORPROC>(GetProcAddress("eglGetError"));
|
||||||
Initialize = reinterpret_cast<PFNEGLINITIALIZEPROC>(GetProcAddress("eglInitialize"));
|
Initialize = reinterpret_cast<PFNEGLINITIALIZEPROC>(GetProcAddress("eglInitialize"));
|
||||||
MakeCurrent = reinterpret_cast<PFNEGLMAKECURRENTPROC>(GetProcAddress("eglMakeCurrent"));
|
MakeCurrent = reinterpret_cast<PFNEGLMAKECURRENTPROC>(GetProcAddress("eglMakeCurrent"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ struct EGLFunctions {
|
||||||
PFNEGLGETCURRENTDISPLAYPROC GetCurrentDisplay;
|
PFNEGLGETCURRENTDISPLAYPROC GetCurrentDisplay;
|
||||||
PFNEGLGETCURRENTSURFACEPROC GetCurrentSurface;
|
PFNEGLGETCURRENTSURFACEPROC GetCurrentSurface;
|
||||||
PFNEGLGETDISPLAYPROC GetDisplay;
|
PFNEGLGETDISPLAYPROC GetDisplay;
|
||||||
|
PFNEGLGETERRORPROC GetError;
|
||||||
PFNEGLGETPROCADDRESSPROC GetProcAddress;
|
PFNEGLGETPROCADDRESSPROC GetProcAddress;
|
||||||
PFNEGLINITIALIZEPROC Initialize;
|
PFNEGLINITIALIZEPROC Initialize;
|
||||||
PFNEGLMAKECURRENTPROC MakeCurrent;
|
PFNEGLMAKECURRENTPROC MakeCurrent;
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
// 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/UtilsEGL.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "dawn/native/opengl/EGLFunctions.h"
|
||||||
|
|
||||||
|
namespace dawn::native::opengl {
|
||||||
|
|
||||||
|
const char* EGLErrorAsString(EGLint error) {
|
||||||
|
switch (error) {
|
||||||
|
case EGL_SUCCESS:
|
||||||
|
return "EGL_SUCCESS";
|
||||||
|
case EGL_NOT_INITIALIZED:
|
||||||
|
return "EGL_NOT_INITIALIZED";
|
||||||
|
case EGL_BAD_ACCESS:
|
||||||
|
return "EGL_BAD_ACCESS";
|
||||||
|
case EGL_BAD_ALLOC:
|
||||||
|
return "EGL_BAD_ALLOC";
|
||||||
|
case EGL_BAD_ATTRIBUTE:
|
||||||
|
return "EGL_BAD_ATTRIBUTE";
|
||||||
|
case EGL_BAD_CONTEXT:
|
||||||
|
return "EGL_BAD_CONTEXT";
|
||||||
|
case EGL_BAD_CONFIG:
|
||||||
|
return "EGL_BAD_CONFIG";
|
||||||
|
case EGL_BAD_CURRENT_SURFACE:
|
||||||
|
return "EGL_BAD_CURRENT_SURFACE";
|
||||||
|
case EGL_BAD_DISPLAY:
|
||||||
|
return "EGL_BAD_DISPLAY";
|
||||||
|
case EGL_BAD_SURFACE:
|
||||||
|
return "EGL_BAD_SURFACE";
|
||||||
|
case EGL_BAD_MATCH:
|
||||||
|
return "EGL_BAD_MATCH";
|
||||||
|
case EGL_BAD_PARAMETER:
|
||||||
|
return "EGL_BAD_PARAMETER";
|
||||||
|
case EGL_BAD_NATIVE_PIXMAP:
|
||||||
|
return "EGL_BAD_NATIVE_PIXMAP";
|
||||||
|
case EGL_BAD_NATIVE_WINDOW:
|
||||||
|
return "EGL_BAD_NATIVE_WINDOW";
|
||||||
|
case EGL_CONTEXT_LOST:
|
||||||
|
return "EGL_CONTEXT_LOST";
|
||||||
|
default:
|
||||||
|
return "<Unknown EGL error>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeError CheckEGL(const EGLFunctions& egl, EGLBoolean result, const char* context) {
|
||||||
|
if (DAWN_LIKELY(result == EGL_TRUE)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
EGLint error = egl.GetError();
|
||||||
|
std::string message = std::string(context) + " failed with " + EGLErrorAsString(error);
|
||||||
|
if (error == EGL_BAD_ALLOC) {
|
||||||
|
return DAWN_OUT_OF_MEMORY_ERROR(message);
|
||||||
|
} else if (error == EGL_CONTEXT_LOST) {
|
||||||
|
return DAWN_DEVICE_LOST_ERROR(message);
|
||||||
|
} else {
|
||||||
|
return DAWN_INTERNAL_ERROR(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dawn::native::opengl
|
|
@ -0,0 +1,31 @@
|
||||||
|
// 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_UTILSEGL_H_
|
||||||
|
#define SRC_DAWN_NATIVE_OPENGL_UTILSEGL_H_
|
||||||
|
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
|
#include "dawn/native/Error.h"
|
||||||
|
|
||||||
|
namespace dawn::native::opengl {
|
||||||
|
|
||||||
|
struct EGLFunctions;
|
||||||
|
|
||||||
|
const char* EGLErrorAsString(EGLint error);
|
||||||
|
MaybeError CheckEGL(const EGLFunctions& egl, EGLBoolean result, const char* context);
|
||||||
|
|
||||||
|
} // namespace dawn::native::opengl
|
||||||
|
|
||||||
|
#endif // SRC_DAWN_NATIVE_OPENGL_UTILSEGL_H_
|
Loading…
Reference in New Issue