Vulkan: Port renderer to Fuchsia

Add DisplayVk and WindowSurfaceVk subclasses for Fuchsia to the vulkan
renderer, as well as an implementation of OSWindow that renders
fullscreen for the test suite.

Disallow use of the vulkan loader from third_party as Fuchsia uses a fork
of the loader and has not sent those changes upstream yet.

Add a small wayland-inspired library libfuchsia-egl to provide a type
"struct fuchsia_egl_window" to use as EGLNativeWindowType. This type
combines a zx_handle_t to an image pipe channel and a surface size.

Image pipes can only be used once to create a VkSurfaceKHR. This means we
have to recreate the pipe in tests that call eglCreateWindowSurface more
than once with a single OSWindow, or the second call will fail. Add a
resetNativeWindow() method to accomplish this.

BUG=angleproject:2475
TEST=angle_end2end_tests on Fuchsia

Change-Id: I71a613a362dd1c8aada49a3c02ae461e064457bf
Reviewed-on: https://chromium-review.googlesource.com/c/1446496
Commit-Queue: Michael Spang <spang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Michael Spang
2019-01-21 18:09:15 -05:00
committed by Commit Bot
parent 6b695c3ffb
commit 991d1cfb5e
45 changed files with 881 additions and 39 deletions

4
.gitignore vendored
View File

@@ -21,18 +21,22 @@
*.vsp
*~
.*.sw*
.cipd
.gclient
.gclient_entries
/src/tests/third_party/gles_conformance_tests
/testing
/third_party/cherry
/third_party/deqp/src
/third_party/fuchsia-sdk
/third_party/gles1_conform
/third_party/glslang/src
/third_party/googletest/src
/third_party/jsoncpp
/third_party/libpng/src
/third_party/llvm-build
/third_party/qemu-linux-x64
/third_party/qemu-mac-x64
/third_party/spirv-headers/src
/third_party/spirv-tools/src
/third_party/vulkan-headers/src

View File

