chromium/third_party/angle/src/libANGLE/Display.cpp

//
// Copyright 2002 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.
//

// Display.cpp: Implements the egl::Display class, representing the abstract
// display on which graphics are drawn. Implements EGLDisplay.
// [EGL 1.4] section 2.1.2 page 3.

#include "libANGLE/Display.h"

#include <algorithm>
#include <iterator>
#include <sstream>
#include <vector>

#include <EGL/eglext.h>
#include <platform/PlatformMethods.h>

#include "anglebase/no_destructor.h"
#include "common/android_util.h"
#include "common/debug.h"
#include "common/mathutil.h"
#include "common/platform_helpers.h"
#include "common/string_utils.h"
#include "common/system_utils.h"
#include "common/tls.h"
#include "common/utilities.h"
#include "gpu_info_util/SystemInfo.h"
#include "image_util/loadimage.h"
#include "libANGLE/Context.h"
#include "libANGLE/Device.h"
#include "libANGLE/EGLSync.h"
#include "libANGLE/Image.h"
#include "libANGLE/ResourceManager.h"
#include "libANGLE/Stream.h"
#include "libANGLE/Surface.h"
#include "libANGLE/Thread.h"
#include "libANGLE/capture/FrameCapture.h"
#include "libANGLE/histogram_macros.h"
#include "libANGLE/renderer/DeviceImpl.h"
#include "libANGLE/renderer/DisplayImpl.h"
#include "libANGLE/renderer/ImageImpl.h"
#include "libANGLE/trace.h"

#if defined(ANGLE_PLATFORM_APPLE)
#    include <dispatch/dispatch.h>
#    include "common/tls.h"
#endif

#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
#    include "libANGLE/renderer/d3d/DisplayD3D.h"
#endif

#if defined(ANGLE_ENABLE_OPENGL)
#    if defined(ANGLE_PLATFORM_WINDOWS)
#        include "libANGLE/renderer/gl/wgl/DisplayWGL.h"
#    elif ANGLE_ENABLE_CGL
#        include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
#    elif ANGLE_ENABLE_EAGL
#        include "libANGLE/renderer/gl/eagl/DisplayEAGL.h"
#    elif defined(ANGLE_PLATFORM_LINUX)
#        include "libANGLE/renderer/gl/egl/DisplayEGL.h"
#        if defined(ANGLE_USE_X11)
#            include "libANGLE/renderer/gl/glx/DisplayGLX_api.h"
#        endif
#    elif defined(ANGLE_PLATFORM_ANDROID)
#        include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h"
#    else
#        error Unsupported OpenGL platform.
#    endif
#endif

#if defined(ANGLE_ENABLE_NULL)
#    include "libANGLE/renderer/null/DisplayNULL.h"
#endif  // defined(ANGLE_ENABLE_NULL)

#if defined(ANGLE_ENABLE_WGPU)
#    include "libANGLE/renderer/wgpu/DisplayWgpu_api.h"
#endif

#if defined(ANGLE_ENABLE_VULKAN)
#    include "libANGLE/renderer/vulkan/DisplayVk_api.h"
#endif  // defined(ANGLE_ENABLE_VULKAN)

#if defined(ANGLE_ENABLE_METAL)
#    include "libANGLE/renderer/metal/DisplayMtl_api.h"
#endif  // defined(ANGLE_ENABLE_METAL)

namespace egl
{

namespace
{
struct TLSData
{};

TLSData::TLSData() :{}

#if defined(ANGLE_PLATFORM_APPLE)
// TODO(angleproject:6479): Due to a bug in Apple's dyld loader, `thread_local` will cause
// excessive memory use. Temporarily avoid it by using pthread's thread
// local storage instead.
static angle::TLSIndex GetDisplayTLSIndex()
{
    static angle::TLSIndex DisplayIndex = TLS_INVALID_INDEX;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
      ASSERT(DisplayIndex == TLS_INVALID_INDEX);
      DisplayIndex = angle::CreateTLSIndex(nullptr);
    });
    return DisplayIndex;
}
TLSData *GetDisplayTLS()
{
    angle::TLSIndex DisplayIndex = GetDisplayTLSIndex();
    ASSERT(DisplayIndex != TLS_INVALID_INDEX);
    return static_cast<TLSData *>(angle::GetTLSValue(DisplayIndex));
}
void SetDisplayTLS(TLSData *tlsData)
{
    angle::TLSIndex DisplayIndex = GetDisplayTLSIndex();
    ASSERT(DisplayIndex != TLS_INVALID_INDEX);
    angle::SetTLSValue(DisplayIndex, tlsData);
}
#else
// Tail calls generated during execution of the entry point, to be run at the end of the entry
// point.  gTLSData->unlockedTailCall.run() is called at the end of any EGL entry point that is
// expected to generate such calls.  At the end of every other call, it is asserted that this is
// empty.
thread_local TLSData *gDisplayTLS =;

