refactor Windows classes to separate EGL/WGL/Backing Window
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
#include <map>
|
||||
@@ -26,21 +27,29 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <future>
|
||||
#include <thread>
|
||||
|
||||
#include "PolyvoxFilamentApi.h"
|
||||
#ifdef USE_ANGLE
|
||||
#include "PlatformANGLE.h"
|
||||
#endif
|
||||
|
||||
#include <Commctrl.h>
|
||||
#include <Windows.h>
|
||||
#include <dwmapi.h>
|
||||
#include <wrl.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "flutter_render_context.h"
|
||||
|
||||
#if USE_ANGLE
|
||||
#include "egl_context.h"
|
||||
#else
|
||||
#include "wgl_context.h"
|
||||
#endif
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace polyvox_filament {
|
||||
|
||||
// static
|
||||
void PolyvoxFilamentPlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrarWindows *registrar) {
|
||||
auto channel =
|
||||
@@ -57,21 +66,25 @@ void PolyvoxFilamentPlugin::RegisterWithRegistrar(
|
||||
PolyvoxFilamentPlugin::PolyvoxFilamentPlugin(
|
||||
flutter::TextureRegistrar *textureRegistrar,
|
||||
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));
|
||||
});
|
||||
}
|
||||
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> &channel)
|
||||
: _textureRegistrar(textureRegistrar), _pluginRegistrar(pluginRegistrar),
|
||||
_channel(std::move(channel)) {
|
||||
|
||||
// attach the method call handler for incoming messages
|
||||
_channel->SetMethodCallHandler([=](const auto &call, auto result) {
|
||||
std::cout << call.method_name() << std::endl;
|
||||
this->HandleMethodCall(call, std::move(result));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
PolyvoxFilamentPlugin::~PolyvoxFilamentPlugin() {}
|
||||
|
||||
ResourceBuffer PolyvoxFilamentPlugin::loadResource(const char *name) {
|
||||
|
||||
|
||||
std::string name_str(name);
|
||||
std::filesystem::path targetFilePath;
|
||||
|
||||
|
||||
if (name_str.rfind("file://", 0) == 0) {
|
||||
targetFilePath = name_str.substr(7);
|
||||
} else {
|
||||
@@ -89,14 +102,14 @@ ResourceBuffer PolyvoxFilamentPlugin::loadResource(const char *name) {
|
||||
std::wstring exePathBuf(pBuf);
|
||||
std::filesystem::path exePath(exePathBuf);
|
||||
auto exeDir = exePath.remove_filename();
|
||||
targetFilePath = exeDir.wstring() + L"data/flutter_assets/" +
|
||||
assetPath;
|
||||
targetFilePath = exeDir.wstring() + L"data/flutter_assets/" + assetPath;
|
||||
}
|
||||
std::streampos length;
|
||||
|
||||
|
||||
std::ifstream is(targetFilePath.c_str(), std::ios::binary);
|
||||
if (!is) {
|
||||
std::cout << "Failed to find resource at file path " << targetFilePath << std::endl;
|
||||
std::cout << "Failed to find resource at file path " << targetFilePath
|
||||
<< std::endl;
|
||||
return ResourceBuffer(nullptr, 0, -1);
|
||||
}
|
||||
is.seekg(0, std::ios::end);
|
||||
@@ -111,7 +124,8 @@ ResourceBuffer PolyvoxFilamentPlugin::loadResource(const char *name) {
|
||||
auto rb = ResourceBuffer(buffer, length, id);
|
||||
_resources.emplace(id, rb);
|
||||
|
||||
std::wcout << "Loaded resource of length " << length << " from path " << targetFilePath << std::endl;
|
||||
std::wcout << "Loaded resource of length " << length << " from path "
|
||||
<< targetFilePath << std::endl;
|
||||
|
||||
return rb;
|
||||
}
|
||||
@@ -130,301 +144,28 @@ static void _freeResource(ResourceBuffer rbf, void *const plugin) {
|
||||
|
||||
// this is the C-style function that will be returned via getRenderCallback
|
||||
// called on every frame by the FFI API
|
||||
// this is just a convenient wrapper to call RenderCallback on the actual plugin instance
|
||||
void render_callback(void* owner) {
|
||||
((PolyvoxFilamentPlugin*)owner)->RenderCallback();
|
||||
// this is just a convenient wrapper to call RenderCallback on the actual plugin
|
||||
// instance
|
||||
void render_callback(void *owner) {
|
||||
((PolyvoxFilamentPlugin *)owner)->RenderCallback();
|
||||
}
|
||||
|
||||
// this is the method on PolyvoxFilamentPlugin that will copy between D3D textures
|
||||
// this is the method on PolyvoxFilamentPlugin that will copy between D3D
|
||||
// textures
|
||||
void PolyvoxFilamentPlugin::RenderCallback() {
|
||||
|
||||
// std::lock_guard<std::mutex> guard(*(_renderMutex.get()));
|
||||
if (_active) {
|
||||
#ifdef USE_ANGLE
|
||||
_active->RenderCallback();
|
||||
#endif
|
||||
_textureRegistrar->MarkTextureFrameAvailable(_active->flutterTextureId);
|
||||
}
|
||||
}
|
||||
|
||||
if (_context) {
|
||||
auto flutterTextureId = _context->GetFlutterTextureId();
|
||||
#ifdef USE_ANGLE
|
||||
bool PolyvoxFilamentPlugin::CreateSharedEGLContext() {
|
||||
|
||||
//platform = new filament::backend::PlatformANGLE(_internalD3DTextureHandle,
|
||||
// width, height);
|
||||
_platform = new filament::backend::PlatformEGL();
|
||||
|
||||
// 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);
|
||||
|
||||
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;
|
||||
|
||||
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_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, EGL_ALPHA_SIZE, 8,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
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, [=](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;
|
||||
}
|
||||
#else
|
||||
bool PolyvoxFilamentPlugin::CreateSharedWGLContext() {
|
||||
|
||||
HWND hwnd = _pluginRegistrar->GetView()
|
||||
->GetNativeWindow();
|
||||
|
||||
HDC whdc = GetDC(hwnd);
|
||||
if (whdc == NULL) {
|
||||
std::cout << "No device context for temporary window" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(tempContext);
|
||||
|
||||
if (!_context || !wglMakeCurrent(whdc, _context)) {
|
||||
std::cout << "Failed to create OpenGL context." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool PolyvoxFilamentPlugin::MakeOpenGLTexture(uint32_t width, uint32_t height,std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
|
||||
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<OpenGLTextureBuffer>(
|
||||
_pluginRegistrar,
|
||||
_textureRegistrar,
|
||||
std::move(result),
|
||||
width,
|
||||
height,
|
||||
_context,
|
||||
_renderMutex
|
||||
);
|
||||
|
||||
return _active->flutterTextureId != -1;
|
||||
|
||||
}
|
||||
_active->RenderCallback();
|
||||
#endif
|
||||
|
||||
_textureRegistrar->MarkTextureFrameAvailable(flutterTextureId);
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
@@ -433,86 +174,78 @@ void PolyvoxFilamentPlugin::CreateTexture(
|
||||
|
||||
// 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
|
||||
if (!_context) {
|
||||
#ifdef USE_ANGLE
|
||||
_context = std::make_unique<EGLContext>(_pluginRegistrar);
|
||||
#else
|
||||
_context = std::make_unique<WGLContext>(_pluginRegistrar, _textureRegistrar);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_ANGLE
|
||||
bool success = MakeD3DTexture(width, height, std::move(result));
|
||||
#else
|
||||
bool success = MakeOpenGLTexture(width, height, std::move(result));
|
||||
#endif
|
||||
//_context->CreateTexture(width, height, std::move(result));
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
if(!flutterTextureId) {
|
||||
const auto *flutterTextureId = std::get_if<int64_t>(methodCall.arguments());
|
||||
|
||||
if (!flutterTextureId) {
|
||||
result->Error("NOT_IMPLEMENTED", "Flutter texture ID must be provided");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!_active) {
|
||||
result->Success("Texture has already been detroyed, ignoring");
|
||||
return;
|
||||
|
||||
if (_context) {
|
||||
_context->DestroyTexture(std::move(result));
|
||||
}
|
||||
|
||||
if(_active->flutterTextureId != *flutterTextureId) {
|
||||
result->Error("TEXTURE_MISMATCH", "Specified texture ID is not active");
|
||||
return;
|
||||
else {
|
||||
result->Error("NO_CONTEXT", "No rendering context is active");
|
||||
}
|
||||
|
||||
auto sh = std::make_shared<std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>>>(std::move(result));
|
||||
|
||||
_textureRegistrar->UnregisterTexture(_active->flutterTextureId, [=,
|
||||
sharedResult=std::move(sh)
|
||||
]() {
|
||||
this->_inactive = std::move(this->_active);
|
||||
auto unique = std::move(*(sharedResult.get()));
|
||||
unique->Success(flutter::EncodableValue(true));
|
||||
std::cout << "Unregistered/destroyed texture." << std::endl;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
void PolyvoxFilamentPlugin::HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue> &methodCall,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
|
||||
if (methodCall.method_name() == "getSharedContext") {
|
||||
result->Success(flutter::EncodableValue((int64_t)_context));
|
||||
if (methodCall.method_name() == "useBackingWindow") {
|
||||
result->Success(flutter::EncodableValue(
|
||||
#ifdef WGL_USE_BACKING_WINDOW
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
));
|
||||
} else if (methodCall.method_name() == "getSharedContext") {
|
||||
result->Success(flutter::EncodableValue((int64_t)_context->sharedContext));
|
||||
} else if (methodCall.method_name() == "getResourceLoaderWrapper") {
|
||||
const ResourceLoaderWrapper *const resourceLoader =
|
||||
new ResourceLoaderWrapper(_loadResource, _freeResource, this);
|
||||
new ResourceLoaderWrapper(_loadResource, _freeResource, this);
|
||||
result->Success(flutter::EncodableValue((int64_t)resourceLoader));
|
||||
} else if (methodCall.method_name() == "createTexture") {
|
||||
CreateTexture(methodCall, std::move(result));
|
||||
} else if (methodCall.method_name() == "destroyTexture") {
|
||||
DestroyTexture(methodCall, std::move(result));
|
||||
} else if(methodCall.method_name() == "getRenderCallback") {
|
||||
flutter::EncodableList resultList;
|
||||
resultList.push_back(flutter::EncodableValue((int64_t)&render_callback));
|
||||
resultList.push_back(flutter::EncodableValue((int64_t)this));
|
||||
result->Success(resultList);
|
||||
} else if(methodCall.method_name() == "getDriverPlatform") {
|
||||
#ifdef USE_ANGLE
|
||||
result->Success(flutter::EncodableValue((int64_t)_platform));
|
||||
} else if (methodCall.method_name() == "getRenderCallback") {
|
||||
#if !ANGLE && WGL_USE_BACKING_WINDOW
|
||||
result->Success(nullptr);
|
||||
#else
|
||||
result->Success(flutter::EncodableValue((int64_t)nullptr));
|
||||
flutter::EncodableList resultList;
|
||||
resultList.push_back(flutter::EncodableValue((int64_t)&render_callback));
|
||||
resultList.push_back(flutter::EncodableValue((int64_t)this));
|
||||
result->Success(resultList);
|
||||
#endif
|
||||
} else if (methodCall.method_name() == "getDriverPlatform") {
|
||||
#ifdef USE_ANGLE
|
||||
result->Success(flutter::EncodableValue((int64_t)_platform));
|
||||
#else
|
||||
result->Success(flutter::EncodableValue((int64_t) nullptr));
|
||||
#endif
|
||||
} else {
|
||||
result->Error("NOT_IMPLEMENTED", "Method is not implemented %s", methodCall.method_name());
|
||||
result->Error("NOT_IMPLEMENTED", "Method is not implemented %s",
|
||||
methodCall.method_name());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace polyvox_filament
|
||||
|
||||
|
||||
Reference in New Issue
Block a user