blob: 66e67c41c293e83eade10fa98312f7f433e9c24f [file] [log] [blame]
//
// Copyright 2014 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.
//
#ifndef UTIL_EGLWINDOW_H_
#define UTIL_EGLWINDOW_H_
#include <stdint.h>
#include <list>
#include <memory>
#include <string>
#include "common/Optional.h"
#include "common/PackedEnums.h"
#include "common/angleutils.h"
#include "util/EGLPlatformParameters.h"
#include "util/util_export.h"
#include "util/util_gl.h"
class OSWindow;
namespace angle
{
class Library;
struct PlatformMethods;
using GenericProc = void (*)();
} // namespace angle
struct ANGLE_UTIL_EXPORT ConfigParameters
{
ConfigParameters();
~ConfigParameters();
void reset();
// Surface and Context parameters.
int redBits;
int greenBits;
int blueBits;
int alphaBits;
int depthBits;
int stencilBits;
Optional<bool> webGLCompatibility;
Optional<bool> robustResourceInit;
// EGLWindow-specific.
EGLenum componentType;
bool multisample;
bool debug;
bool noError;
Optional<bool> extensionsEnabled;
bool bindGeneratesResource;
bool clientArraysEnabled;
bool robustAccess;
bool mutableRenderBuffer;
EGLint samples;
Optional<bool> contextProgramCacheEnabled;
EGLenum resetStrategy;
EGLenum colorSpace;
EGLint swapInterval;
};
using GLWindowContext = struct GLWindowHandleContext_T *;
enum class GLWindowResult
{
NoError,
NoColorspaceSupport,
NoMutableRenderBufferSupport,
Error,
};
class ANGLE_UTIL_EXPORT GLWindowBase : angle::NonCopyable
{
public:
static void Delete(GLWindowBase **window);
using Image = void *;
using ClientBuffer = void *;
using Enum = unsigned int;
using Attrib = intptr_t;
using AttribKHR = khronos_int32_t;
using Boolean = unsigned int;
using Surface = void *;
using Sync = void *;
using Display = void *;
// It should also be possible to set multisample and floating point framebuffers.
EGLint getClientMajorVersion() const { return mClientMajorVersion; }
EGLint getClientMinorVersion() const { return mClientMinorVersion; }
EGLenum getClientType() const { return mClientType; }
EGLint getProfileMask() const { return mProfileMask; }
virtual bool initializeGL(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &platformParams,
const ConfigParameters &configParams) = 0;
virtual GLWindowResult initializeGLWithResult(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &platformParams,
const ConfigParameters &configParams) = 0;
virtual bool isGLInitialized() const = 0;
virtual void swap() = 0;
virtual void destroyGL() = 0;
virtual bool makeCurrent() = 0;
virtual bool hasError() const = 0;
virtual bool setSwapInterval(EGLint swapInterval) = 0;
virtual angle::GenericProc getProcAddress(const char *name) = 0;
// EGLContext and HGLRC (WGL) are both "handles", which are implemented as pointers.
// Use void* here and let the underlying implementation handle interpreting the type correctly.
virtual GLWindowContext getCurrentContextGeneric() = 0;
virtual GLWindowContext createContextGeneric(GLWindowContext share) = 0;
virtual bool makeCurrentGeneric(GLWindowContext context) = 0;
virtual Image createImage(GLWindowContext context,
Enum target,
ClientBuffer buffer,
const Attrib *attrib_list) = 0;
virtual Image createImageKHR(GLWindowContext context,
Enum target,
ClientBuffer buffer,
const AttribKHR *attrib_list) = 0;
virtual EGLBoolean destroyImage(Image image) = 0;
virtual EGLBoolean destroyImageKHR(Image image) = 0;
virtual Sync createSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) = 0;
virtual Sync createSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) = 0;
virtual EGLBoolean destroySync(EGLDisplay dpy, Sync sync) = 0;
virtual EGLBoolean destroySyncKHR(EGLDisplay dpy, Sync sync) = 0;
virtual EGLint clientWaitSync(EGLDisplay dpy, Sync sync, EGLint flags, EGLTimeKHR timeout) = 0;
virtual EGLint clientWaitSyncKHR(EGLDisplay dpy,
Sync sync,
EGLint flags,
EGLTimeKHR timeout) = 0;
virtual EGLint getEGLError() = 0;
virtual Display getCurrentDisplay() = 0;
virtual Surface createPbufferSurface(const EGLint *attrib_list) = 0;
virtual EGLBoolean destroySurface(Surface surface) = 0;
virtual EGLBoolean bindTexImage(EGLSurface surface, EGLint buffer) = 0;
virtual EGLBoolean releaseTexImage(EGLSurface surface, EGLint buffer) = 0;
virtual bool makeCurrent(EGLSurface draw, EGLSurface read, EGLContext context) = 0;
bool isMultisample() const { return mConfigParams.multisample; }
bool isDebugEnabled() const { return mConfigParams.debug; }
const angle::PlatformMethods *getPlatformMethods() const { return mPlatform.platformMethods; }
const EGLPlatformParameters &getPlatform() const { return mPlatform; }
const ConfigParameters &getConfigParams() const { return mConfigParams; }
virtual bool isFeatureEnabled(angle::Feature feature) { return false; }
protected:
GLWindowBase(EGLenum clientType,
EGLint glesMajorVersion,
EGLint glesMinorVersion,
EGLint profileMask);
virtual ~GLWindowBase();
EGLenum mClientType;
EGLint mClientMajorVersion;
EGLint mClientMinorVersion;
EGLint mProfileMask;
EGLPlatformParameters mPlatform;
ConfigParameters mConfigParams;
};
enum class ANGLEFeatureStatus
{
Enabled,
Disabled,
Unknown,
};
using ANGLEFeatureArray = angle::PackedEnumMap<angle::Feature, ANGLEFeatureStatus>;
class ANGLE_UTIL_EXPORT EGLWindow : public GLWindowBase
{
public:
static EGLWindow *New(EGLenum clientType,
EGLint glesMajorVersion,
EGLint glesMinorVersion,
EGLint profileMask);
static void Delete(EGLWindow **window);
static EGLBoolean FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config);
EGLConfig getConfig() const;
EGLDisplay getDisplay() const;
EGLSurface getSurface() const;
EGLContext getContext() const;
bool isContextVersion(EGLint glesMajorVersion, EGLint glesMinorVersion) const;
// Internally initializes the Display, Surface and Context.
bool initializeGL(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &platformParams,
const ConfigParameters &configParams) override;
GLWindowResult initializeGLWithResult(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &platformParams,
const ConfigParameters &configParams) override;
bool isGLInitialized() const override;
void swap() override;
void destroyGL() override;
bool makeCurrent() override;
bool hasError() const override;
bool setSwapInterval(EGLint swapInterval) override;
angle::GenericProc getProcAddress(const char *name) override;
// Initializes EGL resources.
GLWindowContext getCurrentContextGeneric() override;
GLWindowContext createContextGeneric(GLWindowContext share) override;
bool makeCurrentGeneric(GLWindowContext context) override;
// Only initializes the Display.
bool initializeDisplay(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
angle::GLESDriverType driverType,
const EGLPlatformParameters &params);
// Only initializes the Surface.
GLWindowResult initializeSurface(OSWindow *osWindow,
angle::Library *glWindowingLibrary,
const ConfigParameters &params);
// Create an EGL context with this window's configuration
EGLContext createContext(EGLContext share, EGLint *extraAttributes);
// Make the EGL context current
bool makeCurrent(EGLContext context);
Image createImage(GLWindowContext context,
Enum target,
ClientBuffer buffer,
const Attrib *attrib_list) override;
Image createImageKHR(GLWindowContext context,
Enum target,
ClientBuffer buffer,
const AttribKHR *attrib_list) override;
EGLBoolean destroyImage(Image image) override;
EGLBoolean destroyImageKHR(Image image) override;
Sync createSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) override;
Sync createSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) override;
EGLBoolean destroySync(EGLDisplay dpy, Sync sync) override;
EGLBoolean destroySyncKHR(EGLDisplay dpy, Sync sync) override;
EGLint clientWaitSync(EGLDisplay dpy, Sync sync, EGLint flags, EGLTimeKHR timeout) override;
EGLint clientWaitSyncKHR(EGLDisplay dpy, Sync sync, EGLint flags, EGLTimeKHR timeout) override;
EGLint getEGLError() override;
Display getCurrentDisplay() override;
Surface createPbufferSurface(const EGLint *attrib_list) override;
EGLBoolean destroySurface(Surface surface) override;
EGLBoolean bindTexImage(EGLSurface surface, EGLint buffer) override;
EGLBoolean releaseTexImage(EGLSurface surface, EGLint buffer) override;
bool makeCurrent(EGLSurface draw, EGLSurface read, EGLContext context) override;
// Only initializes the Context.
bool initializeContext();
void destroySurface();
void destroyContext();
bool isDisplayInitialized() const { return mDisplay != EGL_NO_DISPLAY; }
// Get the status of features and cache them in mFeatures.
void queryFeatures();
// Return whether a feature is enabled. Features that don't exist in the backend have Unknown
// status, and are considered disabled for the purposes of this function.
bool isFeatureEnabled(angle::Feature feature) override;
private:
EGLWindow(EGLenum clientType,
EGLint glesMajorVersion,
EGLint glesMinorVersion,
EGLint profileMask);
~EGLWindow() override;
EGLConfig mConfig;
EGLDisplay mDisplay;
EGLSurface mSurface;
EGLContext mContext;
EGLint mEGLMajorVersion;
EGLint mEGLMinorVersion;
ANGLEFeatureArray mFeatures;
};
#endif // UTIL_EGLWINDOW_H_