TLSData *GetDisplayTLS()
{}
#endif

constexpr angle::SubjectIndex kGPUSwitchedSubjectIndex =;

static constexpr size_t kWindowSurfaceMapSize =;
WindowSurfaceMap;
// Get a map of all EGL window surfaces to validate that no window has more than one EGL surface
// associated with it.
static WindowSurfaceMap *GetWindowSurfaces()
{}

size_t EGLStringArrayHash(const char **ary)
{}

struct ANGLEPlatformDisplay
{};

inline bool operator==(const ANGLEPlatformDisplay &a, const ANGLEPlatformDisplay &b)
{}

static constexpr size_t kANGLEPlatformDisplayMapSize =;
ANGLEPlatformDisplayMap;
static ANGLEPlatformDisplayMap *GetANGLEPlatformDisplayMap()
{}

static constexpr size_t kDevicePlatformDisplayMapSize =;
DevicePlatformDisplayMap;
static DevicePlatformDisplayMap *GetDevicePlatformDisplayMap()
{}

rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice, const DisplayState &state)
{}

// On platforms with support for multiple back-ends, allow an environment variable to control
// the default.  This is useful to run angle with benchmarks without having to modify the
// benchmark source.  Possible values for this environment variable (ANGLE_DEFAULT_PLATFORM)
// are: vulkan, gl, d3d11, null.
EGLAttrib GetDisplayTypeFromEnvironment()
{}

EGLAttrib GetDeviceTypeFromEnvironment()
{}

EGLAttrib GetPlatformTypeFromEnvironment()
{}

rx::DisplayImpl *CreateDisplayFromAttribs(EGLAttrib displayType,
                                          EGLAttrib deviceType,
                                          EGLAttrib platformType,
                                          const DisplayState &state)
{}

void Display_logError(angle::PlatformMethods *platform, const char *errorMessage)
{}

void Display_logWarning(angle::PlatformMethods *platform, const char *warningMessage)
{}

void Display_logInfo(angle::PlatformMethods *platform, const char *infoMessage)
{}

const std::vector<std::string> EGLStringArrayToStringVector(const char **ary)
{}

void ANGLESetDefaultDisplayPlatform(angle::EGLDisplayType display)
{}

void UpdateAttribsFromEnvironment(AttributeMap &attribMap)
{}

static constexpr uint32_t kScratchBufferLifetime =;

}  // anonymous namespace

// DisplayState
DisplayState::DisplayState(EGLNativeDisplayType nativeDisplayId)
    :{}

DisplayState::~DisplayState() {}

void DisplayState::notifyDeviceLost() const
{}

// Note that ANGLE support on Ozone platform is limited. Our preferred support Matrix for
// EGL_ANGLE_platform_angle on Linux and Ozone/Linux/Fuchsia platforms should be the following:
//
// |--------------------------------------------------------|
// | ANGLE type | DEVICE type |  PLATFORM type   | Display  |
// |--------------------------------------------------------|
// |   OPENGL   |     EGL     |       ANY        |   EGL    |
// |   OPENGL   |   HARDWARE  |     X11_EXT      |   GLX    |
// |  OPENGLES  |   HARDWARE  |     X11_EXT      |   GLX    |
// |  OPENGLES  |     EGL     |       ANY        |   EGL    |
// |   VULKAN   |   HARDWARE  |     X11_EXT      |  VkXcb   |
// |   VULKAN   | SWIFTSHADER |     X11_EXT      |  VkXcb   |
// |  OPENGLES  |   HARDWARE  | SURFACELESS_MESA |   EGL*   |
// |  OPENGLES  |   HARDWARE  |    DEVICE_EXT    |   EGL    |
// |   VULKAN   |   HARDWARE  | SURFACELESS_MESA | VkBase** |
// |   VULKAN   | SWIFTSHADER | SURFACELESS_MESA | VkBase** |
// |--------------------------------------------------------|
//
// * No surfaceless support yet.
// ** Not implemented yet.
//
// |-----------------------------------------------|
// |   OS    | BUILD type |  Default PLATFORM type |
// |-----------------------------------------------|
// |  Linux  |    X11     |        X11_EXT         |
// |  Linux  |   Ozone    |    SURFACELESS_MESA    |
// | Fuchsia |   Ozone    |        FUCHSIA***      |
// |-----------------------------------------------|
//
// *** Chosen implicitly. No EGLAttrib available.
//
// For more details, please refer to
// https://docs.google.com/document/d/1XjHiDZQISq1AMrg_l1TX1_kIKvDpU76hidn9i4cAjl8/edit?disco=AAAAJl9V_YY
//
// static
Display *Display::GetDisplayFromNativeDisplay(EGLenum platform,
                                              EGLNativeDisplayType nativeDisplay,
                                              const AttributeMap &attribMap)
{}

