// This file is a part of media_kit // (https://github.com/media-kit/media-kit). // // Copyright © 2021 & onwards, Hitesh Kumar Saini . // All rights reserved. // Use of this source code is governed by MIT license that can be found in the // LICENSE file. #ifndef ANGLE_SURFACE_MANAGER_H_ #define ANGLE_SURFACE_MANAGER_H_ #include #include #include #include #include #include #include #include #include #include #include // |ANGLESurfaceManager| provides an abstraction around ANGLE to easily draw // OpenGL ES 2.0 content & read as D3D 11 texture using shared |HANDLE|. // * |Draw|: Takes callback where OpenGL ES 2.0 calls can be made for rendering. // * |Read|: Copies the drawn content to D3D 11 texture & makes it available to // the shared |handle| for access. // A large part of implementation is inspired from Flutter. // https://github.com/flutter/engine/blob/master/shell/platform/windows/angle_surface_manager.h class ANGLESurfaceManager { public: const int32_t width() const { return width_; } const int32_t height() const { return height_; } const HANDLE handle() const { return handle_; } ANGLESurfaceManager(int32_t width, int32_t height); ~ANGLESurfaceManager(); void HandleResize(int32_t width, int32_t height); void Draw(std::function callback); void Read(); void MakeCurrent(bool value); private: void SwapBuffers(); void Create(); void CleanUp(bool release_context); bool CreateD3DTexture(); bool CreateEGLDisplay(); bool CreateAndBindEGLSurface(); IDXGIAdapter* adapter_ = nullptr; int32_t width_ = 1; int32_t height_ = 1; HANDLE internal_handle_ = nullptr; HANDLE handle_ = nullptr; // Sync |Draw| & |Read| calls. HANDLE mutex_ = nullptr; // D3D 11 ID3D11Device* d3d_11_device_ = nullptr; ID3D11DeviceContext* d3d_11_device_context_ = nullptr; Microsoft::WRL::ComPtr internal_d3d_11_texture_2D_; Microsoft::WRL::ComPtr d3d_11_texture_2D_; // ANGLE EGLSurface surface_ = EGL_NO_SURFACE; EGLDisplay display_ = EGL_NO_DISPLAY; EGLContext context_ = nullptr; EGLConfig config_ = nullptr; static constexpr EGLint kEGLConfigurationAttributes[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8, EGL_NONE, }; static constexpr EGLint kEGLContextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, }; static constexpr EGLint kD3D11DisplayAttributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_NONE, }; static constexpr EGLint kD3D11_9_3DisplayAttributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_NONE, }; static constexpr EGLint kD3D9DisplayAttributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, EGL_NONE, }; static constexpr EGLint kWrapDisplayAttributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_NONE, }; // Number of active instances of ANGLESurfaceManager. static int32_t instance_count_; }; #endif // ANGLE_SURFACE_MANAGER_H_