refactor Windows rendering into standalone DLL

This commit is contained in:
Nick Fisher
2024-11-04 10:52:22 +08:00
parent 8976eb9621
commit ef97f0e6c2
20 changed files with 263 additions and 213 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>"
)

View File

@@ -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;
} }
}

View File

@@ -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;
};
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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());

View File

@@ -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;