// static
Display *Display::GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay)
{}

// static
Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attribMap)
{}

// static
Display::EglDisplaySet Display::GetEglDisplaySet()
{}

Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice)
    :{}

Display::~Display()
{}

void Display::setLabel(EGLLabelKHR label)
{}

EGLLabelKHR Display::getLabel() const
{}

void Display::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
{}

void Display::setupDisplayPlatform(rx::DisplayImpl *impl)
{}

Error Display::initialize()
{}

Error Display::destroyInvalidEglObjects()
{}

Error Display::terminate(Thread *thread, TerminateReason terminateReason)
{}

#if ANGLE_USE_DISPLAY_PREPARE_FOR_CALL
Error Display::prepareForCall()
{
    return mImplementation->prepareForCall();
}
#endif

Error Display::releaseThread()
{}

std::vector<const Config *> Display::getConfigs(const egl::AttributeMap &attribs) const
{}

std::vector<const Config *> Display::chooseConfig(const egl::AttributeMap &attribs) const
{}

Error Display::createWindowSurface(const Config *configuration,
                                   EGLNativeWindowType window,
                                   const AttributeMap &attribs,
                                   Surface **outSurface)
{}

Error Display::createPbufferSurface(const Config *configuration,
                                    const AttributeMap &attribs,
                                    Surface **outSurface)
{}

Error Display::createPbufferFromClientBuffer(const Config *configuration,
                                             EGLenum buftype,
                                             EGLClientBuffer clientBuffer,
                                             const AttributeMap &attribs,
                                             Surface **outSurface)
{}

Error Display::createPixmapSurface(const Config *configuration,
                                   NativePixmapType nativePixmap,
                                   const AttributeMap &attribs,
                                   Surface **outSurface)
{}

Error Display::createImage(const gl::Context *context,
                           EGLenum target,
                           EGLClientBuffer buffer,
                           const AttributeMap &attribs,
                           Image **outImage)
{}

Error Display::createStream(const AttributeMap &attribs, Stream **outStream)
{}

Error Display::createContext(const Config *configuration,
                             gl::Context *shareContext,
                             EGLenum clientType,
                             const AttributeMap &attribs,
                             gl::Context **outContext)
{}

Error Display::createSync(const gl::Context *currentContext,
                          EGLenum type,
                          const AttributeMap &attribs,
                          Sync **outSync)
{}

Error Display::makeCurrent(Thread *thread,
                           gl::Context *previousContext,
                           egl::Surface *drawSurface,
                           egl::Surface *readSurface,
                           gl::Context *context)
{}

Error Display::restoreLostDevice()
{}

Error Display::destroySurfaceImpl(Surface *surface, SurfaceMap *surfaces)
{}

void Display::destroyImageImpl(Image *image, ImageMap *images)
{}

void Display::destroyStreamImpl(Stream *stream, StreamSet *streams)
{}

// releaseContext must be called with the context being deleted as current.
// To do that we can only call this in two places, Display::makeCurrent at the point where this
// context is being made uncurrent and in Display::destroyContext where we make the context current
// as part of destruction.
Error Display::releaseContext(gl::Context *context, Thread *thread)
{}

Error Display::releaseContextImpl(gl::Context *context, ContextMap *contexts)
{}

Error Display::destroyContext(Thread *thread, gl::Context *context)
{}

void Display::destroySyncImpl(SyncID syncId, SyncMap *syncs)
{}

void Display::destroyImage(Image *image)
{}

void Display::destroyStream(Stream *stream)
{}

Error Display::destroySurface(Surface *surface)
{}

void Display::destroySync(Sync *sync)
{}

bool Display::isDeviceLost() const
{}

bool Display::testDeviceLost()
{}

void Display::notifyDeviceLost()
{}

void Display::setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get)
{}

// static
EGLClientBuffer Display::GetNativeClientBuffer(const AHardwareBuffer *buffer)
{}

// static
Error Display::CreateNativeClientBuffer(const egl::AttributeMap &attribMap,
                                        EGLClientBuffer *eglClientBuffer)
{}

Error Display::waitClient(const gl::Context *context)
{}

Error Display::waitNative(const gl::Context *context, EGLint engine)
{}

const Caps &Display::getCaps() const
{}

bool Display::isInitialized() const
{}

bool Display::isValidConfig(const Config *config) const
{}

bool Display::isValidContext(const gl::ContextID contextID) const
{}

bool Display::isValidSurface(SurfaceID surfaceID) const
{}

