use shared EGLContext for ANGLE on Windows
This commit is contained in:
@@ -12,7 +12,6 @@ set(PLUGIN_NAME "polyvox_filament_plugin")
|
||||
list(APPEND PLUGIN_SOURCES
|
||||
"polyvox_filament_plugin.cpp"
|
||||
"polyvox_filament_plugin.h"
|
||||
"opengl_texture_buffer.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/src/AssetManager.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/src/FilamentViewer.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/src/PolyvoxFilamentApi.cpp"
|
||||
@@ -23,11 +22,16 @@ list(APPEND PLUGIN_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../ios/src/camutils/Bookmark.cpp"
|
||||
)
|
||||
|
||||
set(USE_ANGLE FALSE)
|
||||
set(USE_ANGLE TRUE)
|
||||
|
||||
if(USE_ANGLE)
|
||||
add_compile_definitions(USE_ANGLE)
|
||||
list(APPEND PLUGIN_SOURCES "PlatformAngle.cpp")
|
||||
list(APPEND PLUGIN_SOURCES
|
||||
# "PlatformAngle.cpp"
|
||||
"flutter_angle_texture.cpp"
|
||||
)
|
||||
else()
|
||||
list(APPEND PLUGIN_SOURCES "opengl_texture_buffer.cpp")
|
||||
endif()
|
||||
|
||||
# Define the plugin library target. Its name must not be changed (see comment
|
||||
@@ -57,6 +61,8 @@ if(USE_ANGLE)
|
||||
list(APPEND GL_LIBS
|
||||
EGL
|
||||
GLESv2
|
||||
#bluegl
|
||||
#opengl32
|
||||
)
|
||||
set(ANGLE_OR_OPENGL_DIR angle)
|
||||
add_library(EGL SHARED IMPORTED)
|
||||
@@ -67,6 +73,10 @@ if(USE_ANGLE)
|
||||
set_property(TARGET GLESv2 PROPERTY IMPORTED_IMPLIB_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lib/Debug/angle/libGLESv2.dll.lib")
|
||||
set_property(TARGET GLESv2 PROPERTY IMPORTED_IMPLIB_PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/angle/libGLESv2.dll.lib")
|
||||
set_property(TARGET GLESv2 PROPERTY IMPORTED_IMPLIB_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/angle/libGLESv2.dll.lib")
|
||||
add_library(bluegl SHARED IMPORTED)
|
||||
set_property(TARGET bluegl PROPERTY IMPORTED_IMPLIB_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lib/Debug/angle/bluegl.lib")
|
||||
set_property(TARGET bluegl PROPERTY IMPORTED_IMPLIB_PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/angle/bluegl.lib")
|
||||
set_property(TARGET bluegl PROPERTY IMPORTED_IMPLIB_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/angle/bluegl.lib")
|
||||
else()
|
||||
list(APPEND GL_LIBS
|
||||
bluegl
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
|
||||
using namespace utils;
|
||||
|
||||
PROC wglGetProcAddress(LPCSTR name) {
|
||||
// PANIC
|
||||
return nullptr;
|
||||
}
|
||||
// PROC wglGetProcAddress(LPCSTR name) {
|
||||
// // PANIC
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
namespace filament::backend::GLUtils {
|
||||
class unordered_string_set : public std::unordered_set<std::string_view> {
|
||||
@@ -108,6 +108,9 @@ PlatformANGLE::PlatformANGLE(
|
||||
|
||||
}
|
||||
|
||||
PlatformANGLE::~PlatformANGLE() {
|
||||
|
||||
}
|
||||
|
||||
backend::Driver* PlatformANGLE::createDriver(void* sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept {
|
||||
@@ -258,6 +261,13 @@ backend::Driver* PlatformANGLE::createDriver(void* sharedContext,
|
||||
}
|
||||
|
||||
glGenTextures(1, &glTextureId);
|
||||
|
||||
if (glTextureId == 0) {
|
||||
std::cout << "Failed to generate OpenGL texture for ANGLE, OpenGL err was %d",
|
||||
glGetError();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, glTextureId);
|
||||
eglBindTexImage(mEGLDisplay, mCurrentReadSurface, EGL_BACK_BUFFER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
@@ -437,10 +447,10 @@ bool PlatformANGLE::setExternalImage(void* externalImage,
|
||||
if (UTILS_LIKELY(ext.gl.OES_EGL_image_external_essl3)) {
|
||||
assert_invariant(texture->target == GL_TEXTURE_EXTERNAL_OES);
|
||||
// the texture is guaranteed to be bound here.
|
||||
#ifdef GL_OES_EGL_image
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
|
||||
static_cast<GLeglImageOES>(externalImage));
|
||||
#endif
|
||||
// #ifdef GL_OES_EGL_image
|
||||
// glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
|
||||
// static_cast<GLeglImageOES>(externalImage));
|
||||
// #endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace filament::backend {
|
||||
class PlatformANGLE : public OpenGLPlatform {
|
||||
public:
|
||||
PlatformANGLE(HANDLE d3dTextureHandle, uint32_t width, uint32_t height) noexcept;
|
||||
~PlatformANGLE();
|
||||
|
||||
Driver* createDriver(void* sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
230
windows/flutter_angle_texture.cpp
Normal file
230
windows/flutter_angle_texture.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
#include "flutter_angle_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 "backend/platforms/PlatformEGL.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace polyvox_filament {
|
||||
|
||||
static void logEglError(const char *name) noexcept {
|
||||
const char *err;
|
||||
switch (eglGetError()) {
|
||||
case EGL_NOT_INITIALIZED:
|
||||
err = "EGL_NOT_INITIALIZED";
|
||||
break;
|
||||
case EGL_BAD_ACCESS:
|
||||
err = "EGL_BAD_ACCESS";
|
||||
break;
|
||||
case EGL_BAD_ALLOC:
|
||||
err = "EGL_BAD_ALLOC";
|
||||
break;
|
||||
case EGL_BAD_ATTRIBUTE:
|
||||
err = "EGL_BAD_ATTRIBUTE";
|
||||
break;
|
||||
case EGL_BAD_CONTEXT:
|
||||
err = "EGL_BAD_CONTEXT";
|
||||
break;
|
||||
case EGL_BAD_CONFIG:
|
||||
err = "EGL_BAD_CONFIG";
|
||||
break;
|
||||
case EGL_BAD_CURRENT_SURFACE:
|
||||
err = "EGL_BAD_CURRENT_SURFACE";
|
||||
break;
|
||||
case EGL_BAD_DISPLAY:
|
||||
err = "EGL_BAD_DISPLAY";
|
||||
break;
|
||||
case EGL_BAD_SURFACE:
|
||||
err = "EGL_BAD_SURFACE";
|
||||
break;
|
||||
case EGL_BAD_MATCH:
|
||||
err = "EGL_BAD_MATCH";
|
||||
break;
|
||||
case EGL_BAD_PARAMETER:
|
||||
err = "EGL_BAD_PARAMETER";
|
||||
break;
|
||||
case EGL_BAD_NATIVE_PIXMAP:
|
||||
err = "EGL_BAD_NATIVE_PIXMAP";
|
||||
break;
|
||||
case EGL_BAD_NATIVE_WINDOW:
|
||||
err = "EGL_BAD_NATIVE_WINDOW";
|
||||
break;
|
||||
case EGL_CONTEXT_LOST:
|
||||
err = "EGL_CONTEXT_LOST";
|
||||
break;
|
||||
default:
|
||||
err = "unknown";
|
||||
break;
|
||||
}
|
||||
std::cout << name << " failed with " << err << std::endl;
|
||||
}
|
||||
|
||||
void FlutterAngleTexture::RenderCallback() {
|
||||
_D3D11DeviceContext->CopyResource(_externalD3DTexture2D.Get(),
|
||||
_internalD3DTexture2D.Get());
|
||||
_D3D11DeviceContext->Flush();
|
||||
}
|
||||
|
||||
FlutterAngleTexture::FlutterAngleTexture(
|
||||
flutter::PluginRegistrarWindows *pluginRegistrar,
|
||||
flutter::TextureRegistrar *textureRegistrar,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result,
|
||||
uint32_t width, uint32_t height, ID3D11Device *D3D11Device,
|
||||
ID3D11DeviceContext *D3D11DeviceContext, EGLConfig eglConfig,
|
||||
EGLDisplay eglDisplay, EGLContext eglContext)
|
||||
: _pluginRegistrar(pluginRegistrar), _textureRegistrar(textureRegistrar),
|
||||
_width(width), _height(height), _D3D11Device(D3D11Device),
|
||||
_D3D11DeviceContext(D3D11DeviceContext), _eglConfig(eglConfig),
|
||||
_eglDisplay(eglDisplay), _eglContext(eglContext) {
|
||||
|
||||
auto d3d11_texture2D_desc = D3D11_TEXTURE2D_DESC{0};
|
||||
d3d11_texture2D_desc.Width = width;
|
||||
d3d11_texture2D_desc.Height = height;
|
||||
d3d11_texture2D_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
d3d11_texture2D_desc.MipLevels = 1;
|
||||
d3d11_texture2D_desc.ArraySize = 1;
|
||||
d3d11_texture2D_desc.SampleDesc.Count = 1;
|
||||
d3d11_texture2D_desc.SampleDesc.Quality = 0;
|
||||
d3d11_texture2D_desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
d3d11_texture2D_desc.BindFlags =
|
||||
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
|
||||
d3d11_texture2D_desc.CPUAccessFlags = 0;
|
||||
d3d11_texture2D_desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||
|
||||
// create internal texture
|
||||
auto hr = _D3D11Device->CreateTexture2D(&d3d11_texture2D_desc, nullptr,
|
||||
&_internalD3DTexture2D);
|
||||
if FAILED (hr) {
|
||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||
return;
|
||||
;
|
||||
}
|
||||
auto resource = Microsoft::WRL::ComPtr<IDXGIResource>{};
|
||||
hr = _internalD3DTexture2D.As(&resource);
|
||||
|
||||
if FAILED (hr) {
|
||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||
return;
|
||||
;
|
||||
}
|
||||
hr = resource->GetSharedHandle(&_internalD3DTextureHandle);
|
||||
if FAILED (hr) {
|
||||
result->Error("ERROR", "Failed to get shared handle to D3D texture",
|
||||
nullptr);
|
||||
return;
|
||||
;
|
||||
}
|
||||
_internalD3DTexture2D->AddRef();
|
||||
|
||||
std::cout << "Created internal D3D texture" << std::endl;
|
||||
|
||||
// external
|
||||
hr = _D3D11Device->CreateTexture2D(&d3d11_texture2D_desc, nullptr,
|
||||
&_externalD3DTexture2D);
|
||||
if FAILED (hr) {
|
||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||
return;
|
||||
;
|
||||
}
|
||||
hr = _externalD3DTexture2D.As(&resource);
|
||||
|
||||
if FAILED (hr) {
|
||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||
return;
|
||||
;
|
||||
}
|
||||
hr = resource->GetSharedHandle(&_externalD3DTextureHandle);
|
||||
if FAILED (hr) {
|
||||
result->Error("ERROR",
|
||||
"Failed to get shared handle to external D3D texture",
|
||||
nullptr);
|
||||
return;
|
||||
;
|
||||
}
|
||||
_externalD3DTexture2D->AddRef();
|
||||
|
||||
std::cout << "Created external D3D texture" << std::endl;
|
||||
|
||||
EGLint pbufferAttribs[] = {
|
||||
EGL_WIDTH, width, EGL_HEIGHT, height,
|
||||
EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
auto surface = eglCreatePbufferFromClientBuffer(
|
||||
_eglDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
|
||||
_internalD3DTextureHandle, _eglConfig, pbufferAttribs);
|
||||
|
||||
if (!eglMakeCurrent(_eglDisplay, surface, surface, _eglContext)) {
|
||||
// eglMakeCurrent failed
|
||||
logEglError("eglMakeCurrent");
|
||||
return;
|
||||
}
|
||||
|
||||
glGenTextures(1, &glTextureId);
|
||||
|
||||
if (glTextureId == 0) {
|
||||
std::cout
|
||||
<< "Failed to generate OpenGL texture for ANGLE, OpenGL err was %d",
|
||||
glGetError();
|
||||
return;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, glTextureId);
|
||||
eglBindTexImage(_eglDisplay, surface, EGL_BACK_BUFFER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
// clearGlError
|
||||
GLenum const error = glGetError();
|
||||
if (error != GL_NO_ERROR) {
|
||||
std::cout << "Ignoring pending GL error " << error << std::endl;
|
||||
}
|
||||
char const *version;
|
||||
|
||||
version = (char const *)glGetString(GL_VERSION);
|
||||
std::cout << "Got version " << version << std::endl;
|
||||
|
||||
EGLint major, minor;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
||||
|
||||
// platform = new filament::backend::PlatformANGLE(_internalD3DTextureHandle,
|
||||
// width, height);
|
||||
platform = new filament::backend::PlatformEGL(); //_internalD3DTextureHandle,
|
||||
//width, height);
|
||||
|
||||
_textureDescriptor = std::make_unique<FlutterDesktopGpuSurfaceDescriptor>();
|
||||
_textureDescriptor->struct_size = sizeof(FlutterDesktopGpuSurfaceDescriptor);
|
||||
_textureDescriptor->handle = _externalD3DTextureHandle;
|
||||
_textureDescriptor->width = _textureDescriptor->visible_width = width;
|
||||
_textureDescriptor->height = _textureDescriptor->visible_height = height;
|
||||
_textureDescriptor->release_context = nullptr;
|
||||
_textureDescriptor->release_callback = [](void *release_context) {
|
||||
|
||||
};
|
||||
_textureDescriptor->format = kFlutterDesktopPixelFormatBGRA8888;
|
||||
|
||||
texture =
|
||||
std::make_unique<flutter::TextureVariant>(flutter::GpuSurfaceTexture(
|
||||
kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle,
|
||||
[&](auto, auto) { 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));
|
||||
result->Success(resultList);
|
||||
}
|
||||
|
||||
FlutterAngleTexture::~FlutterAngleTexture() {}
|
||||
|
||||
} // namespace polyvox_filament
|
||||
81
windows/flutter_angle_texture.h
Normal file
81
windows/flutter_angle_texture.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef _FLUTTER_ANGLE_TEXTURE_H
|
||||
#define _FLUTTER_ANGLE_TEXTURE_H
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <flutter/texture_registrar.h>
|
||||
#include <flutter/method_channel.h>
|
||||
#include <flutter/plugin_registrar_windows.h>
|
||||
|
||||
#include <d3d.h>
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "EGL/egl.h"
|
||||
#include "EGL/eglext.h"
|
||||
#include "EGL/eglplatform.h"
|
||||
#include "GLES2/gl2.h"
|
||||
#include "GLES2/gl2ext.h"
|
||||
#include <GLES3/gl31.h>
|
||||
|
||||
#include "PlatformANGLE.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <wrl.h>
|
||||
|
||||
typedef uint32_t GLuint;
|
||||
|
||||
namespace polyvox_filament {
|
||||
|
||||
class FlutterAngleTexture {
|
||||
public:
|
||||
FlutterAngleTexture(
|
||||
flutter::PluginRegistrarWindows* pluginRegistrar,
|
||||
flutter::TextureRegistrar* textureRegistrar,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
ID3D11Device* D3D11Device,
|
||||
ID3D11DeviceContext* D3D11DeviceContext,
|
||||
EGLConfig eglConfig,
|
||||
EGLDisplay eglDisplay,
|
||||
EGLContext eglContext
|
||||
);
|
||||
~FlutterAngleTexture();
|
||||
|
||||
void RenderCallback();
|
||||
|
||||
int64_t flutterTextureId = 0;
|
||||
GLuint glTextureId = 0;
|
||||
std::unique_ptr<flutter::TextureVariant> texture;
|
||||
filament::backend::Platform* platform = nullptr;
|
||||
|
||||
|
||||
private:
|
||||
flutter::PluginRegistrarWindows* _pluginRegistrar;
|
||||
flutter::TextureRegistrar* _textureRegistrar;
|
||||
uint32_t _width = 0;
|
||||
uint32_t _height = 0;
|
||||
bool logged = false;
|
||||
std::shared_ptr<std::mutex> _renderMutex;
|
||||
|
||||
// Device
|
||||
ID3D11Device* _D3D11Device = nullptr;
|
||||
ID3D11DeviceContext* _D3D11DeviceContext = nullptr;
|
||||
// Texture objects/shared handles
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> _externalD3DTexture2D;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> _internalD3DTexture2D;
|
||||
HANDLE _externalD3DTextureHandle = nullptr;
|
||||
HANDLE _internalD3DTextureHandle = nullptr;
|
||||
|
||||
EGLDisplay _eglDisplay = EGL_NO_DISPLAY;
|
||||
EGLContext _eglContext = EGL_NO_CONTEXT;
|
||||
EGLConfig _eglConfig = EGL_NO_CONFIG_KHR;
|
||||
|
||||
std::unique_ptr<FlutterDesktopGpuSurfaceDescriptor> _textureDescriptor = nullptr;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif // _FLUTTER_ANGLE_TEXTURE
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:bf1bd7a89d00fa74f04c446aaeb9742793e02b42d53c0cf1375951f5948cd2ef
|
||||
size 20108820
|
||||
oid sha256:1fcbbe01dc1cc92264b2bcf56a386c34c79fb2c90b5ab5f95e8aa37db3542788
|
||||
size 20903930
|
||||
|
||||
@@ -136,249 +136,253 @@ void render_callback(void* owner) {
|
||||
|
||||
// this is the method on PolyvoxFilamentPlugin that will copy between D3D textures
|
||||
void PolyvoxFilamentPlugin::RenderCallback() {
|
||||
#ifdef USE_ANGLE
|
||||
_D3D11DeviceContext->CopyResource(_externalD3DTexture2D.Get(),
|
||||
_internalD3DTexture2D.Get());
|
||||
_D3D11DeviceContext->Flush();
|
||||
#endif
|
||||
|
||||
std::lock_guard<std::mutex> guard(*(_renderMutex.get()));
|
||||
if (_active) {
|
||||
#ifdef USE_ANGLE
|
||||
_active->RenderCallback();
|
||||
#endif
|
||||
_textureRegistrar->MarkTextureFrameAvailable(_active->flutterTextureId);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_ANGLE
|
||||
bool PolyvoxFilamentPlugin::MakeD3DTexture(uint32_t width, uint32_t height,std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
bool PolyvoxFilamentPlugin::CreateSharedEGLContext() {
|
||||
// D3D starts here
|
||||
IDXGIAdapter* adapter_ = nullptr;
|
||||
|
||||
// D3D starts here
|
||||
IDXGIAdapter* adapter_ = nullptr;
|
||||
// first, we need to initialize the D3D device and create the backing texture
|
||||
// this has been taken from https://github.com/alexmercerind/flutter-windows-ANGLE-OpenGL-ES/blob/master/windows/angle_surface_manager.cc
|
||||
auto feature_levels = {
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0,
|
||||
D3D_FEATURE_LEVEL_9_3,
|
||||
};
|
||||
// NOTE: Not enabling DirectX 12.
|
||||
// |D3D11CreateDevice| crashes directly on Windows 7.
|
||||
// D3D_FEATURE_LEVEL_12_2, D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0,
|
||||
// D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1,
|
||||
// D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3,
|
||||
IDXGIFactory* dxgi = nullptr;
|
||||
::CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&dxgi);
|
||||
// Manually selecting adapter. As far as my experience goes, this is the
|
||||
// safest approach. Passing NULL (so-called default) seems to cause issues
|
||||
// on Windows 7 or maybe some older graphics drivers.
|
||||
// First adapter is the default.
|
||||
// |D3D_DRIVER_TYPE_UNKNOWN| must be passed with manual adapter selection.
|
||||
dxgi->EnumAdapters(0, &adapter_);
|
||||
dxgi->Release();
|
||||
if (!adapter_) {
|
||||
std::cout << "Failed to locate default D3D adapter"<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
DXGI_ADAPTER_DESC adapter_desc_;
|
||||
adapter_->GetDesc(&adapter_desc_);
|
||||
std::wcout << L"D3D adapter description: " << adapter_desc_.Description << std::endl;
|
||||
|
||||
auto hr = ::D3D11CreateDevice(
|
||||
adapter_, D3D_DRIVER_TYPE_UNKNOWN, 0, 0, feature_levels.begin(),
|
||||
static_cast<UINT>(feature_levels.size()), D3D11_SDK_VERSION,
|
||||
&_D3D11Device, 0, &_D3D11DeviceContext);
|
||||
|
||||
// first, we need to initialize the D3D device and create the backing texture
|
||||
// this has been taken from https://github.com/alexmercerind/flutter-windows-ANGLE-OpenGL-ES/blob/master/windows/angle_surface_manager.cc
|
||||
auto feature_levels = {
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0,
|
||||
D3D_FEATURE_LEVEL_9_3,
|
||||
if (FAILED(hr)) {
|
||||
std::cout << "Failed to create D3D device"<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device = nullptr;
|
||||
auto dxgi_device_success = _D3D11Device->QueryInterface(
|
||||
__uuidof(IDXGIDevice), (void**)&dxgi_device);
|
||||
if (SUCCEEDED(dxgi_device_success) && dxgi_device != nullptr) {
|
||||
dxgi_device->SetGPUThreadPriority(5); // Must be in interval [-7, 7].
|
||||
}
|
||||
auto level = _D3D11Device->GetFeatureLevel();
|
||||
std::cout << "media_kit: ANGLESurfaceManager: Direct3D Feature Level: "
|
||||
<< (((unsigned)level) >> 12) << "_"
|
||||
<< ((((unsigned)level) >> 8) & 0xf) << std::endl;
|
||||
|
||||
|
||||
// *******************
|
||||
// * *
|
||||
// * *
|
||||
// * EGL starts here *
|
||||
// * *
|
||||
// * *
|
||||
// * *
|
||||
// *******************
|
||||
EGLBoolean bindAPI = eglBindAPI(EGL_OPENGL_ES_API);
|
||||
if (UTILS_UNLIKELY(!bindAPI)) {
|
||||
std::cout << "eglBindAPI EGL_OPENGL_ES_API failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
assert_invariant(_eglDisplay != EGL_NO_DISPLAY);
|
||||
|
||||
EGLint major, minor;
|
||||
EGLBoolean initialized = false; // = eglInitialize(_eglDisplay, &major, &minor);
|
||||
|
||||
// if (!initialized) {
|
||||
EGLDeviceEXT eglDevice;
|
||||
EGLint numDevices;
|
||||
|
||||
if(auto* getPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
|
||||
eglGetProcAddress("eglGetPlatformDisplayEXT"))) {
|
||||
|
||||
EGLint kD3D11DisplayAttributes[] = {
|
||||
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
|
||||
EGL_TRUE,
|
||||
EGL_NONE,
|
||||
};
|
||||
_eglDisplay = getPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, kD3D11DisplayAttributes);
|
||||
initialized = eglInitialize(_eglDisplay, &major, &minor);
|
||||
}
|
||||
|
||||
std::cout << "Got major " << major << " and minor " << minor << std::endl;
|
||||
|
||||
if (UTILS_UNLIKELY(!initialized)) {
|
||||
std::cout << "eglInitialize failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
importGLESExtensionsEntryPoints();
|
||||
|
||||
EGLint configsCount;
|
||||
|
||||
EGLint configAttribs[] = {
|
||||
EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, EGL_ALPHA_SIZE, 8,
|
||||
EGL_NONE
|
||||
};
|
||||
// NOTE: Not enabling DirectX 12.
|
||||
// |D3D11CreateDevice| crashes directly on Windows 7.
|
||||
// D3D_FEATURE_LEVEL_12_2, D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0,
|
||||
// D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1,
|
||||
// D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3,
|
||||
IDXGIFactory* dxgi = nullptr;
|
||||
::CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&dxgi);
|
||||
// Manually selecting adapter. As far as my experience goes, this is the
|
||||
// safest approach. Passing NULL (so-called default) seems to cause issues
|
||||
// on Windows 7 or maybe some older graphics drivers.
|
||||
// First adapter is the default.
|
||||
// |D3D_DRIVER_TYPE_UNKNOWN| must be passed with manual adapter selection.
|
||||
dxgi->EnumAdapters(0, &adapter_);
|
||||
dxgi->Release();
|
||||
if (!adapter_) {
|
||||
result->Error("ERROR", "Failed to locate default D3D adapter", nullptr);
|
||||
|
||||
EGLint contextAttribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||
EGL_NONE, EGL_NONE, // reserved for EGL_CONTEXT_OPENGL_NO_ERROR_KHR below
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
// find an opaque config
|
||||
if (!eglChooseConfig(_eglDisplay, configAttribs, &_eglConfig, 1, &configsCount)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_context = (void*)eglCreateContext(_eglDisplay, _eglConfig, EGL_NO_CONTEXT, contextAttribs);
|
||||
|
||||
if (UTILS_UNLIKELY(_context == EGL_NO_CONTEXT)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PolyvoxFilamentPlugin::MakeD3DTexture(uint32_t width, uint32_t height,std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
importGLESExtensionsEntryPoints();
|
||||
|
||||
if(_active.get()) {
|
||||
result->Error("ERROR", "Texture already exists. You must call destroyTexture before attempting to create a new one.");
|
||||
return false;
|
||||
}
|
||||
|
||||
_active = std::make_unique<FlutterAngleTexture>(
|
||||
_pluginRegistrar,
|
||||
_textureRegistrar,
|
||||
std::move(result),
|
||||
width,
|
||||
height,
|
||||
_D3D11Device,
|
||||
_D3D11DeviceContext,
|
||||
_eglConfig,
|
||||
_eglDisplay,
|
||||
_context
|
||||
);
|
||||
|
||||
DXGI_ADAPTER_DESC adapter_desc_;
|
||||
adapter_->GetDesc(&adapter_desc_);
|
||||
std::wcout << L"D3D adapter description: " << adapter_desc_.Description << std::endl;
|
||||
|
||||
auto hr = ::D3D11CreateDevice(
|
||||
adapter_, D3D_DRIVER_TYPE_UNKNOWN, 0, 0, feature_levels.begin(),
|
||||
static_cast<UINT>(feature_levels.size()), D3D11_SDK_VERSION,
|
||||
&_D3D11Device, 0, &_D3D11DeviceContext);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
result->Error("ERROR", "Failed to create D3D device", nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device = nullptr;
|
||||
auto dxgi_device_success = _D3D11Device->QueryInterface(
|
||||
__uuidof(IDXGIDevice), (void**)&dxgi_device);
|
||||
if (SUCCEEDED(dxgi_device_success) && dxgi_device != nullptr) {
|
||||
dxgi_device->SetGPUThreadPriority(5); // Must be in interval [-7, 7].
|
||||
}
|
||||
|
||||
auto level = _D3D11Device->GetFeatureLevel();
|
||||
std::cout << "media_kit: ANGLESurfaceManager: Direct3D Feature Level: "
|
||||
<< (((unsigned)level) >> 12) << "_"
|
||||
<< ((((unsigned)level) >> 8) & 0xf) << std::endl;
|
||||
auto d3d11_texture2D_desc = D3D11_TEXTURE2D_DESC{0};
|
||||
d3d11_texture2D_desc.Width = width;
|
||||
d3d11_texture2D_desc.Height = height;
|
||||
d3d11_texture2D_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
d3d11_texture2D_desc.MipLevels = 1;
|
||||
d3d11_texture2D_desc.ArraySize = 1;
|
||||
d3d11_texture2D_desc.SampleDesc.Count = 1;
|
||||
d3d11_texture2D_desc.SampleDesc.Quality = 0;
|
||||
d3d11_texture2D_desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
d3d11_texture2D_desc.BindFlags =
|
||||
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
|
||||
d3d11_texture2D_desc.CPUAccessFlags = 0;
|
||||
d3d11_texture2D_desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||
|
||||
// create internal texture
|
||||
hr = _D3D11Device->CreateTexture2D(&d3d11_texture2D_desc, nullptr, &_internalD3DTexture2D);
|
||||
if FAILED(hr)
|
||||
{
|
||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||
return false;
|
||||
}
|
||||
auto resource = Microsoft::WRL::ComPtr<IDXGIResource>{};
|
||||
hr = _internalD3DTexture2D.As(&resource);
|
||||
|
||||
if FAILED(hr) {
|
||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||
return false;
|
||||
}
|
||||
hr = resource->GetSharedHandle(&_internalD3DTextureHandle);
|
||||
if FAILED(hr) {
|
||||
result->Error("ERROR", "Failed to get shared handle to D3D texture", nullptr);
|
||||
return false;
|
||||
}
|
||||
_internalD3DTexture2D->AddRef();
|
||||
|
||||
std::cout << "Created internal D3D texture" << std::endl;
|
||||
|
||||
// external
|
||||
hr = _D3D11Device->CreateTexture2D(&d3d11_texture2D_desc, nullptr, &_externalD3DTexture2D);
|
||||
if FAILED(hr)
|
||||
{
|
||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||
return false;
|
||||
}
|
||||
hr = _externalD3DTexture2D.As(&resource);
|
||||
|
||||
if FAILED(hr) {
|
||||
result->Error("ERROR", "Failed to create D3D texture", nullptr);
|
||||
return false;
|
||||
}
|
||||
hr = resource->GetSharedHandle(&_externalD3DTextureHandle);
|
||||
if FAILED(hr) {
|
||||
result->Error("ERROR", "Failed to get shared handle to external D3D texture", nullptr);
|
||||
return false;
|
||||
}
|
||||
_externalD3DTexture2D->AddRef();
|
||||
|
||||
std::cout << "Created external D3D texture" << std::endl;
|
||||
|
||||
_platform = new filament::backend::PlatformANGLE(_internalD3DTextureHandle, width, height);
|
||||
|
||||
_textureDescriptor = std::make_unique<FlutterDesktopGpuSurfaceDescriptor>();
|
||||
_textureDescriptor->struct_size = sizeof(FlutterDesktopGpuSurfaceDescriptor);
|
||||
_textureDescriptor->handle = _externalD3DTextureHandle;
|
||||
_textureDescriptor->width = _textureDescriptor->visible_width = width;
|
||||
_textureDescriptor->height = _textureDescriptor->visible_height = height;
|
||||
_textureDescriptor->release_context = nullptr;
|
||||
_textureDescriptor->release_callback = [](void* release_context) {};
|
||||
_textureDescriptor->format = kFlutterDesktopPixelFormatBGRA8888;
|
||||
|
||||
_texture =
|
||||
std::make_unique<flutter::TextureVariant>(flutter::GpuSurfaceTexture(
|
||||
kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle,
|
||||
[&](auto, auto) { 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(_platform->glTextureId));
|
||||
result->Success(resultList);
|
||||
return true;
|
||||
return _active->flutterTextureId != -1;
|
||||
}
|
||||
#else
|
||||
bool PolyvoxFilamentPlugin::MakeOpenGLTexture(uint32_t width, uint32_t height,std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
#else
|
||||
bool PolyvoxFilamentPlugin::CreateSharedWGLContext() {
|
||||
|
||||
HWND hwnd = _pluginRegistrar->GetView()
|
||||
->GetNativeWindow();
|
||||
|
||||
HDC whdc = GetDC(hwnd);
|
||||
if (whdc == NULL) {
|
||||
result->Error("ERROR", "No device context for temporary window", nullptr);
|
||||
std::cout << "No device context for temporary window" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!_renderMutex.get()) {
|
||||
_renderMutex = std::make_shared<std::mutex>();
|
||||
}
|
||||
|
||||
|
||||
// we need a single context (since this will be passed to the renderer)
|
||||
// if this is the first time we are attempting to create a texture, let's create the context
|
||||
if(_context == NULL) {
|
||||
|
||||
std::cout << "No GL context exists, creating" << std::endl;
|
||||
std::cout << "No GL context exists, creating" << std::endl;
|
||||
|
||||
PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
|
||||
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
|
||||
32, // Colordepth of the framebuffer.
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
32, // Number of bits for the depthbuffer
|
||||
0, // Number of bits for the stencilbuffer
|
||||
0, // Number of Aux buffers in the framebuffer.
|
||||
PFD_MAIN_PLANE,
|
||||
0,
|
||||
0, 0, 0
|
||||
};
|
||||
PIXELFORMATDESCRIPTOR pfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1,
|
||||
PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
|
||||
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
|
||||
32, // Colordepth of the framebuffer.
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0, 0, 0,
|
||||
32, // Number of bits for the depthbuffer
|
||||
0, // Number of bits for the stencilbuffer
|
||||
0, // Number of Aux buffers in the framebuffer.
|
||||
PFD_MAIN_PLANE,
|
||||
0,
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
int pixelFormat = ChoosePixelFormat(whdc, &pfd);
|
||||
SetPixelFormat(whdc, pixelFormat, &pfd);
|
||||
int pixelFormat = ChoosePixelFormat(whdc, &pfd);
|
||||
SetPixelFormat(whdc, pixelFormat, &pfd);
|
||||
|
||||
// We need a tmp context to retrieve and call wglCreateContextAttribsARB.
|
||||
HGLRC tempContext = wglCreateContext(whdc);
|
||||
if (!wglMakeCurrent(whdc, tempContext)) {
|
||||
result->Error("ERROR", "Failed to acquire temporary context", nullptr);
|
||||
// We need a tmp context to retrieve and call wglCreateContextAttribsARB.
|
||||
HGLRC tempContext = wglCreateContext(whdc);
|
||||
if (!wglMakeCurrent(whdc, tempContext)) {
|
||||
std::cout <<"Failed to acquire temporary context" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
GLenum err = glGetError();
|
||||
|
||||
if(err != GL_NO_ERROR) {
|
||||
std::cout <<"GL Error @ 455 %d" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = nullptr;
|
||||
|
||||
wglCreateContextAttribs =
|
||||
(PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress(
|
||||
"wglCreateContextAttribsARB");
|
||||
|
||||
if (!wglCreateContextAttribs) {
|
||||
std::cout <<"Failed to resolve wglCreateContextAttribsARB" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int minor = 5; minor >= 1; minor--) {
|
||||
std::vector<int> mAttribs = {WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, minor, 0};
|
||||
_context = wglCreateContextAttribs(whdc, nullptr, mAttribs.data());
|
||||
if (_context) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GLenum err = glGetError();
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(tempContext);
|
||||
|
||||
if(err != GL_NO_ERROR) {
|
||||
result->Error("ERROR", "GL Error @ 455 %d", err);
|
||||
return false;
|
||||
}
|
||||
if (!_context || !wglMakeCurrent(whdc, _context)) {
|
||||
std::cout << "Failed to create OpenGL context." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = nullptr;
|
||||
|
||||
wglCreateContextAttribs =
|
||||
(PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress(
|
||||
"wglCreateContextAttribsARB");
|
||||
}
|
||||
|
||||
if (!wglCreateContextAttribs) {
|
||||
result->Error("ERROR", "Failed to resolve wglCreateContextAttribsARB",
|
||||
nullptr);
|
||||
return false;
|
||||
}
|
||||
bool PolyvoxFilamentPlugin::MakeOpenGLTexture(uint32_t width, uint32_t height,std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
|
||||
for (int minor = 5; minor >= 1; minor--) {
|
||||
std::vector<int> mAttribs = {WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, minor, 0};
|
||||
_context = wglCreateContextAttribs(whdc, nullptr, mAttribs.data());
|
||||
if (_context) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(tempContext);
|
||||
|
||||
if (!_context || !wglMakeCurrent(whdc, _context)) {
|
||||
result->Error("ERROR", "Failed to create OpenGL context.");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(_active.get()) {
|
||||
result->Error("ERROR", "Texture already exists. You must call destroyTexture before attempting to create a new one.");
|
||||
return false;
|
||||
@@ -397,18 +401,36 @@ bool PolyvoxFilamentPlugin::MakeOpenGLTexture(uint32_t width, uint32_t height,st
|
||||
return _active->flutterTextureId != -1;
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
void PolyvoxFilamentPlugin::CreateTexture(
|
||||
const flutter::MethodCall<flutter::EncodableValue> &methodCall,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
|
||||
|
||||
if(!_renderMutex.get()) {
|
||||
_renderMutex = std::make_shared<std::mutex>();
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(*(_renderMutex.get()));
|
||||
|
||||
const auto *args =
|
||||
std::get_if<flutter::EncodableList>(methodCall.arguments());
|
||||
|
||||
const auto width = (uint32_t)round(*(std::get_if<double>(&(args->at(0)))));
|
||||
const auto height = (uint32_t)round(*(std::get_if<double>(&(args->at(1)))));
|
||||
|
||||
// create a single shared context for the life of the application
|
||||
// this will be used to create a backing texture and passed to Filament
|
||||
if(!_context) {
|
||||
#ifdef USE_ANGLE
|
||||
CreateSharedEGLContext();
|
||||
#else
|
||||
CreateSharedWGLContext();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_ANGLE
|
||||
bool success = MakeD3DTexture(width, height, std::move(result));
|
||||
#else
|
||||
@@ -428,59 +450,55 @@ void PolyvoxFilamentPlugin::DestroyTexture(
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_ANGLE
|
||||
// TODO
|
||||
result->Error("NOT_IMPLEMENTED", "Method is not implemented %s", methodCall.method_name());
|
||||
#else
|
||||
auto sh = std::make_shared<std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>>>(std::move(result));
|
||||
|
||||
if(!_active) {
|
||||
result->Success("Texture has already been detroyed, ignoring");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!_active) {
|
||||
result->Success("Texture has already been detroyed, ignoring");
|
||||
return;
|
||||
}
|
||||
if(_active->flutterTextureId != *flutterTextureId) {
|
||||
result->Error("TEXTURE_MISMATCH", "Specified texture ID is not active");
|
||||
return;
|
||||
}
|
||||
|
||||
if(_active->flutterTextureId != *flutterTextureId) {
|
||||
result->Error("TEXTURE_MISMATCH", "Specified texture ID is not active");
|
||||
return;
|
||||
}
|
||||
auto sh = std::make_shared<std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>>>(std::move(result));
|
||||
|
||||
|
||||
// result->Error("NOT_IMPLEMENTED", "Method is not implemented %s", methodCall.method_name());
|
||||
_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(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;
|
||||
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);
|
||||
}
|
||||
glDeleteTextures(1, &this->_inactive->glTextureId);
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
}
|
||||
this->_inactive = std::move(this->_active);
|
||||
this->_inactive = std::move(this->_active);
|
||||
#endif
|
||||
auto unique = std::move(*(sharedResult.get()));
|
||||
unique->Success(flutter::EncodableValue(true));
|
||||
std::cout << "Destroyed OpenGLTextureBuffer." << std::endl;
|
||||
std::cout << "Unregistered/destroyed texture." << std::endl;
|
||||
});
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
void PolyvoxFilamentPlugin::HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue> &methodCall,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
|
||||
// std::cout << methodCall.method_name() << std::endl;
|
||||
if (methodCall.method_name() == "getSharedContext") {
|
||||
#ifdef USE_ANGLE
|
||||
result->Success(flutter::EncodableValue((int64_t)nullptr));
|
||||
#else
|
||||
result->Success(flutter::EncodableValue((int64_t)_context));
|
||||
#endif
|
||||
} else if (methodCall.method_name() == "getResourceLoaderWrapper") {
|
||||
const ResourceLoaderWrapper *const resourceLoader =
|
||||
new ResourceLoaderWrapper(_loadResource, _freeResource, this);
|
||||
@@ -496,7 +514,7 @@ void PolyvoxFilamentPlugin::HandleMethodCall(
|
||||
result->Success(resultList);
|
||||
} else if(methodCall.method_name() == "getDriverPlatform") {
|
||||
#ifdef USE_ANGLE
|
||||
result->Success(flutter::EncodableValue((int64_t)_platform));
|
||||
result->Success(flutter::EncodableValue((int64_t)_active->platform));
|
||||
#else
|
||||
result->Success(flutter::EncodableValue((int64_t)nullptr));
|
||||
#endif
|
||||
|
||||
@@ -11,21 +11,11 @@
|
||||
#include <Windows.h>
|
||||
#include <wrl.h>
|
||||
|
||||
#ifdef USE_ANGLE
|
||||
#include <d3d.h>
|
||||
#include <d3d11.h>
|
||||
#endif
|
||||
|
||||
#include "GL/GL.h"
|
||||
#include "GL/GLu.h"
|
||||
|
||||
#ifdef USE_ANGLE
|
||||
#include "EGL/egl.h"
|
||||
#include "EGL/eglext.h"
|
||||
#include "EGL/eglplatform.h"
|
||||
#include "GLES2/gl2.h"
|
||||
#include "GLES2/gl2ext.h"
|
||||
#include "PlatformAngle.h"
|
||||
#include "flutter_angle_texture.h"
|
||||
#else
|
||||
#include "opengl_texture_buffer.h"
|
||||
#endif
|
||||
@@ -53,33 +43,9 @@ public:
|
||||
|
||||
flutter::PluginRegistrarWindows *_pluginRegistrar;
|
||||
flutter::TextureRegistrar *_textureRegistrar;
|
||||
|
||||
std::map<uint32_t, ResourceBuffer> _resources;
|
||||
|
||||
std::unique_ptr<FlutterDesktopGpuSurfaceDescriptor> _textureDescriptor = nullptr;
|
||||
|
||||
#ifdef USE_ANGLE
|
||||
// Device
|
||||
ID3D11Device* _D3D11Device = nullptr;
|
||||
ID3D11DeviceContext* _D3D11DeviceContext = nullptr;
|
||||
// Texture objects/shared handles
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> _externalD3DTexture2D;
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> _internalD3DTexture2D;
|
||||
HANDLE _externalD3DTextureHandle = nullptr;
|
||||
HANDLE _internalD3DTextureHandle = nullptr;
|
||||
filament::backend::PlatformANGLE* _platform = nullptr;
|
||||
|
||||
bool MakeD3DTexture(uint32_t width, uint32_t height, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
#else
|
||||
std::shared_ptr<std::mutex> _renderMutex;
|
||||
std::unique_ptr<OpenGLTextureBuffer> _active = nullptr;
|
||||
std::unique_ptr<OpenGLTextureBuffer> _inactive = nullptr;
|
||||
|
||||
// shared OpenGLContext
|
||||
HGLRC _context = NULL;
|
||||
bool MakeOpenGLTexture(uint32_t width, uint32_t height, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
#endif
|
||||
|
||||
|
||||
void CreateTexture(
|
||||
const flutter::MethodCall<flutter::EncodableValue> &methodCall,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
@@ -90,6 +56,25 @@ public:
|
||||
|
||||
ResourceBuffer loadResource(const char *path);
|
||||
void freeResource(ResourceBuffer rbuf);
|
||||
|
||||
private:
|
||||
#ifdef USE_ANGLE
|
||||
EGLContext _context = NULL;
|
||||
EGLConfig _eglConfig = NULL;
|
||||
EGLDisplay _eglDisplay = NULL;
|
||||
std::unique_ptr<FlutterAngleTexture> _active = nullptr;
|
||||
ID3D11Device* _D3D11Device = nullptr;
|
||||
ID3D11DeviceContext* _D3D11DeviceContext = nullptr;
|
||||
bool CreateSharedEGLContext();
|
||||
bool MakeD3DTexture(uint32_t width, uint32_t height, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
#else
|
||||
std::unique_ptr<OpenGLTextureBuffer> _active = nullptr;
|
||||
std::unique_ptr<OpenGLTextureBuffer> _inactive = nullptr;
|
||||
// shared OpenGLContext
|
||||
HGLRC _context = NULL;
|
||||
bool CreateSharedWGLContext();
|
||||
bool MakeOpenGLTexture(uint32_t width, uint32_t height, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace polyvox_filament
|
||||
|
||||
Reference in New Issue
Block a user