diff options
Diffstat (limited to 'src/egl.h')
-rw-r--r-- | src/egl.h | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/egl.h b/src/egl.h new file mode 100644 index 0000000..0f16f88 --- /dev/null +++ b/src/egl.h @@ -0,0 +1,207 @@ +// Copyright 2021 Benjamin Barenblat +// +// 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 +// +// https://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. + +// An idiomatic C++ interface to EGL 1.5. + +#ifndef GLPLANET_SRC_EGL_H_ +#define GLPLANET_SRC_EGL_H_ + +#include <EGL/egl.h> +#include <X11/Xlib.h> + +#include <utility> +#include <vector> + +#include "src/undo_xlib_dot_h_namespace_pollution.h" +// + +#include "src/util.h" +#include "third_party/abseil/absl/types/optional.h" + +namespace egl { + +class Context; +class Display; +class Surface; + +// Makes a Context active in the current thread. +void BindContext(Surface&, Context&); + +// Configuration attributes. +enum Attribute : EGLint { + kBufferSize = EGL_BUFFER_SIZE, + + kRedSize = EGL_RED_SIZE, + kGreenSize = EGL_GREEN_SIZE, + kBlueSize = EGL_BLUE_SIZE, + kLuminanceSize = EGL_LUMINANCE_SIZE, + kAlphaSize = EGL_ALPHA_SIZE, + kAlphaMaskSize = EGL_ALPHA_MASK_SIZE, + + kBindToTextureRgb = EGL_BIND_TO_TEXTURE_RGB, + kBindToTextureRgba = EGL_BIND_TO_TEXTURE_RGBA, + kColorBufferType = EGL_COLOR_BUFFER_TYPE, + kConfigCaveat = EGL_CONFIG_CAVEAT, + kConfigId = EGL_CONFIG_ID, + kConformantMask = EGL_CONFORMANT, + kDepthSize = EGL_DEPTH_SIZE, + kLevel = EGL_LEVEL, + kMatchNativePixmap = EGL_MATCH_NATIVE_PIXMAP, + kMaxSwapInterval = EGL_MAX_SWAP_INTERVAL, + kMinSwapInterval = EGL_MIN_SWAP_INTERVAL, + kNativeRenderable = EGL_NATIVE_RENDERABLE, + kNativeVisualId = EGL_NATIVE_VISUAL_ID, + kNativeVisualType = EGL_NATIVE_VISUAL_TYPE, + kSampleBuffers = EGL_SAMPLE_BUFFERS, + kSamples = EGL_SAMPLES, + kStencilSize = EGL_STENCIL_SIZE, + kSurfaceTypeMask = EGL_SURFACE_TYPE, + kTransparentType = EGL_TRANSPARENT_TYPE, + kTransparentRedValue = EGL_TRANSPARENT_RED_VALUE, + kTransparentGreenValue = EGL_TRANSPARENT_GREEN_VALUE, + kTransparentBlueValue = EGL_TRANSPARENT_BLUE_VALUE, + + kRenderableTypeMask = EGL_RENDERABLE_TYPE, +}; + +// A "don't care" value for use in attribute lists. +constexpr int kDontCare = EGL_DONT_CARE; + +enum class Api : EGLenum { + kOpenglEs = EGL_OPENGL_ES_API, + kOpenvg = EGL_OPENVG_API, + kOpengl = EGL_OPENGL_API, +}; + +enum ApiMask : EGLint { + kOpenglEsBit = EGL_OPENGL_ES_BIT, + kOpenVgBit = EGL_OPENVG_BIT, + kOpenglEs2Bit = EGL_OPENGL_ES2_BIT, + kOpenglBit = EGL_OPENGL_BIT, +}; + +// The format, type, and size of the buffers for a drawable. +// +// This class is thread-safe. +class Configuration final { + public: + Configuration(const Configuration&) = default; + Configuration& operator=(const Configuration&) = default; + Configuration(Configuration&&) noexcept = default; + Configuration& operator=(Configuration&&) noexcept = default; + + int Get(Attribute attribute) const; + + private: + friend class Display; + + explicit Configuration(EGLDisplay display, EGLConfig config) noexcept + : display_(display), config_(config) {} + + EGLDisplay display_; + EGLConfig config_; +}; + +// A rendering surface. +// +// This class inherits the thread-safety properties of the Display that +// constructed it. +class Surface final { + public: + Surface(const Surface&) = default; + Surface& operator=(const Surface&) = default; + Surface(Surface&&) noexcept = default; + Surface& operator=(Surface&&) noexcept = default; + + void SwapBuffers(); + + private: + friend class Display; + friend void BindContext(Surface&, Context&); + + explicit Surface(EGLDisplay display, EGLSurface surface) noexcept + : display_(display), surface_(surface) {} + + EGLDisplay display_; + EGLSurface surface_; +}; + +// A rendering context. +// +// This class inherits the thread-safety properties of the Display that +// constructed it. +class Context final { + public: + Context(Context&&) noexcept = default; + Context& operator=(Context&&) noexcept = default; + + ~Context() noexcept { + // This should always succeed, since display_ and context_ are guaranteed + // valid. + DCHECK(eglDestroyContext(display_, context_)); + } + + private: + friend class Display; + friend void BindContext(Surface&, Context&); + + explicit Context(EGLDisplay display, EGLContext context) noexcept + : display_(display), context_(context) {} + + EGLDisplay display_; + EGLContext context_; +}; + +// The abstract display on which graphics are drawn. +// +// This class inherits the thread-safety properties of the underlying Xlib +// Display with which it is constructed. +class Display final { + public: + explicit Display(::Display* xlib_display); + + Display(Display&&) noexcept = default; + Display& operator=(Display&&) noexcept = default; + + ~Display() noexcept; + + // Gets Configurations that match the specified attributes. If a limit is + // specified, no more than that many Configurations will be returned. + // + // The returned Configurations hold references into this object and must not + // outlive it. + std::vector<Configuration> GetConfigurations( + const std::vector<std::pair<Attribute, int>>& filter_attributes, + absl::optional<int> limit = absl::nullopt) const; + + // Creates a rendering surface on a window. + // + // The returned Surface holds a reference into this Display and must not + // outlive it. + Surface CreateWindowSurface(const Configuration& config, ::Window window); + + // Creates an OpenGL context. + // + // The returned Context holds a reference into this Display and must not + // outlive it. + Context CreateContext(const Configuration& config, Api api, int major, + int minor); + + private: + EGLDisplay display_; +}; + +} // namespace egl + +#endif // GLPLANET_SRC_EGL_H_ |