bool Display::isValidImage(ImageID imageID) const
{}

bool Display::isValidStream(const Stream *stream) const
{}

bool Display::isValidSync(SyncID syncID) const
{}

bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
{}

static ClientExtensions GenerateClientExtensions()
{}

template <typename T>
static std::string GenerateExtensionsString(const T &extensions)
{}

// static
const ClientExtensions &Display::GetClientExtensions()
{}

// static
const std::string &Display::GetClientExtensionString()
{}

void Display::initDisplayExtensions()
{}

bool Display::isValidNativeWindow(EGLNativeWindowType window) const
{}

Error Display::validateClientBuffer(const Config *configuration,
                                    EGLenum buftype,
                                    EGLClientBuffer clientBuffer,
                                    const AttributeMap &attribs) const
{}

Error Display::validateImageClientBuffer(const gl::Context *context,
                                         EGLenum target,
                                         EGLClientBuffer clientBuffer,
                                         const egl::AttributeMap &attribs) const
{}

Error Display::valdiatePixmap(const Config *config,
                              EGLNativePixmapType pixmap,
                              const AttributeMap &attributes) const
{}

bool Display::isValidDisplay(const egl::Display *display)
{}

bool Display::isValidNativeDisplay(EGLNativeDisplayType display)
{}

void Display::initVendorString()
{}

void Display::initVersionString()
{}

void Display::initClientAPIString()
{}

void Display::initializeFrontendFeatures()
{}

const DisplayExtensions &Display::getExtensions() const
{}

const std::string &Display::getExtensionString() const
{}

const std::string &Display::getVendorString() const
{}

const std::string &Display::getVersionString() const
{}

const std::string &Display::getClientAPIString() const
{}

std::string Display::getBackendRendererDescription() const
{}

std::string Display::getBackendVendorString() const
{}

std::string Display::getBackendVersionString(bool includeFullVersion) const
{}

Device *Display::getDevice() const
{}

Surface *Display::getWGLSurface() const
{}

gl::Version Display::getMaxSupportedESVersion() const
{}

EGLint Display::programCacheGetAttrib(EGLenum attrib) const
{}

Error Display::programCacheQuery(EGLint index,
                                 void *key,
                                 EGLint *keysize,
                                 void *binary,
                                 EGLint *binarysize)
{}

Error Display::programCachePopulate(const void *key,
                                    EGLint keysize,
                                    const void *binary,
                                    EGLint binarysize)
{}

EGLint Display::programCacheResize(EGLint limit, EGLenum mode)
{}

void Display::overrideFrontendFeatures(const std::vector<std::string> &featureNames, bool enabled)
{}

const char *Display::queryStringi(const EGLint name, const EGLint index)
{}

EGLAttrib Display::queryAttrib(const EGLint attribute)
{}

angle::ScratchBuffer Display::requestScratchBuffer()
{}

void Display::returnScratchBuffer(angle::ScratchBuffer scratchBuffer)
{}

angle::ScratchBuffer Display::requestZeroFilledBuffer()
{}

void Display::returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer)
{}

angle::ScratchBuffer Display::requestScratchBufferImpl(
    std::vector<angle::ScratchBuffer> *bufferVector)
{}

void Display::returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer,
                                      std::vector<angle::ScratchBuffer> *bufferVector)
{}

Error Display::handleGPUSwitch()
{}

Error Display::forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow)
{}

Error Display::waitUntilWorkScheduled()
{}

bool Display::supportsDmaBufFormat(EGLint format) const
{}

Error Display::queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats)
{}

Error Display::queryDmaBufModifiers(EGLint format,
                                    EGLint max_modifiers,
                                    EGLuint64KHR *modifiers,
                                    EGLBoolean *external_only,
                                    EGLint *num_modifiers)
{}

angle::ImageLoadContext Display::getImageLoadContext() const
{}

const gl::Context *Display::getContext(gl::ContextID contextID) const
{}

const egl::Surface *Display::getSurface(egl::SurfaceID surfaceID) const
{}

const egl::Image *Display::getImage(egl::ImageID imageID) const
{}

const egl::Sync *Display::getSync(egl::SyncID syncID) const
{}

gl::Context *Display::getContext(gl::ContextID contextID)
{}

egl::Surface *Display::getSurface(egl::SurfaceID surfaceID)
{}

egl::Image *Display::getImage(egl::ImageID imageID)
{}

egl::Sync *Display::getSync(egl::SyncID syncID)
{}

// static
void Display::InitTLS()
{}

// static
angle::UnlockedTailCall *Display::GetCurrentThreadUnlockedTailCall()
{}

// static
Error *Display::GetCurrentThreadErrorScratchSpace()
{}
}  // namespace egl