@@ -494,6 +494,9 @@ if (angle_enable_vulkan) {
]
libs = [ "vulkan" ]
}
if (is_fuchsia) {
defines = [ "VK_USE_PLATFORM_FUCHSIA" ]
}
}
# Use this target to include everything ANGLE needs for Vulkan.
@@ -503,7 +506,7 @@ if (angle_enable_vulkan) {
]
public_configs = [ ":vulkan_config" ]
data_deps = []
if (!is_android) {
if (!is_android && !is_fuchsia) {
deps = [
"$angle_root/third_party/vulkan-loader:libvulkan",
]
@@ -511,11 +514,24 @@ if (angle_enable_vulkan) {
public_configs +=
[ "$angle_root/third_party/vulkan-loader:vulkan_loader_config" ]
}
if (is_fuchsia) {
public_deps += [
"$angle_root/src/common/fuchsia_egl",
"//third_party/fuchsia-sdk:vulkan_base",
"//third_party/fuchsia-sdk/sdk:vulkan",
]
}
if (angle_enable_vulkan_validation_layers) {
data_deps += [ "$angle_root/third_party/vulkan-validation-layers:vulkan_validation_layers" ]
if (!is_android) {
data_deps += [ "$angle_root/third_party/vulkan-validation-layers:vulkan_gen_json_files" ]
if (is_fuchsia) {
deps = [
"//third_party/fuchsia-sdk:vulkan_validation",
]
} else {
data_deps += [ "$angle_root/third_party/vulkan-validation-layers:vulkan_validation_layers" ]
if (!is_android) {
data_deps += [ "$angle_root/third_party/vulkan-validation-layers:vulkan_gen_json_files" ]
}
}
}
}
@@ -618,6 +634,13 @@ angle_static_library("libANGLE") {
if (is_linux) {
sources += libangle_vulkan_xcb_sources
}
if (is_fuchsia) {
sources += libangle_vulkan_fuchsia_sources
deps += [
"$angle_root/src/common/fuchsia_egl",
"$angle_root/src/common/fuchsia_egl:backend",
]
}
if (is_android) {
sources += libangle_vulkan_android_sources
libs += [ "vulkan" ]
@@ -924,10 +947,6 @@ foreach(is_shared_library,
]
}
if (use_ozone) {
sources += util_ozone_sources
}
configs += [ ":debug_annotations_config" ]
public_configs += [ ":angle_util_config" ]
@@ -937,6 +956,24 @@ foreach(is_shared_library,
":angle_util_loader_headers",
]
public_deps = []
if (is_fuchsia) {
sources += util_fuchsia_sources
public_deps += [
"$angle_root/src/common/fuchsia_egl",
"//third_party/fuchsia-sdk/sdk:async_loop_cpp",
"//third_party/fuchsia-sdk/sdk:fdio",
"//third_party/fuchsia-sdk/sdk:images",
"//third_party/fuchsia-sdk/sdk:scenic_cpp",
"//third_party/fuchsia-sdk/sdk:ui_gfx",
"//third_party/fuchsia-sdk/sdk:ui_policy",
"//third_party/fuchsia-sdk/sdk:ui_scenic",
"//third_party/fuchsia-sdk/sdk:ui_viewsv1",
]
} else if (use_ozone) {
sources += util_ozone_sources
}
if (is_shared_library) {
defines = [ "LIBANGLE_UTIL_IMPLEMENTATION" ]
@@ -944,9 +981,7 @@ foreach(is_shared_library,
sources += util_win_shared_sources
}
public_deps = [
":angle_util_loader",
]
public_deps += [ ":angle_util_loader" ]
if (is_mac && !is_component_build) {
ldflags = [

41
DEPS
View File

@@ -36,12 +36,12 @@ vars = {
deps = {
'{angle_root}/build': {
'url': '{chromium_git}/chromium/src/build.git@9dbdd5c2ae8c298bef55ca7c42754079aabe60c7',
'url': '{chromium_git}/chromium/src/build.git@9a53be87ebb636c35f2ed9772e5deaeb350d790b',
'condition': 'not build_with_chromium',
},
'{angle_root}/buildtools': {
'url': '{chromium_git}/chromium/buildtools.git@24ebce4578745db15274e180da1938ebc1358243',
'url': '{chromium_git}/chromium/buildtools.git@6fbda1b24c1893a893b17aa219b765b9e7c801d8',
'condition': 'not build_with_chromium',
},
@@ -85,6 +85,28 @@ deps = {
'condition': 'not build_with_chromium',
},
'{angle_root}/third_party/qemu-linux-x64': {
'packages': [
{
'package': 'fuchsia/qemu/linux-amd64',
'version': '9cc486c5b18a0be515c39a280ca9a309c54cf994'
},
],
'condition': 'not build_with_chromium and (host_os == "linux" and checkout_fuchsia)',
'dep_type': 'cipd',
},
'{angle_root}/third_party/qemu-mac-x64': {
'packages': [
{
'package': 'fuchsia/qemu/mac-amd64',
'version': '2d3358ae9a569b2d4a474f498b32b202a152134f'
},
],
'condition': 'not build_with_chromium and (host_os == "mac" and checkout_fuchsia)',
'dep_type': 'cipd',
},
'{angle_root}/third_party/spirv-headers/src': {
'url': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Headers@{spirv_headers_revision}',
'condition': 'not build_with_chromium',
@@ -120,6 +142,11 @@ deps = {
'url': '{chromium_git}/chromium/src/tools/clang.git@3114fbc11f9644c54dd0a4cdbfa867bac50ff983',
'condition': 'not build_with_chromium',
},
'{angle_root}/third_party/fuchsia-sdk': {
'url': '{chromium_git}/chromium/src/third_party/fuchsia-sdk.git@8e8db13b538ecb251e5ce9d5c781fc142f9752fd',
'condition': 'checkout_fuchsia and not build_with_chromium',
},
}
hooks = [
@@ -248,6 +275,16 @@ hooks = [
'-s', '{angle_root}/build/toolchain/win/rc/win/rc.exe.sha1',
],
},
{
'name': 'fuchsia_sdk',
'pattern': '.',
'condition': 'checkout_fuchsia and not build_with_chromium',
'action': [
'python',
'{angle_root}/build/fuchsia/update_sdk.py',
],
},
]
recursedeps = [

View File

@@ -63,7 +63,7 @@ declare_args() {
(use_x11 && !is_chromeos)) && !is_fuchsia
angle_enable_vulkan = is_win || (is_linux && use_x11 && !is_chromeos) ||
(is_android && ndk_supports_vulkan)
(is_android && ndk_supports_vulkan) || is_fuchsia
angle_enable_null = true
angle_enable_essl = true
angle_enable_glsl = true

View File

@@ -0,0 +1,30 @@
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("../../../gni/angle.gni")
assert(is_fuchsia)
config("config") {
include_dirs = [ "." ]
}
angle_shared_library("fuchsia_egl") {
sources = [
"fuchsia_egl.c",
]
public = [
"fuchsia_egl.h",
]
public_configs = [":config"]
deps = [
":backend",
]
}
angle_source_set("backend") {
public = [
"fuchsia_egl_backend.h",
]
}

View File

@@ -0,0 +1,75 @@
// Copyright 2019 The Fuchsia 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 "fuchsia_egl.h"
#include "fuchsia_egl_backend.h"
#include <zircon/assert.h>
#include <zircon/syscalls.h>
#define FUCHSIA_EGL_WINDOW_MAGIC 0x80738870 // "FXIP"
struct fuchsia_egl_window
{
uint32_t magic;
zx_handle_t image_pipe_handle;
int32_t width;
int32_t height;
};
fuchsia_egl_window *fuchsia_egl_window_create(zx_handle_t image_pipe_handle,
int32_t width,
int32_t height)
{
if (width <= 0 || height <= 0)
return NULL;
fuchsia_egl_window *egl_window = malloc(sizeof(*egl_window));
egl_window->magic = FUCHSIA_EGL_WINDOW_MAGIC;
egl_window->image_pipe_handle = image_pipe_handle;
egl_window->width = width;
egl_window->height = height;
return egl_window;
}
void fuchsia_egl_window_destroy(fuchsia_egl_window *egl_window)
{
ZX_ASSERT(egl_window->magic == FUCHSIA_EGL_WINDOW_MAGIC);
if (egl_window->image_pipe_handle != ZX_HANDLE_INVALID)
{
zx_handle_close(egl_window->image_pipe_handle);
egl_window->image_pipe_handle = ZX_HANDLE_INVALID;
}
egl_window->magic = -1U;
free(egl_window);
}
void fuchsia_egl_window_resize(fuchsia_egl_window *egl_window, int32_t width, int32_t height)
{
ZX_ASSERT(egl_window->magic == FUCHSIA_EGL_WINDOW_MAGIC);
if (width <= 0 || height <= 0)
return;
egl_window->width = width;
egl_window->height = height;
}
int32_t fuchsia_egl_window_get_width(fuchsia_egl_window *egl_window)
{
ZX_ASSERT(egl_window->magic == FUCHSIA_EGL_WINDOW_MAGIC);
return egl_window->width;
}
int32_t fuchsia_egl_window_get_height(fuchsia_egl_window *egl_window)
{
ZX_ASSERT(egl_window->magic == FUCHSIA_EGL_WINDOW_MAGIC);
return egl_window->height;
}
zx_handle_t fuchsia_egl_window_release_image_pipe(fuchsia_egl_window *egl_window)
{
ZX_ASSERT(egl_window->magic == FUCHSIA_EGL_WINDOW_MAGIC);
zx_handle_t image_pipe_handle = egl_window->image_pipe_handle;
egl_window->image_pipe_handle = ZX_HANDLE_INVALID;
return image_pipe_handle;
}

View File

@@ -0,0 +1,42 @@
// Copyright 2019 The Fuchsia 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 FUCHSIA_EGL_H_
#define FUCHSIA_EGL_H_
#include <inttypes.h>
#include <zircon/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(FUCHSIA_EGL_EXPORT)
# define FUCHSIA_EGL_EXPORT __attribute__((__visibility__("default")))
#endif
typedef struct fuchsia_egl_window fuchsia_egl_window;
FUCHSIA_EGL_EXPORT
fuchsia_egl_window *fuchsia_egl_window_create(zx_handle_t image_pipe_handle,
int32_t width,
int32_t height);
FUCHSIA_EGL_EXPORT
void fuchsia_egl_window_destroy(fuchsia_egl_window *egl_window);
FUCHSIA_EGL_EXPORT
void fuchsia_egl_window_resize(fuchsia_egl_window *egl_window, int32_t width, int32_t height);
FUCHSIA_EGL_EXPORT
int32_t fuchsia_egl_window_get_width(fuchsia_egl_window *egl_window);
FUCHSIA_EGL_EXPORT
int32_t fuchsia_egl_window_get_height(fuchsia_egl_window *egl_window);
#ifdef __cplusplus
}
#endif
#endif // FUCHSIA_EGL_H_

View File

@@ -0,0 +1,25 @@
// Copyright 2019 The Fuchsia 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 FUCHSIA_EGL_BACKEND_H_
#define FUCHSIA_EGL_BACKEND_H_
#include <zircon/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(FUCHSIA_EGL_EXPORT)
# define FUCHSIA_EGL_EXPORT __attribute__((__visibility__("default")))
#endif
FUCHSIA_EGL_EXPORT
zx_handle_t fuchsia_egl_window_release_image_pipe(fuchsia_egl_window *egl_window);
#ifdef __cplusplus
}
#endif
#endif // FUCHSIA_EGL_BACKEND_H_

View File

@@ -11,6 +11,9 @@
#if defined(_WIN32)
# define ANGLE_PLATFORM_WINDOWS 1
#elif defined(__Fuchsia__)
# define ANGLE_PLATFORM_FUCHSIA 1
# define ANGLE_PLATFORM_POSIX 1
#elif defined(__APPLE__)
# define ANGLE_PLATFORM_APPLE 1
# define ANGLE_PLATFORM_POSIX 1

View File

@@ -70,6 +70,8 @@
# include "libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h"
# elif defined(ANGLE_PLATFORM_ANDROID)
# include "libANGLE/renderer/vulkan/android/DisplayVkAndroid.h"
# elif defined(ANGLE_PLATFORM_FUCHSIA)
# include "libANGLE/renderer/vulkan/fuchsia/DisplayVkFuchsia.h"
# else
# error Unsupported Vulkan platform.
# endif
@@ -189,6 +191,8 @@ rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap, const D
impl = new rx::DisplayGLX(state);
#elif defined(ANGLE_PLATFORM_APPLE)
impl = new rx::DisplayCGL(state);
#elif defined(ANGLE_PLATFORM_FUCHSIA)
impl = new rx::DisplayVkFuchsia(state);
#elif defined(ANGLE_USE_OZONE)
impl = new rx::DisplayOzone(state);
#elif defined(ANGLE_PLATFORM_ANDROID)
@@ -261,6 +265,8 @@ rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap, const D
impl = new rx::DisplayVkXcb(state);
# elif defined(ANGLE_PLATFORM_ANDROID)
impl = new rx::DisplayVkAndroid(state);
# elif defined(ANGLE_PLATFORM_FUCHSIA)
impl = new rx::DisplayVkFuchsia(state);
# else
# error Unsupported Vulkan platform.
# endif

View File

@@ -355,7 +355,7 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable
// Changing CWD and setting environment variables makes no sense on Android,
// since this code is a part of Java application there.
// Android Vulkan loader doesn't need this either.
#if !defined(ANGLE_PLATFORM_ANDROID)
#if !defined(ANGLE_PLATFORM_ANDROID) && !defined(ANGLE_PLATFORM_FUCHSIA)
if (enableMockICD)
{
// Override environment variable to use built Mock ICD

View File

@@ -363,7 +363,8 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk)
// TODO(jmadill): Support devices which don't support copy. We use this for ReadPixels.
ANGLE_VK_CHECK(displayVk,
(mSurfaceCaps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0,
(mSurfaceCaps.supportedUsageFlags & kSurfaceVKColorImageUsageFlags) ==
kSurfaceVKColorImageUsageFlags,
VK_ERROR_INITIALIZATION_FAILED);
EGLAttrib attribWidth = mState.attributes.get(EGL_WIDTH, 0);

View File

@@ -0,0 +1,59 @@
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DisplayVkFuchsia.h:
// Implements methods from DisplayVkFuchsia
//
#include "libANGLE/renderer/vulkan/fuchsia/DisplayVkFuchsia.h"
#include "libANGLE/renderer/vulkan/fuchsia/WindowSurfaceVkFuchsia.h"
#include "libANGLE/renderer/vulkan/vk_caps_utils.h"
namespace rx
{
DisplayVkFuchsia::DisplayVkFuchsia(const egl::DisplayState &state) : DisplayVk(state) {}
bool DisplayVkFuchsia::isValidNativeWindow(EGLNativeWindowType window) const
{
return WindowSurfaceVkFuchsia::isValidNativeWindow(window);
}
SurfaceImpl *DisplayVkFuchsia::createWindowSurfaceVk(const egl::SurfaceState &state,
EGLNativeWindowType window,
EGLint width,
EGLint height)
{
ASSERT(isValidNativeWindow(window));
return new WindowSurfaceVkFuchsia(state, window, width, height);
}
egl::ConfigSet DisplayVkFuchsia::generateConfigs()
{
constexpr GLenum kColorFormats[] = {GL_BGRA8_EXT, GL_BGRX8_ANGLEX};
constexpr EGLint kSampleCounts[] = {0};
return egl_vk::GenerateConfigs(kColorFormats, egl_vk::kConfigDepthStencilFormats, kSampleCounts,
this);
}
bool DisplayVkFuchsia::checkConfigSupport(egl::Config *config)
{
// TODO(geofflang): Test for native support and modify the config accordingly.
// anglebug.com/2692
return true;
}
const char *DisplayVkFuchsia::getWSIExtension() const
{
return VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME;
}
const char *DisplayVkFuchsia::getWSILayer() const
{
return "VK_LAYER_FUCHSIA_imagepipe_swapchain";
}
} // namespace rx

View File

@@ -0,0 +1,39 @@
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DisplayVkFuchsia.h:
// Subclasses DisplayVk for the Fuchsia platform.
//
#ifndef LIBANGLE_RENDERER_VULKAN_FUCHSIA_DISPLAYVKFUCHSIA_H_
#define LIBANGLE_RENDERER_VULKAN_FUCHSIA_DISPLAYVKFUCHSIA_H_
#include "libANGLE/renderer/vulkan/DisplayVk.h"
namespace rx
{
class DisplayVkFuchsia : public DisplayVk
{
public:
DisplayVkFuchsia(const egl::DisplayState &state);
bool isValidNativeWindow(EGLNativeWindowType window) const override;
SurfaceImpl *createWindowSurfaceVk(const egl::SurfaceState &state,
EGLNativeWindowType window,
EGLint width,
EGLint height) override;
egl::ConfigSet generateConfigs() override;
bool checkConfigSupport(egl::Config *config) override;
const char *getWSIExtension() const override;
const char *getWSILayer() const override;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_FUCHSIA_DISPLAYVKFUCHSIA_H_

View File

@@ -0,0 +1,66 @@
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// WindowSurfaceVkFuchsia.cpp:
// Implements methods from WindowSurfaceVkFuchsia.
//
#include "libANGLE/renderer/vulkan/fuchsia/WindowSurfaceVkFuchsia.h"
#include <fuchsia_egl.h>
#include <fuchsia_egl_backend.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/vk_utils.h"
namespace rx
{
WindowSurfaceVkFuchsia::WindowSurfaceVkFuchsia(const egl::SurfaceState &surfaceState,
EGLNativeWindowType window,
EGLint width,
EGLint height)
: WindowSurfaceVk(surfaceState, window, width, height)
{}
WindowSurfaceVkFuchsia::~WindowSurfaceVkFuchsia() {}
// static
bool WindowSurfaceVkFuchsia::isValidNativeWindow(EGLNativeWindowType window)
{
fuchsia_egl_window *egl_window = reinterpret_cast<fuchsia_egl_window *>(window);
return fuchsia_egl_window_get_width(egl_window) >= 0;
}
angle::Result WindowSurfaceVkFuchsia::createSurfaceVk(vk::Context *context, gl::Extents *extentsOut)
{
InitImagePipeSurfaceFUCHSIAFunctions(context->getRenderer()->getInstance());
fuchsia_egl_window *egl_window = reinterpret_cast<fuchsia_egl_window *>(mNativeWindowType);
VkImagePipeSurfaceCreateInfoFUCHSIA createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA;
createInfo.imagePipeHandle = fuchsia_egl_window_release_image_pipe(egl_window);
ANGLE_VK_TRY(context, vkCreateImagePipeSurfaceFUCHSIA(context->getRenderer()->getInstance(),
&createInfo, nullptr, &mSurface));
return getCurrentWindowSize(context, extentsOut);
}
angle::Result WindowSurfaceVkFuchsia::getCurrentWindowSize(vk::Context *context,
gl::Extents *extentsOut)
{
fuchsia_egl_window *egl_window = reinterpret_cast<fuchsia_egl_window *>(mNativeWindowType);
int32_t width = fuchsia_egl_window_get_width(egl_window);
int32_t height = fuchsia_egl_window_get_height(egl_window);
*extentsOut = gl::Extents(width, height, 0);
return angle::Result::Continue;
}
} // namespace rx

View File

@@ -0,0 +1,36 @@
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// WindowSurfaceVkFuchsia.h:
// Subclasses WindowSurfaceVk for the Fuchsia platform.
//
#ifndef LIBANGLE_RENDERER_VULKAN_FUCHSIA_WINDOWSURFACEVKFUCHSIA_H_
#define LIBANGLE_RENDERER_VULKAN_FUCHSIA_WINDOWSURFACEVKFUCHSIA_H_
#include "libANGLE/renderer/vulkan/SurfaceVk.h"
namespace rx
{
class WindowSurfaceVkFuchsia : public WindowSurfaceVk
{
public:
WindowSurfaceVkFuchsia(const egl::SurfaceState &surfaceState,
EGLNativeWindowType window,
EGLint width,
EGLint height);
~WindowSurfaceVkFuchsia() override;
static bool isValidNativeWindow(EGLNativeWindowType window);
private:
angle::Result createSurfaceVk(vk::Context *context, gl::Extents *extentsOut) override;
angle::Result getCurrentWindowSize(vk::Context *context, gl::Extents *extentsOut) override;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_FUCHSIA_WINDOWSURFACEVKFUCHSIA_H_

View File

@@ -480,6 +480,11 @@ PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = nullptr;
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = nullptr;
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = nullptr;
#if defined(ANGLE_PLATFORM_FUCHSIA)
// VK_FUCHSIA_imagepipe_surface
PFN_vkCreateImagePipeSurfaceFUCHSIA vkCreateImagePipeSurfaceFUCHSIA = nullptr;
#endif
#define GET_FUNC(vkName) \
do \
{ \
@@ -499,6 +504,13 @@ void InitDebugReportEXTFunctions(VkInstance instance)
GET_FUNC(vkDestroyDebugReportCallbackEXT);
}
#if defined(ANGLE_PLATFORM_FUCHSIA)
void InitImagePipeSurfaceFUCHSIAFunctions(VkInstance instance)
{
GET_FUNC(vkCreateImagePipeSurfaceFUCHSIA);
}
#endif
#undef GET_FUNC
namespace gl_vk

View File

@@ -391,6 +391,12 @@ extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
void InitDebugUtilsEXTFunctions(VkInstance instance);
void InitDebugReportEXTFunctions(VkInstance instance);
#if defined(ANGLE_PLATFORM_FUCHSIA)
// VK_FUCHSIA_imagepipe_surface
extern PFN_vkCreateImagePipeSurfaceFUCHSIA vkCreateImagePipeSurfaceFUCHSIA;
void InitImagePipeSurfaceFUCHSIAFunctions(VkInstance instance);
#endif
namespace gl_vk
{
VkRect2D GetRect(const gl::Rectangle &source);

View File

@@ -835,6 +835,13 @@ libangle_vulkan_xcb_sources = [
"src/libANGLE/renderer/vulkan/xcb/WindowSurfaceVkXcb.h",
]
libangle_vulkan_fuchsia_sources = [
"src/libANGLE/renderer/vulkan/fuchsia/DisplayVkFuchsia.cpp",
"src/libANGLE/renderer/vulkan/fuchsia/DisplayVkFuchsia.h",
"src/libANGLE/renderer/vulkan/fuchsia/WindowSurfaceVkFuchsia.cpp",
"src/libANGLE/renderer/vulkan/fuchsia/WindowSurfaceVkFuchsia.h",
]
libangle_null_sources = [
"src/libANGLE/renderer/null/BufferNULL.cpp",
"src/libANGLE/renderer/null/BufferNULL.h",

View File

@@ -39,6 +39,12 @@ if (build_with_chromium) {
]
public_configs += [ ":angle_internal_gtest_config" ]
configs -= [ "${angle_root}:extra_warnings" ]
if (is_fuchsia) {
deps = [
"//third_party/fuchsia-sdk/sdk:fdio",
"//third_party/fuchsia-sdk/sdk:zx",
]
}
}
config("angle_internal_gmock_config") {
@@ -67,10 +73,14 @@ if (build_with_chromium) {
"//src/tests:angle_end2end_tests",
"//src/tests:angle_perftests",
"//src/tests:angle_unittests",
"//src/tests:angle_white_box_perftests",
"//src/tests:angle_white_box_tests",
]
if (build_angle_deqp_tests) {
if (!is_fuchsia) {
deps += [
"//src/tests:angle_white_box_perftests",
"//src/tests:angle_white_box_tests",
]
}
if (build_angle_deqp_tests && !is_fuchsia) {
deps += [
"//src/tests:angle_deqp_egl_no_gtest",
"//src/tests:angle_deqp_egl_tests",
@@ -141,7 +151,7 @@ angle_test("angle_unittests") {
]
}
if (is_win || is_linux || is_mac || is_android) {
if (is_win || is_linux || is_mac || is_android || is_fuchsia) {
import("angle_end2end_tests.gni")
angle_test("angle_end2end_tests") {
@@ -187,7 +197,9 @@ if (is_win || is_linux || is_mac || is_android) {
use_native_activity = true
}
}
}
if (is_win || is_linux || is_mac || is_android) {
import("angle_white_box_tests.gni")
angle_test("angle_white_box_tests") {
@@ -259,6 +271,10 @@ if (is_win || is_linux || is_android || is_mac) {
use_native_activity = true
}
}
}
if (is_win || is_linux || is_android || is_mac || is_fuchsia) {
import("angle_perftests.gni")
# This test suite is designed to run against a generic GL implementation.
angle_test("angle_perftests") {
@@ -517,7 +533,7 @@ if (build_angle_gles1_conform_tests) {
### dEQP tests
###-----------------------------------------------------
if (build_angle_deqp_tests) {
if (build_angle_deqp_tests && !is_fuchsia) {
import("deqp.gni")
angle_tests_main("angle_deqp_tests_main") {

View File

@@ -122,6 +122,15 @@ bool IsWindows()
#endif
}
bool IsFuchsia()
{
#if defined(ANGLE_PLATFORM_FUCHSIA)
return true;
#else
return false;
#endif
}
bool IsConfigWhitelisted(const SystemInfo &systemInfo, const PlatformParameters &param)
{
VendorID vendorID = systemInfo.gpus[systemInfo.primaryGPUIndex].vendorId;
@@ -191,6 +200,17 @@ bool IsConfigWhitelisted(const SystemInfo &systemInfo, const PlatformParameters
return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE);
}
if (IsFuchsia())
{
// Currently we only support the Vulkan back-end on Fuchsia.
if (param.driver != GLESDriverType::AngleEGL)
{
return false;
}
return (param.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
}
if (IsOzone())
{
// Currently we only support the GLES back-end on Ozone.

View File

@@ -23,6 +23,7 @@ bool IsLinux();
bool IsOSX();
bool IsOzone();
bool IsWindows();
bool IsFuchsia();
bool IsPlatformAvailable(const PlatformParameters &param);

View File

@@ -9,6 +9,10 @@
import("../../gni/angle.gni")
import("$angle_root/third_party/vulkan-headers/vulkan_headers_script_deps.gni")
# Fuchsia has non-upstream changes to the vulkan loader, so we don't want
# to build it from upstream sources.
assert(!is_fuchsia)
if (!is_android) {
vulkan_undefine_configs = []
}

View File

@@ -10,6 +10,10 @@ import("../../gni/angle.gni")
import("$angle_root/third_party/vulkan-headers/vulkan_headers_script_deps.gni")
# Vulkan-tools isn't ported to Fuchsia yet.
# TODO(spang): Port mock ICD to Fuchsia.
assert(!is_fuchsia)
vulkan_undefine_configs = []
if (is_win) {
vulkan_undefine_configs += [

View File

@@ -8,6 +8,10 @@
import("../../gni/angle.gni")
# Fuchsia has non-upstream changes to the vulkan layers, so we don't want
# to build it from upstream sources.
assert(!is_fuchsia)
import("$angle_root/third_party/vulkan-headers/vulkan_headers_script_deps.gni")
vulkan_undefine_configs = []

View File

@@ -305,6 +305,8 @@ bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow, angle::Library *
surfaceAttributes.push_back(EGL_NONE);
osWindow->resetNativeWindow();
mSurface = eglCreateWindowSurface(mDisplay, mConfig, osWindow->getNativeWindow(),
&surfaceAttributes[0]);
if (eglGetError() != EGL_SUCCESS || (mSurface == EGL_NO_SURFACE))

View File

@@ -39,6 +39,12 @@ class ANGLE_UTIL_EXPORT OSWindow
// just grab the pixels of the window. Returns if it was successful.
virtual bool takeScreenshot(uint8_t *pixelData);
// Re-initializes the native window. This is used on platforms which do not
// have a reusable EGLNativeWindowType in order to recreate it, and is
// needed by the test suite because it re-uses the same OSWindow for
// multiple EGLSurfaces.
virtual void resetNativeWindow() = 0;
virtual EGLNativeWindowType getNativeWindow() const = 0;
virtual EGLNativeDisplayType getNativeDisplay() const = 0;

View File

@@ -31,6 +31,8 @@ bool AndroidWindow::initialize(const std::string &name, size_t width, size_t hei
}
void AndroidWindow::destroy() {}
void AndroidWindow::resetNativeWindow() {}
EGLNativeWindowType AndroidWindow::getNativeWindow() const
{
// Return the entire Activity Surface for now

View File

@@ -20,6 +20,7 @@ class AndroidWindow : public OSWindow
bool initialize(const std::string &name, size_t width, size_t height) override;
void destroy() override;
void resetNativeWindow() override;
EGLNativeWindowType getNativeWindow() const override;
EGLNativeDisplayType getNativeDisplay() const override;

View File

@@ -0,0 +1,184 @@
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ScenicWindow.cpp:
// Implements methods from ScenicWindow
//
#include "util/fuchsia/ScenicWindow.h"
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/util.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/zx/channel.h>
#include <zircon/status.h>
#include "common/debug.h"
namespace
{
async::Loop *GetDefaultLoop()
{
static async::Loop *defaultLoop = new async::Loop(&kAsyncLoopConfigAttachToThread);
return defaultLoop;
}
zx::channel ConnectToServiceRoot()
{
zx::channel clientChannel;
zx::channel serverChannel;
zx_status_t result = zx::channel::create(0, &clientChannel, &serverChannel);
ASSERT(result == ZX_OK);
result = fdio_service_connect("/svc/.", serverChannel.release());
ASSERT(result == ZX_OK);
return clientChannel;
}
template <typename Interface>
zx_status_t ConnectToService(zx_handle_t serviceRoot, fidl::InterfaceRequest<Interface> request)
{
ASSERT(request.is_valid());
return fdio_service_connect_at(serviceRoot, Interface::Name_, request.TakeChannel().release());
}
template <typename Interface>
fidl::InterfacePtr<Interface> ConnectToService(zx_handle_t serviceRoot)
{
fidl::InterfacePtr<Interface> result;
ConnectToService(serviceRoot, result.NewRequest());
return result;
}
} // namespace
ScenicWindow::ScenicWindow()
: mLoop(GetDefaultLoop()),
mServiceRoot(ConnectToServiceRoot()),
mScenic(ConnectToService<fuchsia::ui::scenic::Scenic>(mServiceRoot.get())),
mViewManager(ConnectToService<fuchsia::ui::viewsv1::ViewManager>(mServiceRoot.get())),
mPresenter(ConnectToService<fuchsia::ui::policy::Presenter>(mServiceRoot.get())),
mScenicSession(mScenic.get()),
mParent(&mScenicSession),
mShape(&mScenicSession),
mMaterial(&mScenicSession),
mViewListenerBinding(this)
{}
ScenicWindow::~ScenicWindow()
{
destroy();
}
bool ScenicWindow::initialize(const std::string &name, size_t width, size_t height)
{
// Set up scenic resources.
zx::eventpair parentExportToken;
mParent.BindAsRequest(&parentExportToken);
mParent.SetEventMask(fuchsia::ui::gfx::kMetricsEventMask);
mParent.AddChild(mShape);
mShape.SetShape(scenic::Rectangle(&mScenicSession, width, height));
mShape.SetMaterial(mMaterial);
// Create view and present it.
zx::eventpair viewHolderToken;
zx::eventpair viewToken;
zx_status_t status = zx::eventpair::create(0 /* options */, &viewToken, &viewHolderToken);
ASSERT(status == ZX_OK);
mPresenter->Present2(std::move(viewHolderToken), nullptr);
mViewManager->CreateView2(mView.NewRequest(), std::move(viewToken),
mViewListenerBinding.NewBinding(), std::move(parentExportToken),
name);
mView.set_error_handler(fit::bind_member(this, &ScenicWindow::OnScenicError));
mViewListenerBinding.set_error_handler(fit::bind_member(this, &ScenicWindow::OnScenicError));
mWidth = width;
mHeight = height;
resetNativeWindow();
return true;
}
void ScenicWindow::destroy()
{
mFuchsiaEGLWindow.reset();
}
void ScenicWindow::resetNativeWindow()
{
fuchsia::images::ImagePipePtr imagePipe;
uint32_t imagePipeId = mScenicSession.AllocResourceId();
mScenicSession.Enqueue(scenic::NewCreateImagePipeCmd(imagePipeId, imagePipe.NewRequest()));
mMaterial.SetTexture(imagePipeId);
mScenicSession.ReleaseResource(imagePipeId);
mScenicSession.Present(0, [](fuchsia::images::PresentationInfo info) {});
mFuchsiaEGLWindow.reset(
fuchsia_egl_window_create(imagePipe.Unbind().TakeChannel().release(), mWidth, mHeight));
}
EGLNativeWindowType ScenicWindow::getNativeWindow() const
{
return reinterpret_cast<EGLNativeWindowType>(mFuchsiaEGLWindow.get());
}
EGLNativeDisplayType ScenicWindow::getNativeDisplay() const
{
return EGL_DEFAULT_DISPLAY;
}
void ScenicWindow::messageLoop()
{
mLoop->Run(zx::deadline_after({}), true /* once */);
}
void ScenicWindow::setMousePosition(int x, int y)
{
UNIMPLEMENTED();
}
bool ScenicWindow::setPosition(int x, int y)
{
UNIMPLEMENTED();
return false;
}
bool ScenicWindow::resize(int width, int height)
{
mWidth = width;
mHeight = height;
fuchsia_egl_window_resize(mFuchsiaEGLWindow.get(), width, height);
return true;
}
void ScenicWindow::setVisible(bool isVisible) {}
void ScenicWindow::signalTestEvent() {}
void ScenicWindow::OnPropertiesChanged(fuchsia::ui::viewsv1::ViewProperties properties,
OnPropertiesChangedCallback callback)
{
UNIMPLEMENTED();
}
void ScenicWindow::OnScenicEvents(std::vector<fuchsia::ui::scenic::Event> events)
{
UNIMPLEMENTED();
}
void ScenicWindow::OnScenicError(zx_status_t status)
{
WARN() << "OnScenicError: " << zx_status_get_string(status);
}
// static
OSWindow *OSWindow::New()
{
return new ScenicWindow;
}

View File

@@ -0,0 +1,83 @@
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ScenicWindow.h:
// Subclasses OSWindow for Fuchsia's Scenic compositor.
//
#ifndef UTIL_FUCHSIA_SCENIC_WINDOW_H
#define UTIL_FUCHSIA_SCENIC_WINDOW_H
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <fuchsia/ui/viewsv1/cpp/fidl.h>
#include <fuchsia_egl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/ui/scenic/cpp/commands.h>
#include <lib/ui/scenic/cpp/resources.h>
#include <lib/ui/scenic/cpp/session.h>
#include <zircon/types.h>
#include <string>
#include "util/OSWindow.h"
#include "util/util_export.h"
struct FuchsiaEGLWindowDeleter
{
void operator()(fuchsia_egl_window *eglWindow) { fuchsia_egl_window_destroy(eglWindow); }
};
class ANGLE_UTIL_EXPORT ScenicWindow : public OSWindow, public fuchsia::ui::viewsv1::ViewListener
{
public:
ScenicWindow();
~ScenicWindow();
// OSWindow:
bool initialize(const std::string &name, size_t width, size_t height) override;
void destroy() override;
void resetNativeWindow() override;
EGLNativeWindowType getNativeWindow() const override;
EGLNativeDisplayType getNativeDisplay() const override;
void messageLoop() override;
void setMousePosition(int x, int y) override;
bool setPosition(int x, int y) override;
bool resize(int width, int height) override;
void setVisible(bool isVisible) override;
void signalTestEvent() override;
// views::ViewListener:
void OnPropertiesChanged(fuchsia::ui::viewsv1::ViewProperties properties,
OnPropertiesChangedCallback callback) override;
// FIDL callbacks:
void OnScenicEvents(std::vector<fuchsia::ui::scenic::Event> events);
void OnScenicError(zx_status_t status);
private:
// Default message loop.
async::Loop *mLoop;
// System services.
zx::channel mServiceRoot;
fuchsia::ui::scenic::ScenicPtr mScenic;
fuchsia::ui::viewsv1::ViewManagerPtr mViewManager;
fuchsia::ui::policy::PresenterPtr mPresenter;
// Scenic session & resources.
scenic::Session mScenicSession;
scenic::ImportNode mParent;
scenic::ShapeNode mShape;
scenic::Material mMaterial;
// Scenic view & listener.
fuchsia::ui::viewsv1::ViewPtr mView;
fidl::Binding<fuchsia::ui::viewsv1::ViewListener> mViewListenerBinding;
// EGL native window.
std::unique_ptr<fuchsia_egl_window, FuchsiaEGLWindowDeleter> mFuchsiaEGLWindow;
};
#endif // UTIL_FUCHSIA_SCENIC_WINDOW_H

View File

@@ -38,6 +38,7 @@ class OSXWindow : public OSWindow
bool initialize(const std::string &name, size_t width, size_t height) override;
void destroy() override;
void resetNativeWindow() override;
EGLNativeWindowType getNativeWindow() const override;
EGLNativeDisplayType getNativeDisplay() const override;

View File

@@ -679,6 +679,8 @@ void OSXWindow::destroy()
mWindow = nil;
}
void OSXWindow::resetNativeWindow() {}
EGLNativeWindowType OSXWindow::getNativeWindow() const
{
return [mView layer];

View File

@@ -29,6 +29,8 @@ bool OzoneWindow::initialize(const std::string &name, size_t width, size_t heigh
void OzoneWindow::destroy() {}
void OzoneWindow::resetNativeWindow() {}
EGLNativeWindowType OzoneWindow::getNativeWindow() const
{
return reinterpret_cast<EGLNativeWindowType>(&mNative);

View File

@@ -22,6 +22,7 @@ class OzoneWindow : public OSWindow
bool initialize(const std::string &name, size_t width, size_t height) override;
void destroy() override;
void resetNativeWindow() override;
EGLNativeWindowType getNativeWindow() const override;
EGLNativeDisplayType getNativeDisplay() const override;

View File

@@ -4,12 +4,12 @@
// found in the LICENSE file.
//
// LinuxTimer.cpp: Implementation of a high precision timer class on Linux
// PosixTimer.cpp: Implementation of a high precision timer class on POSIX
#include "util/linux/LinuxTimer.h"
#include "util/posix/PosixTimer.h"
#include <iostream>
LinuxTimer::LinuxTimer() : mRunning(false) {}
PosixTimer::PosixTimer() : mRunning(false) {}
namespace
{
@@ -21,19 +21,19 @@ uint64_t getCurrentTimeNs()
}
} // anonymous namespace
void LinuxTimer::start()
void PosixTimer::start()
{
mStartTimeNs = getCurrentTimeNs();
mRunning = true;
}
void LinuxTimer::stop()
void PosixTimer::stop()
{
mStopTimeNs = getCurrentTimeNs();
mRunning = false;
}
double LinuxTimer::getElapsedTime() const
double PosixTimer::getElapsedTime() const
{
uint64_t endTimeNs;
if (mRunning)
@@ -48,12 +48,12 @@ double LinuxTimer::getElapsedTime() const
return (endTimeNs - mStartTimeNs) * 1e-9;
}
double LinuxTimer::getAbsoluteTime()
double PosixTimer::getAbsoluteTime()
{
return getCurrentTimeNs() * 1e-9;
}
Timer *CreateTimer()
{
return new LinuxTimer();
return new PosixTimer();
}

View File

@@ -4,20 +4,20 @@
// found in the LICENSE file.
//
// LinuxTimer.h: Definition of a high precision timer class on Linux
// PosixTimer.h: Definition of a high precision timer class on Linux
#ifndef UTIL_LINUX_TIMER_H
#define UTIL_LINUX_TIMER_H
#ifndef UTIL_POSIX_TIMER_H
#define UTIL_POSIX_TIMER_H
#include <stdint.h>
#include <time.h>
#include "util/Timer.h"
class ANGLE_UTIL_EXPORT LinuxTimer : public Timer
class ANGLE_UTIL_EXPORT PosixTimer : public Timer
{
public:
LinuxTimer();
PosixTimer();
void start() override;
void stop() override;
@@ -31,4 +31,4 @@ class ANGLE_UTIL_EXPORT LinuxTimer : public Timer
uint64_t mStopTimeNs;
};
#endif // UTIL_LINUX_TIMER_H
#endif // UTIL_POSIX_TIMER_H

View File

@@ -8,12 +8,15 @@
#include "util/system_utils.h"
#include <dlfcn.h>
#include <sched.h>
#include <sys/resource.h>
#include <time.h>
#include <unistd.h>
#if !defined(ANGLE_PLATFORM_FUCHSIA)
# include <dlfcn.h>
# include <sys/resource.h>
#endif
#include "common/platform.h"
namespace angle
@@ -40,7 +43,9 @@ void Sleep(unsigned int milliseconds)
void SetLowPriorityProcess()
{
#if !defined(ANGLE_PLATFORM_FUCHSIA)
setpriority(PRIO_PROCESS, getpid(), 10);
#endif
}
void WriteDebugMessage(const char *format, ...)
@@ -53,6 +58,7 @@ void WriteDebugMessage(const char *format, ...)
bool StabilizeCPUForBenchmarking()
{
#if !defined(ANGLE_PLATFORM_FUCHSIA)
bool success = true;
errno = 0;
setpriority(PRIO_PROCESS, getpid(), -20);
@@ -80,5 +86,8 @@ bool StabilizeCPUForBenchmarking()
#endif
return success;
#else // defined(ANGLE_PLATFORM_FUCHSIA)
return false;
#endif
}
} // namespace angle

View File

@@ -53,8 +53,8 @@ util_winrt_sources = [
]
util_linux_sources = [
"util/linux/LinuxTimer.cpp",
"util/linux/LinuxTimer.h",
"util/posix/PosixTimer.cpp",
"util/posix/PosixTimer.h",
"util/posix/Posix_system_utils.cpp",
]
@@ -65,6 +65,14 @@ util_x11_sources = [
"util/x11/X11Window.h",
]
util_fuchsia_sources = [
"util/posix/PosixTimer.cpp",
"util/posix/PosixTimer.h",
"util/posix/Posix_system_utils.cpp",
"util/fuchsia/ScenicWindow.cpp",
"util/fuchsia/ScenicWindow.h",
]
util_ozone_sources = [
"util/ozone/OzonePixmap.cpp",
"util/ozone/OzoneWindow.cpp",

View File

@@ -703,6 +703,8 @@ bool Win32Window::takeScreenshot(uint8_t *pixelData)
return !error;
}
void Win32Window::resetNativeWindow() {}
EGLNativeWindowType Win32Window::getNativeWindow() const
{
return mNativeWindow;

View File

@@ -26,6 +26,7 @@ class Win32Window : public OSWindow
bool takeScreenshot(uint8_t *pixelData) override;
void resetNativeWindow() override;
EGLNativeWindowType getNativeWindow() const override;
EGLNativeDisplayType getNativeDisplay() const override;

View File

@@ -217,6 +217,8 @@ void WinRTWindow::destroy()
mCoreDispatcher.Reset();
}
void WinRTWindow::resetNativeWindow() {}
EGLNativeWindowType WinRTWindow::getNativeWindow() const
{
return mNativeWindow;

View File

@@ -25,6 +25,7 @@ class WinRTWindow : public OSWindow
bool initialize(const std::string &name, size_t width, size_t height) override;
void destroy() override;
void resetNativeWindow() override;
EGLNativeWindowType getNativeWindow() const override;
EGLNativeDisplayType getNativeDisplay() const override;

View File

@@ -387,6 +387,8 @@ void X11Window::destroy()
WM_PROTOCOLS = None;
}
void X11Window::resetNativeWindow() {}
EGLNativeWindowType X11Window::getNativeWindow() const
{
return mWindow;

View File

@@ -27,6 +27,7 @@ class ANGLE_UTIL_EXPORT X11Window : public OSWindow
bool initialize(const std::string &name, size_t width, size_t height) override;
void destroy() override;
void resetNativeWindow() override;
EGLNativeWindowType getNativeWindow() const override;
EGLNativeDisplayType getNativeDisplay() const override;