132 lines
3.7 KiB
C++
132 lines
3.7 KiB
C++
// This file is a part of media_kit
|
|
// (https://github.com/media-kit/media-kit).
|
|
//
|
|
// Copyright © 2021 & onwards, Hitesh Kumar Saini <saini123hitesh@gmail.com>.
|
|
// 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 <EGL/egl.h>
|
|
#include <EGL/eglext.h>
|
|
#include <EGL/eglplatform.h>
|
|
#include <GLES2/gl2.h>
|
|
#include <GLES2/gl2ext.h>
|
|
#include <Windows.h>
|
|
#include <d3d.h>
|
|
#include <d3d11.h>
|
|
#include <wrl.h>
|
|
|
|
#include <cstdint>
|
|
#include <functional>
|
|
|
|
// |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<void()> 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<ID3D11Texture2D> internal_d3d_11_texture_2D_;
|
|
Microsoft::WRL::ComPtr<ID3D11Texture2D> 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_
|