FlutterAngleTexture invoke resize callback on size change, cleanup on destruction and call glFinish in RenderCallback

FlutterAngleTexture invoke resize callback on size change, cleanup on destruction and call glFinish in RenderCallback
move OpenGlTextureBuffer cleanup to destructor
This commit is contained in:
Nick Fisher
2023-10-24 12:26:07 +11:00
parent 435ed7bee6
commit 3f988a119c
5 changed files with 59 additions and 39 deletions

View File

@@ -62,13 +62,23 @@ static void logEglError(const char *name) noexcept {
}
void FlutterAngleTexture::RenderCallback() {
glFinish();
_D3D11DeviceContext->CopyResource(_externalD3DTexture2D.Get(),
_internalD3DTexture2D.Get());
_D3D11DeviceContext->Flush();
}
FlutterAngleTexture::~FlutterAngleTexture() {
if (_eglDisplay != EGL_NO_DISPLAY && _eglSurface != EGL_NO_SURFACE) {
eglReleaseTexImage(_eglDisplay, _eglSurface, EGL_BACK_BUFFER);
}
auto success = eglDestroySurface(this->_eglDisplay, this->_eglSurface);
if(success != EGL_TRUE) {
std::cout << "Failed to destroy EGL Surface" << std::endl;
}
_internalD3DTexture2D->Release();
_externalD3DTexture2D->Release();
glDeleteTextures(1, &this->glTextureId);
}
FlutterAngleTexture::FlutterAngleTexture(
@@ -77,11 +87,13 @@ FlutterAngleTexture::FlutterAngleTexture(
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result,
uint32_t width, uint32_t height, ID3D11Device *D3D11Device,
ID3D11DeviceContext *D3D11DeviceContext, EGLConfig eglConfig,
EGLDisplay eglDisplay, EGLContext eglContext)
EGLDisplay eglDisplay, EGLContext eglContext,
std::function<void(size_t, size_t)> onResizeRequested
)
: _pluginRegistrar(pluginRegistrar), _textureRegistrar(textureRegistrar),
_width(width), _height(height), _D3D11Device(D3D11Device),
_D3D11DeviceContext(D3D11DeviceContext), _eglConfig(eglConfig),
_eglDisplay(eglDisplay), _eglContext(eglContext) {
_eglDisplay(eglDisplay), _eglContext(eglContext), _onResizeRequested(onResizeRequested) {
auto d3d11_texture2D_desc = D3D11_TEXTURE2D_DESC{0};
d3d11_texture2D_desc.Width = width;
@@ -157,11 +169,11 @@ FlutterAngleTexture::FlutterAngleTexture(
EGL_NONE,
};
auto surface = eglCreatePbufferFromClientBuffer(
_eglSurface = eglCreatePbufferFromClientBuffer(
_eglDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
_internalD3DTextureHandle, _eglConfig, pbufferAttribs);
if (!eglMakeCurrent(_eglDisplay, surface, surface, _eglContext)) {
if (!eglMakeCurrent(_eglDisplay, _eglSurface, _eglSurface, _eglContext)) {
// eglMakeCurrent failed
logEglError("eglMakeCurrent");
return;
@@ -177,7 +189,7 @@ FlutterAngleTexture::FlutterAngleTexture(
}
glBindTexture(GL_TEXTURE_2D, glTextureId);
eglBindTexImage(_eglDisplay, surface, EGL_BACK_BUFFER);
eglBindTexImage(_eglDisplay, _eglSurface, EGL_BACK_BUFFER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -210,7 +222,10 @@ FlutterAngleTexture::FlutterAngleTexture(
std::make_unique<flutter::TextureVariant>(flutter::GpuSurfaceTexture(
kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle,
[&](size_t width, size_t height) {
return _textureDescriptor.get();
if(width != this->_width || height != this->_height) {
this->_onResizeRequested(width, height);
}
return _textureDescriptor.get();
}));
flutterTextureId = _textureRegistrar->RegisterTexture(texture.get());

View File

@@ -38,7 +38,8 @@ class FlutterAngleTexture {
ID3D11DeviceContext* D3D11DeviceContext,
EGLConfig eglConfig,
EGLDisplay eglDisplay,
EGLContext eglContext
EGLContext eglContext,
std::function<void(size_t, size_t)> onResizeRequested
);
~FlutterAngleTexture();
@@ -55,6 +56,7 @@ class FlutterAngleTexture {
uint32_t _height = 0;
bool logged = false;
std::shared_ptr<std::mutex> _renderMutex;
std::function<void(size_t, size_t)> _onResizeRequested;
// Device
ID3D11Device* _D3D11Device = nullptr;
@@ -68,6 +70,7 @@ class FlutterAngleTexture {
EGLDisplay _eglDisplay = EGL_NO_DISPLAY;
EGLContext _eglContext = EGL_NO_CONTEXT;
EGLConfig _eglConfig = EGL_NO_CONFIG_KHR;
EGLSurface _eglSurface = EGL_NO_SURFACE;
std::unique_ptr<FlutterDesktopGpuSurfaceDescriptor> _textureDescriptor = nullptr;

View File

@@ -126,6 +126,17 @@ OpenGLTextureBuffer::OpenGLTextureBuffer(
result->Success(resultList);
}
OpenGLTextureBuffer::~OpenGLTextureBuffer() {}
OpenGLTextureBuffer::~OpenGLTextureBuffer() {
HWND hwnd = _pluginRegistrar->GetView()->GetNativeWindow();
HDC whdc = GetDC(hwnd);
if (!wglMakeCurrent(whdc, _context)) {
std::cout << "Failed to switch OpenGL context in destructor." << std::endl;
// result->Error("CONTEXT", "Failed to switch OpenGL context.", nullptr);
return;
}
glDeleteTextures(1, &this->_inactive->glTextureId);
wglMakeCurrent(NULL, NULL);
}
} // namespace polyvox_filament

View File

@@ -49,20 +49,21 @@ void PolyvoxFilamentPlugin::RegisterWithRegistrar(
&flutter::StandardMethodCodec::GetInstance());
auto plugin = std::make_unique<PolyvoxFilamentPlugin>(
registrar->texture_registrar(), registrar);
channel->SetMethodCallHandler(
[plugin_pointer = plugin.get()](const auto &call, auto result) {
plugin_pointer->HandleMethodCall(call, std::move(result));
});
registrar->texture_registrar(), registrar, channel);
registrar->AddPlugin(std::move(plugin));
}
PolyvoxFilamentPlugin::PolyvoxFilamentPlugin(
flutter::TextureRegistrar *textureRegistrar,
flutter::PluginRegistrarWindows *pluginRegistrar)
: _textureRegistrar(textureRegistrar), _pluginRegistrar(pluginRegistrar) {}
flutter::PluginRegistrarWindows *pluginRegistrar,
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>>& channel)
: _textureRegistrar(textureRegistrar), _pluginRegistrar(pluginRegistrar), _channel(std::move(channel)) {
_channel->SetMethodCallHandler(
[=](const auto &call, auto result) {
this->HandleMethodCall(call, std::move(result));
});
}
PolyvoxFilamentPlugin::~PolyvoxFilamentPlugin() {}
@@ -299,8 +300,13 @@ bool PolyvoxFilamentPlugin::MakeD3DTexture(uint32_t width, uint32_t height,std::
_D3D11DeviceContext,
_eglConfig,
_eglDisplay,
_context
);
_context, [=](size_t width, size_t height) {
std::vector<int64_t> list;
list.push_back((int64_t)width);
list.push_back((int64_t)height);
auto val = std::make_unique<flutter::EncodableValue>(list);
this->_channel->InvokeMethod("resize", std::move(val), nullptr);
});
return _active->flutterTextureId != -1;
}
@@ -446,7 +452,6 @@ void PolyvoxFilamentPlugin::DestroyTexture(
const flutter::MethodCall<flutter::EncodableValue> &methodCall,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
const auto *flutterTextureId =
std::get_if<int64_t>(methodCall.arguments());
@@ -470,24 +475,7 @@ void PolyvoxFilamentPlugin::DestroyTexture(
_textureRegistrar->UnregisterTexture(_active->flutterTextureId, [=,
sharedResult=std::move(sh)
]() {
#ifdef USE_ANGLE
this->_active = nullptr;
#else
if(this->_inactive) {
HWND hwnd = _pluginRegistrar->GetView()->GetNativeWindow();
HDC whdc = GetDC(hwnd);
if (!wglMakeCurrent(whdc, _context)) {
std::cout << "Failed to switch OpenGL context in destructor." << std::endl;
// result->Error("CONTEXT", "Failed to switch OpenGL context.", nullptr);
return;
}
glDeleteTextures(1, &this->_inactive->glTextureId);
wglMakeCurrent(NULL, NULL);
}
this->_inactive = std::move(this->_active);
#endif
this->_inactive = std::move(this->_active);
auto unique = std::move(*(sharedResult.get()));
unique->Success(flutter::EncodableValue(true));
std::cout << "Unregistered/destroyed texture." << std::endl;

View File

@@ -30,7 +30,8 @@ public:
static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar);
PolyvoxFilamentPlugin(flutter::TextureRegistrar *textureRegistrar,
flutter::PluginRegistrarWindows *registrar);
flutter::PluginRegistrarWindows *registrar,
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>>& channel);
virtual ~PolyvoxFilamentPlugin();
// Disallow copy and assign.
@@ -44,6 +45,7 @@ public:
flutter::PluginRegistrarWindows *_pluginRegistrar;
flutter::TextureRegistrar *_textureRegistrar;
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> _channel;
std::map<uint32_t, ResourceBuffer> _resources;
std::shared_ptr<std::mutex> _renderMutex;
@@ -66,6 +68,7 @@ public:
EGLConfig _eglConfig = NULL;
EGLDisplay _eglDisplay = NULL;
std::unique_ptr<FlutterAngleTexture> _active = nullptr;
std::unique_ptr<FlutterAngleTexture> _inactive = nullptr;
ID3D11Device* _D3D11Device = nullptr;
ID3D11DeviceContext* _D3D11DeviceContext = nullptr;
filament::backend::Platform* _platform = nullptr;