refactor Windows rendering into standalone DLL
This commit is contained in:
@@ -14,11 +14,11 @@ list(APPEND PLUGIN_SOURCES
|
|||||||
"thermion_flutter_plugin.h"
|
"thermion_flutter_plugin.h"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(USE_ANGLE FALSE)
|
set(THERMION_EGL FALSE)
|
||||||
set(WGL_USE_BACKING_WINDOW FALSE)
|
set(WGL_USE_BACKING_WINDOW FALSE)
|
||||||
|
|
||||||
if(USE_ANGLE)
|
if(THERMION_EGL)
|
||||||
add_compile_definitions(USE_ANGLE)
|
add_compile_definitions(THERMION_EGL)
|
||||||
list(APPEND PLUGIN_SOURCES "flutter_angle_texture.cpp" "egl_context.cpp" )
|
list(APPEND PLUGIN_SOURCES "flutter_angle_texture.cpp" "egl_context.cpp" )
|
||||||
else()
|
else()
|
||||||
if(WGL_USE_BACKING_WINDOW)
|
if(WGL_USE_BACKING_WINDOW)
|
||||||
@@ -52,7 +52,7 @@ include_directories(
|
|||||||
"${CMAKE_SOURCE_DIR}/../../../../thermion_dart/native/include"
|
"${CMAKE_SOURCE_DIR}/../../../../thermion_dart/native/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
if(USE_ANGLE)
|
if(THERMION_EGL)
|
||||||
list(APPEND GL_LIBS
|
list(APPEND GL_LIBS
|
||||||
EGL
|
EGL
|
||||||
GLESv2
|
GLESv2
|
||||||
@@ -87,7 +87,7 @@ target_link_libraries(${PLUGIN_NAME} PRIVATE
|
|||||||
)
|
)
|
||||||
|
|
||||||
# List of absolute paths to libraries that should be bundled with the plugin
|
# List of absolute paths to libraries that should be bundled with the plugin
|
||||||
if(USE_ANGLE)
|
if(THERMION_EGL)
|
||||||
set(thermion_flutter_bundled_libraries
|
set(thermion_flutter_bundled_libraries
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/lib/Debug/angle/libEGL.dll
|
${CMAKE_CURRENT_SOURCE_DIR}/lib/Debug/angle/libEGL.dll
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/lib/Debug/angle/libGLESv2.dll
|
${CMAKE_CURRENT_SOURCE_DIR}/lib/Debug/angle/libGLESv2.dll
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
#ifndef _EGL_CONTEXT_H
|
|
||||||
#define _EGL_CONTEXT_H
|
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
#include <flutter/method_channel.h>
|
|
||||||
#include <flutter/plugin_registrar_windows.h>
|
|
||||||
#include <flutter/standard_method_codec.h>
|
|
||||||
#include <flutter/texture_registrar.h>
|
|
||||||
|
|
||||||
#include "flutter_angle_texture.h"
|
|
||||||
#include "backend/platforms/PlatformEGL.h"
|
|
||||||
#include "flutter_render_context.h"
|
|
||||||
|
|
||||||
namespace thermion_flutter {
|
|
||||||
|
|
||||||
class FlutterEGLContext : public FlutterRenderContext {
|
|
||||||
public:
|
|
||||||
FlutterEGLContext(flutter::PluginRegistrarWindows* pluginRegistrar, flutter::TextureRegistrar* textureRegistrar);
|
|
||||||
void* GetSharedContext();
|
|
||||||
void RenderCallback();
|
|
||||||
void* GetPlatform();
|
|
||||||
void CreateRenderingSurface(uint32_t width, uint32_t height, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result, uint32_t left, uint32_t top );
|
|
||||||
|
|
||||||
private:
|
|
||||||
void* _context = nullptr;
|
|
||||||
EGLConfig _eglConfig = NULL;
|
|
||||||
EGLDisplay _eglDisplay = NULL;
|
|
||||||
ID3D11Device* _D3D11Device = nullptr;
|
|
||||||
ID3D11DeviceContext* _D3D11DeviceContext = nullptr;
|
|
||||||
filament::backend::Platform* _platform = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#ifndef _FLUTTER_RENDER_CONTEXT_H
|
|
||||||
#define _FLUTTER_RENDER_CONTEXT_H
|
|
||||||
|
|
||||||
#include <flutter/method_channel.h>
|
|
||||||
#include <flutter/plugin_registrar_windows.h>
|
|
||||||
#include <flutter/standard_method_codec.h>
|
|
||||||
#include <flutter/texture_registrar.h>
|
|
||||||
|
|
||||||
#include "flutter_texture_buffer.h"
|
|
||||||
|
|
||||||
namespace thermion_flutter {
|
|
||||||
|
|
||||||
class FlutterRenderContext {
|
|
||||||
public:
|
|
||||||
|
|
||||||
void CreateRenderingSurface(uint32_t width, uint32_t height, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result, uint32_t left, uint32_t top);
|
|
||||||
|
|
||||||
void DestroyRenderingSurface(std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
|
||||||
|
|
||||||
int64_t GetFlutterTextureId() {
|
|
||||||
if(!_active) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return _active->flutterTextureId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *GetSharedContext();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
FlutterRenderContext( flutter::PluginRegistrarWindows* pluginRegistrar, flutter::TextureRegistrar* textureRegistrar) : _pluginRegistrar(pluginRegistrar), _textureRegistrar(textureRegistrar) {};
|
|
||||||
|
|
||||||
flutter::PluginRegistrarWindows* _pluginRegistrar;
|
|
||||||
flutter::TextureRegistrar* _textureRegistrar;
|
|
||||||
std::unique_ptr<FlutterTextureBuffer> _active = nullptr;
|
|
||||||
std::unique_ptr<FlutterTextureBuffer> _inactive = nullptr;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#ifndef _FLUTTER_TEXTURE_BUFFER_H
|
|
||||||
#define _FLUTTER_TEXTURE_BUFFER_H
|
|
||||||
|
|
||||||
#include <flutter/method_channel.h>
|
|
||||||
#include <flutter/plugin_registrar_windows.h>
|
|
||||||
#include <flutter/standard_method_codec.h>
|
|
||||||
#include <flutter/texture_registrar.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace thermion_flutter {
|
|
||||||
|
|
||||||
class FlutterTextureBuffer {
|
|
||||||
public:
|
|
||||||
int64_t flutterTextureId = -1;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
set(PROJECT_NAME "thermion_egl")
|
||||||
|
project(${PROJECT_NAME} LANGUAGES C CXX)
|
||||||
|
|
||||||
|
cmake_policy(VERSION 3.14...3.25)
|
||||||
|
|
||||||
|
add_compile_definitions(THERMION_EGL)
|
||||||
|
|
||||||
|
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||||
|
set(BUILD_SHARED_LIBS TRUE)
|
||||||
|
set(CMAKE_ENABLE_EXPORTS TRUE)
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME} SHARED
|
||||||
|
"egl_context.cpp"
|
||||||
|
"egl_texture.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)
|
||||||
|
include_directories(${PROJECT_NAME} INTERFACE
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../../include"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(EGL SHARED IMPORTED)
|
||||||
|
set_property(TARGET EGL PROPERTY IMPORTED_IMPLIB_DEBUG "E:\\angle\\libEGL.dll.lib")
|
||||||
|
set_property(TARGET EGL PROPERTY IMPORTED_IMPLIB_PROFILE "E:\\angle\\libEGL.dll.lib")
|
||||||
|
set_property(TARGET EGL PROPERTY IMPORTED_IMPLIB_RELEASE "E:\\angle\\libEGL.dll.lib")
|
||||||
|
set_property(TARGET EGL PROPERTY IMPORTED_IMPLIB_MINSIZEREL "E:\\angle\\libEGL.dll.lib")
|
||||||
|
set_property(TARGET EGL PROPERTY IMPORTED_IMPLIB_RELWITHDEBINFO "E:\\angle\\libEGL.dll.lib")
|
||||||
|
add_library(GLESv2 SHARED IMPORTED)
|
||||||
|
set_property(TARGET GLESv2 PROPERTY IMPORTED_IMPLIB_DEBUG "E:\\angle\\libGLESv2.dll.lib")
|
||||||
|
set_property(TARGET GLESv2 PROPERTY IMPORTED_IMPLIB_PROFILE "E:\\angle\\libGLESv2.dll.lib")
|
||||||
|
set_property(TARGET GLESv2 PROPERTY IMPORTED_IMPLIB_RELEASE "E:\\angle\\libGLESv2.dll")
|
||||||
|
set_property(TARGET GLESv2 PROPERTY IMPORTED_IMPLIB_MINSIZEREL "E:\\angle\\libGLESv2.dll")
|
||||||
|
set_property(TARGET GLESv2 PROPERTY IMPORTED_IMPLIB_RELWITHDEBINFO "E:\\angle\\libGLESv2.dll")
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||||
|
Shlwapi
|
||||||
|
EGL
|
||||||
|
GLESv2
|
||||||
|
dxgi
|
||||||
|
d3d11
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test executable
|
||||||
|
add_executable(${PROJECT_NAME}_test
|
||||||
|
"main.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make sure the test depends on the library
|
||||||
|
add_dependencies(${PROJECT_NAME}_test ${PROJECT_NAME})
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}_test PRIVATE
|
||||||
|
${PROJECT_NAME}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Copy ANGLE DLLs to the output directory
|
||||||
|
add_custom_command(TARGET ${PROJECT_NAME}_test POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
"E:/angle/libEGL.dll"
|
||||||
|
"E:/angle/libGLESv2.dll"
|
||||||
|
"$<TARGET_FILE_DIR:${PROJECT_NAME}_test>"
|
||||||
|
)
|
||||||
@@ -1,20 +1,13 @@
|
|||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "egl_context.h"
|
#include "egl_context.h"
|
||||||
|
|
||||||
#define FILAMENT_USE_EXTERNAL_GLES3
|
namespace thermion::windows::egl {
|
||||||
#include <gl_headers.h>
|
|
||||||
|
|
||||||
#pragma comment(lib, "dwmapi.lib")
|
FlutterEGLContext::FlutterEGLContext() {
|
||||||
#pragma comment(lib, "comctl32.lib")
|
|
||||||
|
|
||||||
namespace thermion_flutter {
|
|
||||||
|
|
||||||
FlutterEGLContext::FlutterEGLContext(
|
|
||||||
flutter::PluginRegistrarWindows* pluginRegistrar,
|
|
||||||
flutter::TextureRegistrar* textureRegistrar) : FlutterRenderContext(pluginRegistrar, textureRegistrar) {
|
|
||||||
|
|
||||||
_platform = new filament::backend::PlatformEGL();
|
|
||||||
|
|
||||||
// D3D starts here
|
// D3D starts here
|
||||||
IDXGIAdapter *adapter_ = nullptr;
|
IDXGIAdapter *adapter_ = nullptr;
|
||||||
|
|
||||||
@@ -81,13 +74,17 @@ FlutterEGLContext::FlutterEGLContext(
|
|||||||
// * *
|
// * *
|
||||||
// *******************
|
// *******************
|
||||||
EGLBoolean bindAPI = eglBindAPI(EGL_OPENGL_ES_API);
|
EGLBoolean bindAPI = eglBindAPI(EGL_OPENGL_ES_API);
|
||||||
if (UTILS_UNLIKELY(!bindAPI)) {
|
if (!bindAPI) {
|
||||||
std::cout << "eglBindAPI EGL_OPENGL_ES_API failed" << std::endl;
|
std::cout << "eglBindAPI EGL_OPENGL_ES_API failed" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
assert_invariant(_eglDisplay != EGL_NO_DISPLAY);
|
if (_eglDisplay == EGL_NO_DISPLAY) {
|
||||||
|
std::cout << "eglBindAPI EGL_OPENGL_ES_API failed" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EGLint major, minor;
|
EGLint major, minor;
|
||||||
EGLBoolean initialized = false;
|
EGLBoolean initialized = false;
|
||||||
@@ -113,12 +110,12 @@ FlutterEGLContext::FlutterEGLContext(
|
|||||||
|
|
||||||
std::cout << "Got major " << major << " and minor " << minor << std::endl;
|
std::cout << "Got major " << major << " and minor " << minor << std::endl;
|
||||||
|
|
||||||
if (UTILS_UNLIKELY(!initialized)) {
|
if (!initialized) {
|
||||||
std::cout << "eglInitialize failed" << std::endl;
|
std::cout << "eglInitialize failed" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glext::importGLESExtensionsEntryPoints();
|
// glext::importGLESExtensionsEntryPoints();
|
||||||
|
|
||||||
EGLint configsCount;
|
EGLint configsCount;
|
||||||
|
|
||||||
@@ -142,34 +139,33 @@ FlutterEGLContext::FlutterEGLContext(
|
|||||||
auto ctx = eglCreateContext(_eglDisplay, _eglConfig, EGL_NO_CONTEXT,contextAttribs);
|
auto ctx = eglCreateContext(_eglDisplay, _eglConfig, EGL_NO_CONTEXT,contextAttribs);
|
||||||
_context = (void*)ctx;
|
_context = (void*)ctx;
|
||||||
|
|
||||||
if (UTILS_UNLIKELY(_context == EGL_NO_CONTEXT)) {
|
if (_context == EGL_NO_CONTEXT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlutterEGLContext::CreateRenderingSurface(
|
void FlutterEGLContext::CreateRenderingSurface(
|
||||||
uint32_t width, uint32_t height,
|
uint32_t width, uint32_t height,
|
||||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result,
|
|
||||||
uint32_t left, uint32_t top
|
uint32_t left, uint32_t top
|
||||||
) {
|
) {
|
||||||
|
|
||||||
glext::importGLESExtensionsEntryPoints();
|
// glext::importGLESExtensionsEntryPoints();
|
||||||
|
|
||||||
if(left != 0 || top != 0) {
|
if(left != 0 || top != 0) {
|
||||||
result->Error("ERROR",
|
// result->Error("ERROR",
|
||||||
"Rendering with EGL uses a Texture render target/Flutter widget and does not need a window offset.");
|
// "Rendering with EGL uses a Texture render target/Flutter widget and does not need a window offset.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_active.get()) {
|
if (_active.get()) {
|
||||||
result->Error("ERROR",
|
// result->Error("ERROR",
|
||||||
"Texture already exists. You must call destroyTexture before "
|
// "Texture already exists. You must call destroyTexture before "
|
||||||
"attempting to create a new one.");
|
// "attempting to create a new one.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FlutterTextureBuffer> active = std::make_unique<FlutterAngleTexture>(
|
_active = std::make_unique<EGLTexture>(
|
||||||
_pluginRegistrar, _textureRegistrar, std::move(result), width, height,
|
width, height,
|
||||||
_D3D11Device, _D3D11DeviceContext, _eglConfig, _eglDisplay, _context,
|
_D3D11Device, _D3D11DeviceContext, _eglConfig, _eglDisplay, _context,
|
||||||
[=](size_t width, size_t height) {
|
[=](size_t width, size_t height) {
|
||||||
std::cout << "RESIZE" << std::endl;
|
std::cout << "RESIZE" << std::endl;
|
||||||
@@ -179,13 +175,12 @@ void FlutterEGLContext::CreateRenderingSurface(
|
|||||||
// auto val = std::make_unique<flutter::EncodableValue>(list);
|
// auto val = std::make_unique<flutter::EncodableValue>(list);
|
||||||
// this->_channel->InvokeMethod("resize", std::move(val), nullptr);
|
// this->_channel->InvokeMethod("resize", std::move(val), nullptr);
|
||||||
});
|
});
|
||||||
_active = std::move(active);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlutterEGLContext::RenderCallback() {
|
void FlutterEGLContext::RenderCallback() {
|
||||||
if(_active.get()) {
|
if(_active.get()) {
|
||||||
((FlutterAngleTexture*)_active.get())->RenderCallback();
|
((EGLTexture*)_active.get())->RenderCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,8 +188,5 @@ void* FlutterEGLContext::GetSharedContext() {
|
|||||||
return (void*)_context;
|
return (void*)_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* FlutterEGLContext::GetPlatform() {
|
|
||||||
return (void*)_platform;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#include "egl_texture.h"
|
||||||
|
|
||||||
|
namespace thermion::windows::egl {
|
||||||
|
|
||||||
|
class FlutterEGLContext {
|
||||||
|
public:
|
||||||
|
FlutterEGLContext();
|
||||||
|
void* GetSharedContext();
|
||||||
|
void RenderCallback();
|
||||||
|
void CreateRenderingSurface(uint32_t width, uint32_t height, uint32_t left, uint32_t top);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* _context = nullptr;
|
||||||
|
EGLConfig _eglConfig = NULL;
|
||||||
|
EGLDisplay _eglDisplay = NULL;
|
||||||
|
ID3D11Device* _D3D11Device = nullptr;
|
||||||
|
ID3D11DeviceContext* _D3D11DeviceContext = nullptr;
|
||||||
|
std::unique_ptr<EGLTexture> _active;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
#include "flutter_angle_texture.h"
|
#include "egl_texture.h"
|
||||||
|
|
||||||
#include <flutter/method_channel.h>
|
|
||||||
#include <flutter/plugin_registrar_windows.h>
|
|
||||||
#include <flutter/standard_method_codec.h>
|
|
||||||
#include <flutter/texture_registrar.h>
|
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace thermion_flutter {
|
namespace thermion::windows::egl {
|
||||||
|
|
||||||
static void logEglError(const char *name) noexcept {
|
static void logEglError(const char *name) noexcept {
|
||||||
const char *err;
|
const char *err;
|
||||||
@@ -61,14 +59,14 @@ static void logEglError(const char *name) noexcept {
|
|||||||
std::cout << name << " failed with " << err << std::endl;
|
std::cout << name << " failed with " << err << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlutterAngleTexture::RenderCallback() {
|
void EGLTexture::RenderCallback() {
|
||||||
glFinish();
|
glFinish();
|
||||||
_D3D11DeviceContext->CopyResource(_externalD3DTexture2D.Get(),
|
_D3D11DeviceContext->CopyResource(_externalD3DTexture2D.Get(),
|
||||||
_internalD3DTexture2D.Get());
|
_internalD3DTexture2D.Get());
|
||||||
_D3D11DeviceContext->Flush();
|
_D3D11DeviceContext->Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
FlutterAngleTexture::~FlutterAngleTexture() {
|
EGLTexture::~EGLTexture() {
|
||||||
if (_eglDisplay != EGL_NO_DISPLAY && _eglSurface != EGL_NO_SURFACE) {
|
if (_eglDisplay != EGL_NO_DISPLAY && _eglSurface != EGL_NO_SURFACE) {
|
||||||
eglReleaseTexImage(_eglDisplay, _eglSurface, EGL_BACK_BUFFER);
|
eglReleaseTexImage(_eglDisplay, _eglSurface, EGL_BACK_BUFFER);
|
||||||
}
|
}
|
||||||
@@ -81,17 +79,13 @@ FlutterAngleTexture::~FlutterAngleTexture() {
|
|||||||
glDeleteTextures(1, &this->glTextureId);
|
glDeleteTextures(1, &this->glTextureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlutterAngleTexture::FlutterAngleTexture(
|
EGLTexture::EGLTexture(
|
||||||
flutter::PluginRegistrarWindows *pluginRegistrar,
|
|
||||||
flutter::TextureRegistrar *textureRegistrar,
|
|
||||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result,
|
|
||||||
uint32_t width, uint32_t height, ID3D11Device *D3D11Device,
|
uint32_t width, uint32_t height, ID3D11Device *D3D11Device,
|
||||||
ID3D11DeviceContext *D3D11DeviceContext, EGLConfig eglConfig,
|
ID3D11DeviceContext *D3D11DeviceContext, EGLConfig eglConfig,
|
||||||
EGLDisplay eglDisplay, EGLContext eglContext,
|
EGLDisplay eglDisplay, EGLContext eglContext,
|
||||||
std::function<void(size_t, size_t)> onResizeRequested
|
std::function<void(size_t, size_t)> onResizeRequested
|
||||||
)
|
)
|
||||||
: _pluginRegistrar(pluginRegistrar), _textureRegistrar(textureRegistrar),
|
: _width(width), _height(height), _D3D11Device(D3D11Device),
|
||||||
_width(width), _height(height), _D3D11Device(D3D11Device),
|
|
||||||
_D3D11DeviceContext(D3D11DeviceContext), _eglConfig(eglConfig),
|
_D3D11DeviceContext(D3D11DeviceContext), _eglConfig(eglConfig),
|
||||||
_eglDisplay(eglDisplay), _eglContext(eglContext), _onResizeRequested(onResizeRequested) {
|
_eglDisplay(eglDisplay), _eglContext(eglContext), _onResizeRequested(onResizeRequested) {
|
||||||
|
|
||||||
@@ -113,7 +107,7 @@ FlutterAngleTexture::FlutterAngleTexture(
|
|||||||
auto hr = _D3D11Device->CreateTexture2D(&d3d11_texture2D_desc, nullptr,
|
auto hr = _D3D11Device->CreateTexture2D(&d3d11_texture2D_desc, nullptr,
|
||||||
&_internalD3DTexture2D);
|
&_internalD3DTexture2D);
|
||||||
if FAILED (hr) {
|
if FAILED (hr) {
|
||||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
// result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||||
return;
|
return;
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@@ -121,14 +115,14 @@ FlutterAngleTexture::FlutterAngleTexture(
|
|||||||
hr = _internalD3DTexture2D.As(&resource);
|
hr = _internalD3DTexture2D.As(&resource);
|
||||||
|
|
||||||
if FAILED (hr) {
|
if FAILED (hr) {
|
||||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
// result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||||
return;
|
return;
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
hr = resource->GetSharedHandle(&_internalD3DTextureHandle);
|
hr = resource->GetSharedHandle(&_internalD3DTextureHandle);
|
||||||
if FAILED (hr) {
|
if FAILED (hr) {
|
||||||
result->Error("ERROR", "Failed to get shared handle to D3D texture",
|
// result->Error("ERROR", "Failed to get shared handle to D3D texture",
|
||||||
nullptr);
|
// nullptr);
|
||||||
return;
|
return;
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@@ -140,22 +134,22 @@ FlutterAngleTexture::FlutterAngleTexture(
|
|||||||
hr = _D3D11Device->CreateTexture2D(&d3d11_texture2D_desc, nullptr,
|
hr = _D3D11Device->CreateTexture2D(&d3d11_texture2D_desc, nullptr,
|
||||||
&_externalD3DTexture2D);
|
&_externalD3DTexture2D);
|
||||||
if FAILED (hr) {
|
if FAILED (hr) {
|
||||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
// result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||||
return;
|
return;
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
hr = _externalD3DTexture2D.As(&resource);
|
hr = _externalD3DTexture2D.As(&resource);
|
||||||
|
|
||||||
if FAILED (hr) {
|
if FAILED (hr) {
|
||||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
// result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||||
return;
|
return;
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
hr = resource->GetSharedHandle(&_externalD3DTextureHandle);
|
hr = resource->GetSharedHandle(&_externalD3DTextureHandle);
|
||||||
if FAILED (hr) {
|
if FAILED (hr) {
|
||||||
result->Error("ERROR",
|
// result->Error("ERROR",
|
||||||
"Failed to get shared handle to external D3D texture",
|
// "Failed to get shared handle to external D3D texture",
|
||||||
nullptr);
|
// nullptr);
|
||||||
return;
|
return;
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@@ -207,37 +201,27 @@ FlutterAngleTexture::FlutterAngleTexture(
|
|||||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||||
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
||||||
|
|
||||||
_textureDescriptor = std::make_unique<FlutterDesktopGpuSurfaceDescriptor>();
|
// _textureDescriptor = std::make_unique<FlutterDesktopGpuSurfaceDescriptor>();
|
||||||
_textureDescriptor->struct_size = sizeof(FlutterDesktopGpuSurfaceDescriptor);
|
// _textureDescriptor->struct_size = sizeof(FlutterDesktopGpuSurfaceDescriptor);
|
||||||
_textureDescriptor->handle = _externalD3DTextureHandle;
|
// _textureDescriptor->handle = _externalD3DTextureHandle;
|
||||||
_textureDescriptor->width = _textureDescriptor->visible_width = width;
|
// _textureDescriptor->width = _textureDescriptor->visible_width = width;
|
||||||
_textureDescriptor->height = _textureDescriptor->visible_height = height;
|
// _textureDescriptor->height = _textureDescriptor->visible_height = height;
|
||||||
_textureDescriptor->release_context = nullptr;
|
// _textureDescriptor->release_context = nullptr;
|
||||||
_textureDescriptor->release_callback = [](void *release_context) {
|
// _textureDescriptor->release_callback = [](void *release_context) {
|
||||||
|
|
||||||
};
|
// };
|
||||||
_textureDescriptor->format = kFlutterDesktopPixelFormatBGRA8888;
|
// _textureDescriptor->format = kFlutterDesktopPixelFormatBGRA8888;
|
||||||
|
|
||||||
texture =
|
// texture =
|
||||||
std::make_unique<flutter::TextureVariant>(flutter::GpuSurfaceTexture(
|
// std::make_unique<flutter::TextureVariant>(flutter::GpuSurfaceTexture(
|
||||||
kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle,
|
// kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle,
|
||||||
[&](size_t width, size_t height) {
|
// [&](size_t width, size_t height) {
|
||||||
if(width != this->_width || height != this->_height) {
|
// if(width != this->_width || height != this->_height) {
|
||||||
this->_onResizeRequested(width, height);
|
// this->_onResizeRequested(width, height);
|
||||||
}
|
// }
|
||||||
return _textureDescriptor.get();
|
// return _textureDescriptor.get();
|
||||||
}));
|
// }));
|
||||||
|
|
||||||
flutterTextureId = _textureRegistrar->RegisterTexture(texture.get());
|
|
||||||
std::cout << "Registered Flutter texture ID " << flutterTextureId
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
std::vector<flutter::EncodableValue> resultList;
|
|
||||||
resultList.push_back(flutter::EncodableValue(flutterTextureId));
|
|
||||||
resultList.push_back(flutter::EncodableValue((int64_t) nullptr));
|
|
||||||
resultList.push_back(flutter::EncodableValue(glTextureId));
|
|
||||||
resultList.push_back(flutter::EncodableValue((int64_t) eglContext));
|
|
||||||
result->Success(resultList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace thermion_flutter
|
} // namespace thermion_flutter
|
||||||
@@ -1,14 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef _FLUTTER_ANGLE_TEXTURE_H
|
#include <functional>
|
||||||
#define _FLUTTER_ANGLE_TEXTURE_H
|
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <flutter/texture_registrar.h>
|
|
||||||
#include <flutter/method_channel.h>
|
|
||||||
#include <flutter/plugin_registrar_windows.h>
|
|
||||||
|
|
||||||
#include <d3d.h>
|
#include <d3d.h>
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
|
|
||||||
@@ -22,18 +16,13 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <wrl.h>
|
#include <wrl.h>
|
||||||
|
|
||||||
#include "flutter_texture_buffer.h"
|
|
||||||
|
|
||||||
typedef uint32_t GLuint;
|
typedef uint32_t GLuint;
|
||||||
|
|
||||||
namespace thermion_flutter {
|
namespace thermion::windows::egl {
|
||||||
|
|
||||||
class FlutterAngleTexture : public FlutterTextureBuffer {
|
class EGLTexture {
|
||||||
public:
|
public:
|
||||||
FlutterAngleTexture(
|
EGLTexture(
|
||||||
flutter::PluginRegistrarWindows* pluginRegistrar,
|
|
||||||
flutter::TextureRegistrar* textureRegistrar,
|
|
||||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result,
|
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
uint32_t height,
|
uint32_t height,
|
||||||
ID3D11Device* D3D11Device,
|
ID3D11Device* D3D11Device,
|
||||||
@@ -43,16 +32,14 @@ class FlutterAngleTexture : public FlutterTextureBuffer {
|
|||||||
EGLContext eglContext,
|
EGLContext eglContext,
|
||||||
std::function<void(size_t, size_t)> onResizeRequested
|
std::function<void(size_t, size_t)> onResizeRequested
|
||||||
);
|
);
|
||||||
~FlutterAngleTexture();
|
~EGLTexture();
|
||||||
|
|
||||||
void RenderCallback();
|
void RenderCallback();
|
||||||
|
|
||||||
GLuint glTextureId = 0;
|
GLuint glTextureId = 0;
|
||||||
std::unique_ptr<flutter::TextureVariant> texture;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
flutter::PluginRegistrarWindows* _pluginRegistrar;
|
bool _error = false;
|
||||||
flutter::TextureRegistrar* _textureRegistrar;
|
|
||||||
uint32_t _width = 0;
|
uint32_t _width = 0;
|
||||||
uint32_t _height = 0;
|
uint32_t _height = 0;
|
||||||
bool logged = false;
|
bool logged = false;
|
||||||
@@ -72,9 +59,8 @@ class FlutterAngleTexture : public FlutterTextureBuffer {
|
|||||||
EGLConfig _eglConfig = EGL_NO_CONFIG_KHR;
|
EGLConfig _eglConfig = EGL_NO_CONFIG_KHR;
|
||||||
EGLSurface _eglSurface = EGL_NO_SURFACE;
|
EGLSurface _eglSurface = EGL_NO_SURFACE;
|
||||||
|
|
||||||
std::unique_ptr<FlutterDesktopGpuSurfaceDescriptor> _textureDescriptor = nullptr;
|
// std::unique_ptr<FlutterDesktopGpuSurfaceDescriptor> _textureDescriptor = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // _FLUTTER_ANGLE_TEXTURE
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#include "egl_context.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "Initializing EGL Context..." << std::endl;
|
||||||
|
|
||||||
|
thermion::windows::egl::FlutterEGLContext context;
|
||||||
|
|
||||||
|
// Create a rendering surface
|
||||||
|
const uint32_t width = 800;
|
||||||
|
const uint32_t height = 600;
|
||||||
|
|
||||||
|
std::cout << "Creating rendering surface " << width << "x" << height << std::endl;
|
||||||
|
context.CreateRenderingSurface(width, height, 0, 0);
|
||||||
|
|
||||||
|
void* sharedContext = context.GetSharedContext();
|
||||||
|
if (sharedContext) {
|
||||||
|
std::cout << "Successfully created shared context" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "Failed to create shared context" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run a simple render loop
|
||||||
|
std::cout << "Starting render loop..." << std::endl;
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
context.RenderCallback();
|
||||||
|
std::cout << "Rendered frame " << i + 1 << std::endl;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "EGL Context demo completed" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "flutter_texture_buffer.h"
|
||||||
|
|
||||||
|
namespace thermion_flutter {
|
||||||
|
|
||||||
|
class FlutterRenderContext {
|
||||||
|
public:
|
||||||
|
void CreateRenderingSurface(uint32_t width, uint32_t height, uint32_t left, uint32_t top);
|
||||||
|
void DestroyRenderingSurface();
|
||||||
|
void *GetSharedContext();
|
||||||
|
FlutterTextureBuffer GetActiveTexture() {
|
||||||
|
return _active->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FlutterRenderContext();
|
||||||
|
std::unique_ptr<FlutterTextureBuffer> _active = nullptr;
|
||||||
|
std::unique_ptr<FlutterTextureBuffer> _inactive = nullptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef _FLUTTER_TEXTURE_BUFFER_H
|
||||||
|
#define _FLUTTER_TEXTURE_BUFFER_H
|
||||||
|
|
||||||
|
#include <flutter/method_channel.h>
|
||||||
|
#include <flutter/plugin_registrar_windows.h>
|
||||||
|
#include <flutter/standard_method_codec.h>
|
||||||
|
#include <flutter/texture_registrar.h>
|
||||||
|
|
||||||
|
namespace thermion_flutter {
|
||||||
|
|
||||||
|
class FlutterTextureBuffer {
|
||||||
|
public:
|
||||||
|
flutter::TextureVariant GetTexture() {
|
||||||
|
return texture->get();
|
||||||
|
}
|
||||||
|
void RegisterFlutterTextureId(int64_t flutterTextureId);
|
||||||
|
int64_t GetFlutterTextureId();
|
||||||
|
private:
|
||||||
|
int64_t flutterTextureId = -1;
|
||||||
|
std::unique_ptr<flutter::TextureVariant> texture;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "flutter_render_context.h"
|
#include "flutter_render_context.h"
|
||||||
|
|
||||||
#if USE_ANGLE
|
#if THERMION_EGL
|
||||||
#include "egl_context.h"
|
#include "egl_context.h"
|
||||||
#else
|
#else
|
||||||
#include "wgl_context.h"
|
#include "wgl_context.h"
|
||||||
@@ -150,6 +150,18 @@ void ThermionFlutterPlugin::CreateTexture(
|
|||||||
auto top = (uint32_t)round(dTop );
|
auto top = (uint32_t)round(dTop );
|
||||||
|
|
||||||
_context->CreateRenderingSurface(width, height, std::move(result), left, top);
|
_context->CreateRenderingSurface(width, height, std::move(result), left, top);
|
||||||
|
auto texture = _context->GetActiveTexture();
|
||||||
|
|
||||||
|
auto flutterTextureId = _textureRegistrar->RegisterTexture(texture.GetFlutterTextureId());
|
||||||
|
texture.RegisterFlutterTextureId(flutterTextureId);
|
||||||
|
std::cout << "Registered Flutter texture ID " << flutterTextureId
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
std::vector<flutter::EncodableValue> resultList;
|
||||||
|
resultList.push_back(flutter::EncodableValue(flutterTextureId));
|
||||||
|
resultList.push_back(flutter::EncodableValue(glTextureId));
|
||||||
|
resultList.push_back(flutter::EncodableValue((int64_t) nullptr));
|
||||||
|
result->Success(resultList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThermionFlutterPlugin::DestroyTexture(
|
void ThermionFlutterPlugin::DestroyTexture(
|
||||||
@@ -180,7 +192,7 @@ void ThermionFlutterPlugin::HandleMethodCall(
|
|||||||
result->Success(flutter::EncodableValue((int64_t)wrapper));
|
result->Success(flutter::EncodableValue((int64_t)wrapper));
|
||||||
} else if(methodCall.method_name() == "getSharedContext") {
|
} else if(methodCall.method_name() == "getSharedContext") {
|
||||||
if (!_context) {
|
if (!_context) {
|
||||||
#ifdef USE_ANGLE
|
#ifdef THERMION_EGL
|
||||||
_context = std::make_unique<FlutterEGLContext>(_pluginRegistrar, _textureRegistrar);
|
_context = std::make_unique<FlutterEGLContext>(_pluginRegistrar, _textureRegistrar);
|
||||||
#else
|
#else
|
||||||
_context = std::make_unique<WGLContext>(_pluginRegistrar, _textureRegistrar);
|
_context = std::make_unique<WGLContext>(_pluginRegistrar, _textureRegistrar);
|
||||||
@@ -214,12 +226,13 @@ void ThermionFlutterPlugin::HandleMethodCall(
|
|||||||
DestroyTexture(methodCall, std::move(result));
|
DestroyTexture(methodCall, std::move(result));
|
||||||
} else if (methodCall.method_name() == "markTextureFrameAvailable") {
|
} else if (methodCall.method_name() == "markTextureFrameAvailable") {
|
||||||
if (_context) {
|
if (_context) {
|
||||||
auto flutterTextureId = _context->GetFlutterTextureId();
|
auto texture = context->GetActiveTexture();
|
||||||
|
auto flutterTextureId = texture.GetFlutterTextureId();
|
||||||
if(flutterTextureId == -1) {
|
if(flutterTextureId == -1) {
|
||||||
std::cout << "Bad texture" << std::endl;
|
std::cout << "Bad texture" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef USE_ANGLE
|
#ifdef THERMION_EGL
|
||||||
_context->RenderCallback();
|
_context->RenderCallback();
|
||||||
#endif
|
#endif
|
||||||
#if !WGL_USE_BACKING_WINDOW
|
#if !WGL_USE_BACKING_WINDOW
|
||||||
@@ -228,11 +241,7 @@ void ThermionFlutterPlugin::HandleMethodCall(
|
|||||||
}
|
}
|
||||||
result->Success(flutter::EncodableValue((int64_t)nullptr));
|
result->Success(flutter::EncodableValue((int64_t)nullptr));
|
||||||
} else if (methodCall.method_name() == "getDriverPlatform") {
|
} else if (methodCall.method_name() == "getDriverPlatform") {
|
||||||
#ifdef USE_ANGLE
|
|
||||||
result->Success(flutter::EncodableValue((int64_t)_context->GetPlatform()));
|
|
||||||
#else
|
|
||||||
result->Success(flutter::EncodableValue((int64_t) nullptr));
|
result->Success(flutter::EncodableValue((int64_t) nullptr));
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
result->Error("NOT_IMPLEMENTED", "Method is not implemented %s",
|
result->Error("NOT_IMPLEMENTED", "Method is not implemented %s",
|
||||||
methodCall.method_name());
|
methodCall.method_name());
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include "ResourceBuffer.h"
|
#include "ResourceBuffer.h"
|
||||||
|
|
||||||
#if USE_ANGLE
|
#if THERMION_EGL
|
||||||
#include "egl_context.h"
|
#include "egl_context.h"
|
||||||
#else
|
#else
|
||||||
#include "wgl_context.h"
|
#include "wgl_context.h"
|
||||||
@@ -59,7 +59,7 @@ public:
|
|||||||
void freeResource(ResourceBuffer rbuf);
|
void freeResource(ResourceBuffer rbuf);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef USE_ANGLE
|
#ifdef THERMION_EGL
|
||||||
std::unique_ptr<FlutterEGLContext> _context = nullptr;
|
std::unique_ptr<FlutterEGLContext> _context = nullptr;
|
||||||
#else
|
#else
|
||||||
std::unique_ptr<WGLContext> _context = nullptr;
|
std::unique_ptr<WGLContext> _context = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user