blob: 1cd66fdb3c293534f120728ee01a0e0773f4c047 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_GL_GL_DISPLAY_H_
#define UI_GL_GL_DISPLAY_H_
#include <stdint.h>
#include <memory>
#include <vector>
#include "ui/gl/gl_export.h"
#if defined(USE_EGL)
#include <EGL/egl.h>
#include "ui/gl/gpu_switching_manager.h"
#endif // defined(USE_EGL)
#if BUILDFLAG(IS_APPLE)
#include "components/metal_util/types.h"
#endif
namespace gl {
struct DisplayExtensionsEGL;
template <typename GLDisplayPlatform>
class GLDisplayManager;
class EGLDisplayPlatform {
public:
constexpr EGLDisplayPlatform()
: display_(EGL_DEFAULT_DISPLAY), platform_(0), valid_(false) {}
explicit constexpr EGLDisplayPlatform(EGLNativeDisplayType display,
int platform = 0)
: display_(display), platform_(platform), valid_(true) {}
bool Valid() const { return valid_; }
int GetPlatform() const { return platform_; }
EGLNativeDisplayType GetDisplay() const { return display_; }
private:
EGLNativeDisplayType display_;
// 0 for default, or EGL_PLATFORM_* enum.
int platform_;
bool valid_;
};
// If adding a new type, also add it to EGLDisplayType in
// tools/metrics/histograms/enums.xml. Don't remove or reorder entries.
enum DisplayType {
DEFAULT = 0,
SWIFT_SHADER = 1,
ANGLE_WARP = 2,
ANGLE_D3D9 = 3,
ANGLE_D3D11 = 4,
ANGLE_OPENGL = 5,
ANGLE_OPENGLES = 6,
ANGLE_NULL = 7,
ANGLE_D3D11_NULL = 8,
ANGLE_OPENGL_NULL = 9,
ANGLE_OPENGLES_NULL = 10,
ANGLE_VULKAN = 11,
ANGLE_VULKAN_NULL = 12,
ANGLE_D3D11on12 = 13,
ANGLE_SWIFTSHADER = 14,
ANGLE_OPENGL_EGL = 15,
ANGLE_OPENGLES_EGL = 16,
ANGLE_METAL = 17,
ANGLE_METAL_NULL = 18,
DISPLAY_TYPE_MAX = 19,
};
enum DisplayPlatform {
NONE = 0,
EGL = 1,
};
class GL_EXPORT GLDisplay {
public:
GLDisplay(const GLDisplay&) = delete;
GLDisplay& operator=(const GLDisplay&) = delete;
uint64_t system_device_id() const { return system_device_id_; }
DisplayKey display_key() const { return display_key_; }
DisplayPlatform type() const { return type_; }
virtual ~GLDisplay();
virtual void* GetDisplay() const = 0;
virtual void Shutdown() = 0;
virtual bool IsInitialized() const = 0;
virtual bool Initialize(GLDisplay* display) = 0;
template <typename GLDisplayPlatform>
GLDisplayPlatform* GetAs();
protected:
GLDisplay(uint64_t system_device_id,
DisplayKey display_key,
DisplayPlatform type);
uint64_t system_device_id_ = 0;
DisplayKey display_key_ = DisplayKey::kDefault;
DisplayPlatform type_ = NONE;
};
#if defined(USE_EGL)
class GL_EXPORT GLDisplayEGL : public GLDisplay {
public:
GLDisplayEGL(const GLDisplayEGL&) = delete;
GLDisplayEGL& operator=(const GLDisplayEGL&) = delete;
~GLDisplayEGL() override;
static GLDisplayEGL* GetDisplayForCurrentContext();
EGLDisplay GetDisplay() const override;
void Shutdown() override;
bool IsInitialized() const override;
void SetDisplay(EGLDisplay display);
EGLDisplayPlatform GetNativeDisplay() const;
DisplayType GetDisplayType() const;
bool IsEGLSurfacelessContextSupported();
bool IsEGLContextPrioritySupported();
bool IsAndroidNativeFenceSyncSupported();
bool IsANGLEExternalContextAndSurfaceSupported();
bool Initialize(bool supports_angle,
std::vector<DisplayType> init_displays,
EGLDisplayPlatform native_display);
bool Initialize(GLDisplay* other_display) override;
void InitializeForTesting();
bool InitializeExtensionSettings();
std::unique_ptr<DisplayExtensionsEGL> ext;
#if BUILDFLAG(IS_APPLE)
bool IsANGLEMetalSharedEventSyncSupported();
bool CreateMetalSharedEvent(metal::MTLSharedEventPtr* shared_event_out,
uint64_t* signal_value_out);
void WaitForMetalSharedEvent(metal::MTLSharedEventPtr shared_event,
uint64_t signal_value);
// Call periodically to clean up resources.
void CleanupTempEGLSyncObjects();
// Call once upon shutdown of the display.
void CleanupMetalSharedEvent();
#endif
private:
friend class GLDisplayManager<GLDisplayEGL>;
friend class EGLApiTest;
class EGLGpuSwitchingObserver final : public ui::GpuSwitchingObserver {
public:
explicit EGLGpuSwitchingObserver(EGLDisplay display);
~EGLGpuSwitchingObserver() override = default;
void OnGpuSwitched(GpuPreference active_gpu_heuristic) override;
private:
EGLDisplay display_ = EGL_NO_DISPLAY;
};
GLDisplayEGL(uint64_t system_device_id, DisplayKey display_key);
bool InitializeDisplay(bool supports_angle,
std::vector<DisplayType> init_displays,
EGLDisplayPlatform native_display,
gl::GLDisplayEGL* existing_display);
void InitializeCommon(bool for_testing);
EGLDisplay display_ = EGL_NO_DISPLAY;
EGLDisplayPlatform native_display_ = EGLDisplayPlatform(EGL_DEFAULT_DISPLAY);
DisplayType display_type_ = DisplayType::DEFAULT;
bool egl_surfaceless_context_supported_ = false;
bool egl_context_priority_supported_ = false;
bool egl_android_native_fence_sync_supported_ = false;
std::unique_ptr<EGLGpuSwitchingObserver> gpu_switching_observer_;
#if BUILDFLAG(IS_APPLE)
metal::MTLSharedEventPtr metal_shared_event_ = nullptr;
uint64_t metal_signaled_value_ = 0;
#endif
};
#endif // defined(USE_EGL)
} // namespace gl
#endif // UI_GL_GL_DISPLAY_H_