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/TextureGL.cpp",
|
||||
"opengl/TextureGL.h",
|
||||
"opengl/UtilsEGL.cpp",
|
||||
"opengl/UtilsEGL.h",
|
||||
"opengl/UtilsGL.cpp",
|
||||
"opengl/UtilsGL.h",
|
||||
"opengl/opengl_platform.h",
|
||||
|
|
|
@ -453,6 +453,8 @@ if (DAWN_ENABLE_OPENGL)
|
|||
"opengl/SwapChainGL.h"
|
||||
"opengl/TextureGL.cpp"
|
||||
"opengl/TextureGL.h"
|
||||
"opengl/UtilsEGL.cpp"
|
||||
"opengl/UtilsEGL.h"
|
||||
"opengl/UtilsGL.cpp"
|
||||
"opengl/UtilsGL.h"
|
||||
"opengl/opengl_platform.h"
|
||||
|
|
|
@ -152,9 +152,8 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
|
|||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
||||
EGLenum api =
|
||||
GetBackendType() == wgpu::BackendType::OpenGL ? EGL_OPENGL_API : EGL_OPENGL_ES_API;
|
||||
|
||||
std::unique_ptr<Device::Context> context = ContextEGL::Create(mEGLFunctions, api);
|
||||
|
||||
std::unique_ptr<Device::Context> context;
|
||||
DAWN_TRY_ASSIGN(context, ContextEGL::Create(mEGLFunctions, api));
|
||||
return Device::Create(this, descriptor, mFunctions, std::move(context));
|
||||
}
|
||||
|
||||
|
|
|
@ -57,8 +57,8 @@ std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
|||
egl.Init(options.getProc);
|
||||
|
||||
EGLenum api = GetType() == wgpu::BackendType::OpenGLES ? EGL_OPENGL_ES_API : EGL_OPENGL_API;
|
||||
std::unique_ptr<Device::Context> context = ContextEGL::Create(egl, api);
|
||||
if (!context) {
|
||||
std::unique_ptr<ContextEGL> context;
|
||||
if (GetInstance()->ConsumedError(ContextEGL::Create(egl, api), &context)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -17,22 +17,29 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "dawn/native/opengl/UtilsEGL.h"
|
||||
|
||||
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();
|
||||
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
display = egl.GetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
return nullptr;
|
||||
}
|
||||
DAWN_INVALID_IF(display == EGL_NO_DISPLAY, "eglGetDisplay");
|
||||
|
||||
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
|
||||
// about is the RENDERABLE_TYPE.
|
||||
|
@ -40,15 +47,13 @@ std::unique_ptr<ContextEGL> ContextEGL::Create(const EGLFunctions& egl, EGLenum
|
|||
|
||||
EGLint num_config;
|
||||
EGLConfig config;
|
||||
if (egl.ChooseConfig(display, config_attribs, &config, 1, &num_config) == EGL_FALSE) {
|
||||
return nullptr;
|
||||
}
|
||||
DAWN_TRY(CheckEGL(egl, egl.ChooseConfig(display, config_attribs, &config, 1, &num_config),
|
||||
"eglChooseConfig"));
|
||||
|
||||
if (!egl.BindAPI(api)) {
|
||||
return nullptr;
|
||||
}
|
||||
DAWN_INVALID_IF(num_config == 0, "eglChooseConfig returned zero configs");
|
||||
|
||||
DAWN_TRY(CheckEGL(egl, egl.BindAPI(api), "eglBindAPI"));
|
||||
|
||||
EGLint major, minor;
|
||||
if (api == EGL_OPENGL_ES_API) {
|
||||
major = 3;
|
||||
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,
|
||||
};
|
||||
EGLContext context = egl.CreateContext(display, config, EGL_NO_CONTEXT, attrib_list);
|
||||
if (!context) {
|
||||
return nullptr;
|
||||
}
|
||||
DAWN_TRY(CheckEGL(egl, context != EGL_NO_CONTEXT, "eglCreateContext"));
|
||||
|
||||
return std::unique_ptr<ContextEGL>(new ContextEGL(egl, display, context));
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ namespace dawn::native::opengl {
|
|||
|
||||
class ContextEGL : public Device::Context {
|
||||
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;
|
||||
~ContextEGL() override;
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ void EGLFunctions::Init(void* (*getProc)(const char*)) {
|
|||
GetCurrentSurface =
|
||||
reinterpret_cast<PFNEGLGETCURRENTSURFACEPROC>(GetProcAddress("eglGetCurrentSurface"));
|
||||
GetDisplay = reinterpret_cast<PFNEGLGETDISPLAYPROC>(GetProcAddress("eglGetDisplay"));
|
||||
GetError = reinterpret_cast<PFNEGLGETERRORPROC>(GetProcAddress("eglGetError"));
|
||||
Initialize = reinterpret_cast<PFNEGLINITIALIZEPROC>(GetProcAddress("eglInitialize"));
|
||||
MakeCurrent = reinterpret_cast<PFNEGLMAKECURRENTPROC>(GetProcAddress("eglMakeCurrent"));
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ struct EGLFunctions {
|
|||
PFNEGLGETCURRENTDISPLAYPROC GetCurrentDisplay;
|
||||
PFNEGLGETCURRENTSURFACEPROC GetCurrentSurface;
|
||||
PFNEGLGETDISPLAYPROC GetDisplay;
|
||||
PFNEGLGETERRORPROC GetError;
|
||||
PFNEGLGETPROCADDRESSPROC GetProcAddress;
|
||||
PFNEGLINITIALIZEPROC Initialize;
|
||||
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