first (rough) working implementation of Filament-GLES-D3D-ANGLE

This commit is contained in:
Nick Fisher
2023-09-29 01:11:07 +10:00
parent afd761e396
commit cfa8e8edb4
26 changed files with 5207 additions and 621 deletions
+101 -101
View File
@@ -17,52 +17,40 @@
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d11.lib")
#include "PlatformANGLE.h"
#include <Windows.h>
#include <wrl.h>
#include <d3d.h>
#include <d3d11.h>
#include <thread>
#include <string_view>
#include <unordered_set>
#include <iostream>
#include <string.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <utils/compiler.h>
#include <utils/Log.h>
#include <utils/Panic.h>
#include <backend/DriverEnums.h>
#include <GL/gl.h>
#include <GL/glext.h>
// #include <GLES2/gl2.h>
#include "bluegl/BlueGL.h"
#include "PlatformANGLE.h"
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> {
public:
bool has(std::string_view str) const noexcept;
};
unordered_string_set split(const char* extensions) noexcept;
}
namespace filament {
// namespace GLUtils {
// class unordered_string_set : public std::unordered_set<std::string_view> {
// public:
// bool has(std::string_view str) const noexcept;
// };
// unordered_string_set split(const char* extensions) noexcept;
// }
using namespace backend;
namespace glext {
@@ -129,54 +117,47 @@ backend::Driver* PlatformANGLE::createDriver(void* sharedContext,
return nullptr;
}
// EGLBoolean bindAPI = eglBindAPI(EGL_OPENGL_API);
// if (UTILS_UNLIKELY(!bindAPI)) {
// slog.e << "eglBindAPI EGL_OPENGL_API failed" << io::endl;
// return nullptr;
// }
// int bindBlueGL = bluegl::bind();
// if (UTILS_UNLIKELY(bindBlueGL != 0)) {
// slog.e << "bluegl bind failed" << io::endl;
// return nullptr;
// }
EGLBoolean bindAPI = eglBindAPI(EGL_OPENGL_ES_API);
if (UTILS_UNLIKELY(!bindAPI)) {
slog.e << "eglBindAPI EGL_OPENGL_ES_API failed" << io::endl;
return nullptr;
}
// Copied from the base class and modified slightly. Should be cleaned up/improved later.
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert_invariant(mEGLDisplay != EGL_NO_DISPLAY);
EGLint major, minor;
EGLBoolean initialized = eglInitialize(mEGLDisplay, &major, &minor);
EGLBoolean initialized = false; // = eglInitialize(mEGLDisplay, &major, &minor);
if (!initialized) {
// if (!initialized) {
EGLDeviceEXT eglDevice;
EGLint numDevices;
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
(PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT");
if (eglQueryDevicesEXT != NULL) {
eglQueryDevicesEXT(1, &eglDevice, &numDevices);
if(auto* getPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
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,
};
mEGLDisplay = getPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, eglDevice, kD3D11DisplayAttributes);
initialized = eglInitialize(mEGLDisplay, &major, &minor);
}
}
EGLint kD3D11DisplayAttributes[] = {
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
EGL_TRUE,
EGL_NONE,
};
mEGLDisplay = getPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, kD3D11DisplayAttributes);
initialized = eglInitialize(mEGLDisplay, &major, &minor);
}
std::cout << "Got major " << major << " and minor " << minor << std::endl;
if (UTILS_UNLIKELY(!initialized)) {
slog.e << "eglInitialize failed" << io::endl;
return nullptr;
}
// auto extensions = GLUtils::split(eglQueryString(mEGLDisplay, EGL_EXTENSIONS));
importGLESExtensionsEntryPoints();
auto extensions = GLUtils::split(eglQueryString(mEGLDisplay, EGL_EXTENSIONS));
eglCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC) eglGetProcAddress("eglCreateSyncKHR");
eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC) eglGetProcAddress("eglDestroySyncKHR");
@@ -204,12 +185,6 @@ backend::Driver* PlatformANGLE::createDriver(void* sharedContext,
EGL_NONE,
};
// kEGLConfigurationAttributes[] = {
// EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
// EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8,
// EGL_NONE,
// };
EGLint contextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 3,
EGL_NONE, EGL_NONE, // reserved for EGL_CONTEXT_OPENGL_NO_ERROR_KHR below
@@ -225,6 +200,8 @@ backend::Driver* PlatformANGLE::createDriver(void* sharedContext,
EGLConfig eglConfig = nullptr;
EGLConfig mEGLTransparentConfig = nullptr;
char const* version;
// find an opaque config
if (!eglChooseConfig(mEGLDisplay, configAttribs, &mEGLConfig, 1, &configsCount)) {
logEglError("eglChooseConfig");
@@ -251,11 +228,19 @@ backend::Driver* PlatformANGLE::createDriver(void* sharedContext,
goto error;
}
// if (!extensions.has("EGL_KHR_no_config_context")) {
// // if we have the EGL_KHR_no_config_context, we don't need to worry about the config
// // when creating the context, otherwise, we must always pick a transparent config.
// eglConfig = mEGLConfig = mEGLTransparentConfig;
// }
if (!extensions.has("EGL_KHR_no_config_context")) {
// if we have the EGL_KHR_no_config_context, we don't need to worry about the config
// when creating the context, otherwise, we must always pick a transparent config.
eglConfig = mEGLConfig = mEGLTransparentConfig;
}
mEGLContext = eglCreateContext(mEGLDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs);
if (UTILS_UNLIKELY(mEGLContext == EGL_NO_CONTEXT)) {
// eglCreateContext failed
logEglError("eglCreateContext");
goto error;
}
mCurrentDrawSurface = mCurrentReadSurface = eglCreatePbufferFromClientBuffer(
mEGLDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, mD3DTextureHandle,
@@ -266,31 +251,27 @@ backend::Driver* PlatformANGLE::createDriver(void* sharedContext,
goto error;
}
mEGLContext = eglCreateContext(mEGLDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs);
// if (mEGLContext == EGL_NO_CONTEXT && sharedContext &&
// extensions.has("EGL_KHR_create_context_no_error")) {
// // context creation could fail because of EGL_CONTEXT_OPENGL_NO_ERROR_KHR
// // not matching the sharedContext. Try with it.
// contextAttribs[2] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR;
// contextAttribs[3] = EGL_TRUE;
// mEGLContext = eglCreateContext(mEGLDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs);
// }
if (UTILS_UNLIKELY(mEGLContext == EGL_NO_CONTEXT)) {
// eglCreateContext failed
logEglError("eglCreateContext");
goto error;
}
if (!makeCurrent(mCurrentDrawSurface, mCurrentDrawSurface)) {
if (!eglMakeCurrent(mEGLDisplay, mCurrentDrawSurface, mCurrentDrawSurface, mEGLContext)) {
// eglMakeCurrent failed
logEglError("eglMakeCurrent");
goto error;
}
glGenTextures(1, &glTextureId);
glBindTexture(GL_TEXTURE_2D, glTextureId);
eglBindTexImage(mEGLDisplay, mCurrentReadSurface, EGL_BACK_BUFFER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
initializeGlExtensions();
clearGlError();
version = (char const*)glGetString(GL_VERSION);
std::cout << "Got version " << version << std::endl;
glGetIntegerv(GL_MAJOR_VERSION, &major);
glGetIntegerv(GL_MINOR_VERSION, &minor);
// success!!
return OpenGLPlatform::createDefaultDriver(this, sharedContext, driverConfig);
@@ -314,11 +295,11 @@ error:
EGLBoolean PlatformANGLE::makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept {
if (UTILS_UNLIKELY((drawSurface != mCurrentDrawSurface || readSurface != mCurrentReadSurface))) {
// if (UTILS_UNLIKELY((drawSurface != mCurrentDrawSurface || readSurface != mCurrentReadSurface))) {
mCurrentDrawSurface = drawSurface;
mCurrentReadSurface = readSurface;
return eglMakeCurrent(mEGLDisplay, drawSurface, readSurface, mEGLContext);
}
// }
return EGL_TRUE;
}
@@ -385,12 +366,31 @@ void PlatformANGLE::makeCurrent(Platform::SwapChain* drawSwapChain,
makeCurrent(drawSur, readSur);
}
}
using namespace std::chrono_literals;
void PlatformANGLE::commit(Platform::SwapChain* swapChain) noexcept {
EGLSurface sur = (EGLSurface) swapChain;
if (sur != EGL_NO_SURFACE) {
eglSwapBuffers(mEGLDisplay, sur);
}
// glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
// glClear(GL_COLOR_BUFFER_BIT);
glFinish();
uint8_t* data = new uint8_t[1024*768*4];
memset(data, 0, 1024 * 768 * 4);
glReadPixels( 0, 0, 100, 100, GL_RGBA,GL_UNSIGNED_BYTE, data);
std::this_thread::sleep_for(200ms);
char c[10];
for(int i =0; i < 10*10; i++) {
std::cout << itoa(data[i], c, 10) << " ";
}
std::cout << std::endl;
}
bool PlatformANGLE::canCreateFence() noexcept {
@@ -435,18 +435,18 @@ FenceStatus PlatformANGLE::waitFence(
OpenGLPlatform::ExternalTexture* PlatformANGLE::createExternalImageTexture() noexcept {
ExternalTexture* outTexture = new ExternalTexture{};
glGenTextures(1, &outTexture->id);
if (UTILS_LIKELY(ext.gl.OES_EGL_image_external_essl3)) {
outTexture->target = GL_TEXTURE_EXTERNAL_OES;
} else {
// if texture external is not supported, revert to texture 2d
outTexture->target = GL_TEXTURE_2D;
}
// glGenTextures(1, &outTexture->id);
// if (UTILS_LIKELY(ext.gl.OES_EGL_image_external_essl3)) {
// outTexture->target = GL_TEXTURE_EXTERNAL_OES;
// } else {
// // if texture external is not supported, revert to texture 2d
// outTexture->target = GL_TEXTURE_2D;
// }
return outTexture;
}
void PlatformANGLE::destroyExternalImage(ExternalTexture* texture) noexcept {
glDeleteTextures(1, &texture->id);
// glDeleteTextures(1, &texture->id);
delete texture;
}
@@ -464,14 +464,14 @@ bool PlatformANGLE::setExternalImage(void* externalImage,
}
void PlatformANGLE::initializeGlExtensions() noexcept {
// GLUtils::unordered_string_set glExtensions;
// GLint n;
// glGetIntegerv(GL_NUM_EXTENSIONS, &n);
/*for (GLint i = 0; i < n; ++i) {
GLUtils::unordered_string_set glExtensions;
GLint n;
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
for (GLint i = 0; i < n; ++i) {
const char* const extension = (const char*)glGetStringi(GL_EXTENSIONS, (GLuint)i);
glExtensions.insert(extension);
}*/
// ext.gl.OES_EGL_image_external_essl3 = glExtensions.has("GL_OES_EGL_image_external_essl3");
}
ext.gl.OES_EGL_image_external_essl3 = glExtensions.has("GL_OES_EGL_image_external_essl3");
}
Platform::SwapChain* PlatformANGLE::createSwapChain(void* nativewindow, uint64_t flags) noexcept {
+21 -5
View File
@@ -4,9 +4,22 @@
#include <d3d.h>
#include <d3d11.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES3/gl31.h>
#include "backend/DriverEnums.h"
#include "backend/platforms/OpenGLPlatform.h"
#include "backend/Platform.h"
#define FILAMENT_USE_EXTERNAL_GLES3
#include "gl_headers.h"
namespace filament::backend {
/**
@@ -23,6 +36,12 @@ public:
Platform::SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
GLuint glTextureId = 0;
EGLSurface mCurrentDrawSurface = EGL_NO_SURFACE;
EGLSurface mCurrentReadSurface = EGL_NO_SURFACE;
EGLDisplay mEGLDisplay = EGL_NO_DISPLAY;
EGLContext mEGLContext = EGL_NO_CONTEXT;
EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR;
private:
/**
* This returns zero. This method can be overridden to return something more useful.
@@ -67,12 +86,9 @@ private:
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept;
// TODO: this should probably use getters instead.
EGLDisplay mEGLDisplay = EGL_NO_DISPLAY;
EGLContext mEGLContext = EGL_NO_CONTEXT;
EGLSurface mCurrentDrawSurface = EGL_NO_SURFACE;
EGLSurface mCurrentReadSurface = EGL_NO_SURFACE;
EGLSurface mEGLDummySurface = EGL_NO_SURFACE;
EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR;
HANDLE mD3DTextureHandle = nullptr;
uint32_t mWidth = 0;
uint32_t mHeight = 0;
+2
View File
@@ -0,0 +1,2 @@
DisableFormat: true
SortIncludes: false
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+27
View File
@@ -0,0 +1,27 @@
#ifndef __gl3platform_h_
#define __gl3platform_h_
/*
** Copyright 2017-2020 The Khronos Group Inc.
** SPDX-License-Identifier: Apache-2.0
*/
/* Platform-specific types and definitions for OpenGL ES 3.X gl3.h
*
* Adopters may modify khrplatform.h and this file to suit their platform.
* Please contribute modifications back to Khronos as pull requests on the
* public github repository:
* https://github.com/KhronosGroup/OpenGL-Registry
*/
#include <KHR/khrplatform.h>
#ifndef GL_APICALL
#define GL_APICALL KHRONOS_APICALL
#endif
#ifndef GL_APIENTRY
#define GL_APIENTRY KHRONOS_APIENTRY
#endif
#endif /* __gl3platform_h_ */
+86
View File
@@ -0,0 +1,86 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_NULLGLES_H
#define TNT_FILAMENT_BACKEND_OPENGL_NULLGLES_H
/*
* This is used for debugging (stubbing out GLES calls)
*
* Simply uncomment the line
* using namespace nullgles;
*
* below.
*
*/
namespace filament::backend {
namespace nullgles {
inline void glScissor(GLint, GLint, GLsizei, GLsizei) { }
inline void glViewport(GLint, GLint, GLsizei, GLsizei) { }
inline void glDepthRangef(GLfloat, GLfloat) { }
inline void glClearColor(GLfloat, GLfloat, GLfloat, GLfloat) { }
inline void glClearStencil(GLint) { }
inline void glClearDepthf(GLfloat) { }
inline void glBindBufferBase(GLenum, GLuint, GLuint) { }
inline void glBindVertexArray (GLuint) { }
inline void glBindTexture (GLenum, GLuint) { }
inline void glBindBuffer (GLenum, GLuint) { }
inline void glBindFramebuffer (GLenum, GLuint) { }
inline void glBindRenderbuffer (GLenum, GLuint) { }
inline void glUseProgram (GLuint) { }
inline void glBufferData(GLenum, GLsizeiptr, const void *, GLenum) { }
inline void glBufferSubData(GLenum, GLintptr, GLsizeiptr, const void *) { }
inline void glCompressedTexSubImage2D(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const void *) { }
inline void glTexSubImage2D(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const void *) { }
inline void glGenerateMipmap(GLenum) { }
inline void glVertexAttribPointer(GLuint, GLint, GLenum, GLboolean, GLsizei, const void *) { }
inline void glDisableVertexAttribArray (GLuint) { }
inline void glEnableVertexAttribArray (GLuint) { }
inline void glDisable (GLenum cap) { }
inline void glEnable (GLenum cap) { }
inline void glCullFace (GLenum mode) { }
inline void glBlendFunc (GLenum, GLenum) { }
inline void glInvalidateFramebuffer (GLenum, GLsizei, const GLenum *) { }
inline void glInvalidateSubFramebuffer (GLenum, GLsizei, const GLenum *, GLint, GLint, GLsizei, GLsizei);
inline void glSamplerParameteri (GLuint, GLenum, GLint) { }
inline void glSamplerParameterf (GLuint, GLenum, GLfloat) { }
inline void glFramebufferRenderbuffer (GLenum, GLenum, GLenum, GLuint) { }
inline void glRenderbufferStorageMultisample (GLenum, GLsizei, GLenum, GLsizei, GLsizei) { }
inline void glRenderbufferStorage (GLenum, GLenum, GLsizei, GLsizei) { }
inline void glClear(GLbitfield) { }
inline void glDrawRangeElements(GLenum, GLuint, GLuint, GLsizei, GLenum, const void *) { }
inline void glBlitFramebuffer (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum) { }
inline void glReadPixels (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, void *) { }
inline GLenum glGetError() { return GL_NO_ERROR; }
} // namespace nullgles
// turn GLES calls defined above into no-ops
//using namespace nullgles;
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_NULLGLES_H
+210
View File
@@ -0,0 +1,210 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_GL_HEADERS_H
#define TNT_FILAMENT_BACKEND_OPENGL_GL_HEADERS_H
/*
* Configuration we aim to support:
*
* GL 4.5 headers
* - GL 4.1 runtime (for macOS)
* - GL 4.5 runtime
*
* GLES 2.0 headers
* - GLES 2.0 runtime Android only
*
* GLES 3.0 headers
* - GLES 3.0 runtime iOS and WebGL2 only
*
* GLES 3.1 headers
* - GLES 2.0 runtime
* - GLES 3.0 runtime
* - GLES 3.1 runtime
*/
#if defined(__ANDROID__) || defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(__EMSCRIPTEN__)
#if defined(__EMSCRIPTEN__)
# include <GLES3/gl3.h>
#else
# include <GLES3/gl31.h>
#endif
#include <GLES2/gl2ext.h>
#elif defined(IOS)
#define GLES_SILENCE_DEPRECATION
#include <OpenGLES/ES3/gl.h>
#include <OpenGLES/ES3/glext.h>
#else
// bluegl exposes symbols prefixed with bluegl_ to avoid clashing with clients that also link
// against GL.
// This header re-defines GL function names with the bluegl_ prefix.
// For example:
// #define glFunction bluegl_glFunction
// This header must come before <bluegl/BlueGL.h>.
#include <bluegl/BlueGLDefines.h>
#include <bluegl/BlueGL.h>
#endif
/* Validate the header configurations we aim to support */
#if defined(GL_VERSION_4_5)
#elif defined(GL_ES_VERSION_3_1)
#elif defined(GL_ES_VERSION_3_0)
# if !defined(IOS) && !defined(__EMSCRIPTEN__)
# error "GLES 3.0 headers only supported on iOS and WebGL2"
# endif
#elif defined(GL_ES_VERSION_2_0)
# if !defined(__ANDROID__)
# error "GLES 2.0 headers only supported on Android"
# endif
#else
# error "Minimum header version must be OpenGL ES 2.0 or OpenGL 4.5"
#endif
/*
* GLES extensions
*/
#if defined(GL_ES_VERSION_2_0) // this basically means all versions of GLES
#if defined(IOS)
// iOS headers only provide prototypes, nothing to do.
#else
#define FILAMENT_IMPORT_ENTRY_POINTS
/* The Android NDK doesn't expose extensions, fake it with eglGetProcAddress */
namespace glext {
// importGLESExtensionsEntryPoints is thread-safe and can be called multiple times.
// it is currently called from PlatformEGL.
void importGLESExtensionsEntryPoints();
#ifdef GL_OES_EGL_image
extern PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
#endif
#ifdef GL_EXT_debug_marker
extern PFNGLINSERTEVENTMARKEREXTPROC glInsertEventMarkerEXT;
extern PFNGLPUSHGROUPMARKEREXTPROC glPushGroupMarkerEXT;
extern PFNGLPOPGROUPMARKEREXTPROC glPopGroupMarkerEXT;
#endif
#ifdef GL_EXT_multisampled_render_to_texture
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
extern PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT;
#endif
#ifdef GL_KHR_debug
extern PFNGLDEBUGMESSAGECALLBACKKHRPROC glDebugMessageCallbackKHR;
extern PFNGLGETDEBUGMESSAGELOGKHRPROC glGetDebugMessageLogKHR;
#endif
#ifdef GL_EXT_clip_control
extern PFNGLCLIPCONTROLEXTPROC glClipControlEXT;
#endif
#ifdef GL_EXT_disjoint_timer_query
extern PFNGLGETQUERYOBJECTUI64VEXTPROC glGetQueryObjectui64v;
#endif
#if defined(__ANDROID__)
extern PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
#endif
} // namespace glext
using namespace glext;
#endif
// Prevent lots of #ifdef's between desktop and mobile
#ifdef GL_EXT_disjoint_timer_query
# define GL_TIME_ELAPSED GL_TIME_ELAPSED_EXT
#endif
#ifdef GL_EXT_clip_control
# define GL_LOWER_LEFT GL_LOWER_LEFT_EXT
# define GL_ZERO_TO_ONE GL_ZERO_TO_ONE_EXT
#endif
// we need GL_TEXTURE_CUBE_MAP_ARRAY defined, but we won't use it if the extension/feature
// is not available.
#if defined(GL_EXT_texture_cube_map_array)
# define GL_TEXTURE_CUBE_MAP_ARRAY GL_TEXTURE_CUBE_MAP_ARRAY_EXT
#else
# define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
#endif
#if defined(GL_KHR_debug)
# define GL_DEBUG_OUTPUT GL_DEBUG_OUTPUT_KHR
# define GL_DEBUG_OUTPUT_SYNCHRONOUS GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR
# define GL_DEBUG_SEVERITY_HIGH GL_DEBUG_SEVERITY_HIGH_KHR
# define GL_DEBUG_SEVERITY_MEDIUM GL_DEBUG_SEVERITY_MEDIUM_KHR
# define GL_DEBUG_SEVERITY_LOW GL_DEBUG_SEVERITY_LOW_KHR
# define GL_DEBUG_SEVERITY_NOTIFICATION GL_DEBUG_SEVERITY_NOTIFICATION_KHR
# define GL_DEBUG_TYPE_MARKER GL_DEBUG_TYPE_MARKER_KHR
# define GL_DEBUG_TYPE_ERROR GL_DEBUG_TYPE_ERROR_KHR
# define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR
# define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR
# define GL_DEBUG_TYPE_PORTABILITY GL_DEBUG_TYPE_PORTABILITY_KHR
# define GL_DEBUG_TYPE_PERFORMANCE GL_DEBUG_TYPE_PERFORMANCE_KHR
# define GL_DEBUG_TYPE_OTHER GL_DEBUG_TYPE_OTHER_KHR
# define glDebugMessageCallback glDebugMessageCallbackKHR
#endif
#endif // GL_ES_VERSION_2_0
// This is just to simplify the implementation (i.e. so we don't have to have #ifdefs everywhere)
#ifndef GL_OES_EGL_image_external
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
#endif
// This is an odd duck function that exists in WebGL 2.0 but not in OpenGL ES.
#if defined(__EMSCRIPTEN__)
extern "C" {
void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data);
}
#endif
#if defined(GL_ES_VERSION_2_0)
# define BACKEND_OPENGL_VERSION_GLES
#elif defined(GL_VERSION_4_5)
# define BACKEND_OPENGL_VERSION_GL
#else
# error "Unsupported header version"
#endif
#if defined(GL_VERSION_4_5) || defined(GL_ES_VERSION_3_1)
# define BACKEND_OPENGL_LEVEL_GLES31
# ifdef __EMSCRIPTEN__
# error "__EMSCRIPTEN__ shouldn't be defined with GLES 3.1 headers"
# endif
#endif
#if defined(GL_VERSION_4_5) || defined(GL_ES_VERSION_3_0)
# define BACKEND_OPENGL_LEVEL_GLES30
#endif
#if defined(GL_VERSION_4_5) || defined(GL_ES_VERSION_2_0)
# define BACKEND_OPENGL_LEVEL_GLES20
#endif
#include "NullGLES.h"
#endif // TNT_FILAMENT_BACKEND_OPENGL_GL_HEADERS_H
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1b975d0080a73a784f956799a52068ee6ebabec5e999928ad4cad2316d0b8894
size 21607660
oid sha256:bf1bd7a89d00fa74f04c446aaeb9742793e02b42d53c0cf1375951f5948cd2ef
size 20108820
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:72ab5ba58660296b135e9aa047107d2d23a985e1f6484ec75764bfb0032ddb15
size 1948398
oid sha256:5afb9555f719e7b7c60313b158b43c0464f122d09ed81e072b2a13db5d67e049
size 2066946
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ac268c42d78985af066d1caeac1d4f17acd7df5ea89f67e8e25f1aa391a2b8d1
size 454656
oid sha256:6ae56046e5c4560cf781ee5f1a4557c63ec2d19a2a71ff60adbecc717b38d8fa
size 222720
+3
View File
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d17be2b996420c38caf1e038b4e9be8d3f3e7d44579bccaff6226c2d73d6a2f4
size 1695744
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dad57352cbce97cacc1e71b08410276e3814f9604bf2cea3047dd3d6afcb1593
size 6934528
oid sha256:7727c415097ee9971a496b0351166c4f136218726a9dc87848988a7f694b1934
size 25372160
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8ca68c5953bc7524e531ae64df7174ceccb5c0533f02acd1e9445f4121e173a4
size 86671360
oid sha256:44c823206c6b2a34d462c73ce4831544e00fce732763785ee7182f30f4d5e66b
size 141041664
+3
View File
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7fb7a22ad254dac200c5bb4ac5c73b812cd8724efdeaeff2f72b1c51a4709061
size 1629184
+3
View File
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:94005da524b2ed1d70c816fc20a91f2248acaf784cde8f0693c712facd874b89
size 1018948
+3
View File
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bccc2476e4a5b82b17a6b2fcf10e30b9b8ae7fb82d3a1b23d666d61d7133c23c
size 6397952
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d8a4bdd6fe9599e045af5c8fc0b8734fab569e6e524395d6ff32118de2d3ebc0
size 2709504
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b17474d55653bd6500cd0798abe8eaa44b963b7768f3c0a3692924761ad80246
size 4097356
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bd1100558fa512ad6f42882db6ca87c590f57dc5d9d81428ed53e4b96c314d5c
size 10821632
+3
View File
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:28756defd96757d4fb2b91f96918331dcaab9b6fdf14db8ba8b17388bec4b15a
size 204800
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b0ed37440ff1840b33e43559d011cf46a42f37c590f32ed8b0a59d11305db552
size 19650
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:72eafb51fc85a3e88319833aec983d94f2f82a88c656a303704c4af2d6f74abe
size 835584
+213 -503
View File
@@ -45,6 +45,35 @@ namespace polyvox_filament {
static ThreadPool* _tp;
GLuint CompileShader(GLenum type, const std::string& source) {
auto shader = glCreateShader(type);
const char* s[1] = {source.c_str()};
glShaderSource(shader, 1, s, NULL);
glCompileShader(shader);
return shader;
}
GLuint CompileProgram(const std::string& vertex_shader_source,
const std::string& fragment_shader_source) {
auto program = glCreateProgram();
auto vs = CompileShader(GL_VERTEX_SHADER, vertex_shader_source);
auto fs = CompileShader(GL_FRAGMENT_SHADER, fragment_shader_source);
if (vs == 0 || fs == 0) {
glDeleteShader(fs);
glDeleteShader(vs);
glDeleteProgram(program);
return 0;
}
glAttachShader(program, vs);
glDeleteShader(vs);
glAttachShader(program, fs);
glDeleteShader(fs);
glLinkProgram(program);
return program;
}
// static
void PolyvoxFilamentPlugin::RegisterWithRegistrar(
flutter::PluginRegistrarWindows *registrar) {
@@ -140,60 +169,27 @@ void PolyvoxFilamentPlugin::CreateFilamentViewer(
const ResourceLoaderWrapper *const resourceLoader =
new ResourceLoaderWrapper(_loadResource, _freeResource, this);
wglMakeCurrent(NULL, NULL);
std::packaged_task<void()> lambda([&]() mutable {
_viewer = (void *)create_filament_viewer(_context, resourceLoader, _platform);
create_swap_chain(_viewer, nullptr, width, height);
create_render_target(_viewer, _glTextureId, width, height);
_viewer = (void *)create_filament_viewer(nullptr, resourceLoader, _platform);
// headless
create_swap_chain(_viewer, nullptr, width, height);
create_render_target(_viewer, _platform->glTextureId, width, height);
result->Success(flutter::EncodableValue((int64_t)_viewer));
});
std::thread([&]() {
while (true)
{
if(_rendering) {
std::packaged_task<void()> renderLambda([&]() mutable {
std::lock_guard<std::mutex> guard(_renderMutex);
render(_viewer, 0, nullptr, nullptr, nullptr);
_textureRegistrar->MarkTextureFrameAvailable(_flutterTextureId);
});
_tp->add_task(renderLambda);
}
std::this_thread::sleep_for(
std::chrono::milliseconds(_frameIntervalInMilliseconds));
}
}).detach();
auto fut = _tp->add_task(lambda);
fut.wait();
}
using namespace std::chrono_literals;
void PolyvoxFilamentPlugin::Render(
const flutter::MethodCall<flutter::EncodableValue> &methodCall,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
// auto callback = [](void *buf, size_t size, void *data) {
// auto plugin = (PolyvoxFilamentPlugin *)data;
// plugin->_textureRegistrar->MarkTextureFrameAvailable(
// plugin->_flutterTextureId);
// };
// _D3D11DeviceContext->CopyResource(_externalD3DTexture2D.Get(),
// _internalD3DTexture2D.Get());
// _D3D11DeviceContext->Flush();
// render(_viewer, 0, _pixelData.get(), callback, this);
std::packaged_task<void()> lambda([=]() mutable {
render(_viewer, 0, nullptr, nullptr, nullptr);
_D3D11DeviceContext->CopyResource(_externalD3DTexture2D.Get(),
_internalD3DTexture2D.Get());
_D3D11DeviceContext->Flush();
_textureRegistrar->MarkTextureFrameAvailable(_flutterTextureId);
});
auto fut = _tp->add_task(lambda);
fut.wait();
result->Success(flutter::EncodableValue(true));
}
@@ -214,394 +210,177 @@ void PolyvoxFilamentPlugin::CreateTexture(
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)))));
// // 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_) {
// result->Error("ERROR", "Failed to locate default D3D adapter", nullptr);
// return;
// }
// 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;
// }
// 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;
// }
// 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;
// _platform = new filament::backend::PlatformANGLE(_internalD3DTextureHandle, width, height);
// // OpenGL starts here
// // GLenum err = GL_NO_ERROR;
// eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, nullptr);
// EGLSurface surface = EGL_NO_SURFACE;
// EGLDisplay display = EGL_NO_DISPLAY;
// EGLContext context = nullptr;
// EGLConfig config = nullptr;
// // create EGL surface
// if (display == EGL_NO_DISPLAY) {
// auto eglGetPlatformDisplayEXT =
// reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
// eglGetProcAddress("eglGetPlatformDisplayEXT"));
// if (eglGetPlatformDisplayEXT) {
// display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
// EGL_DEFAULT_DISPLAY,
// kD3D11DisplayAttributes);
// if (eglInitialize(display, 0, 0) == EGL_FALSE) {
// display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
// EGL_DEFAULT_DISPLAY,
// kD3D11_9_3DisplayAttributes);
// if (eglInitialize(display, 0, 0) == EGL_FALSE) {
// display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
// EGL_DEFAULT_DISPLAY,
// kD3D9DisplayAttributes);
// if (eglInitialize(display, 0, 0) == EGL_FALSE) {
// display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
// EGL_DEFAULT_DISPLAY,
// kWrapDisplayAttributes);
// if (eglInitialize(display, 0, 0) == EGL_FALSE) {
// result->Error("eglGetPlatformDisplayEXT");
// return;
// }
// }
// }
// }
// } else {
// result->Error("eglGetProcAddress");
// return;
// }
// }
// EGLint err = eglGetError();
// if(err != EGL_SUCCESS) {
// result->Error("ERROR", "EGL Error @ 354 %d", err);
// return;
// }
// // Do not create |context_| again, likely due to |Resize|.
// if (context == EGL_NO_CONTEXT) {
// // First time from the constructor itself.
// auto count = 0;
// auto eglResult = eglChooseConfig(display, kEGLConfigurationAttributes,
// &config, 1, &count);
// if (eglResult == EGL_FALSE || count == 0) {
// result->Error("eglChooseConfig");
// return;
// }
// context = eglCreateContext(display, config, EGL_NO_CONTEXT,
// kEGLContextAttributes);
// if (context == EGL_NO_CONTEXT) {
// result->Error("eglCreateContext");
// return;
// }
// }
// err = eglGetError();
// if(err != EGL_SUCCESS) {
// result->Error("ERROR", "EGL Error @ 37 9%d", err);
// return;
// }
// EGLint buffer_attributes[] = {
// EGL_WIDTH, width, EGL_HEIGHT, height,
// EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
// EGL_NONE,
// };
// surface = eglCreatePbufferFromClientBuffer(
// display, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, _internalD3DTextureHandle,
// config, buffer_attributes);
// if (surface == EGL_NO_SURFACE) {
// result->Error("eglCreatePbufferFromClientBuffer");
// return;
// }
// eglMakeCurrent(display, surface, surface, context);
// err = eglGetError();
// if(err != EGL_SUCCESS) {
// result->Error("ERROR", "EGL Error @ 37 9%d", err);
// return;
// }
HWND hwnd = _pluginRegistrar->GetView()
->GetNativeWindow(); // CreateWindowA("STATIC", "dummy", 0, 0,
// 0, 1, 1, NULL, NULL, NULL, NULL);
HDC whdc = GetDC(hwnd);
if (whdc == NULL) {
result->Error("ERROR", "No device context for temporary window", nullptr);
return;
}
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
// 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,
};
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);
// 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);
return;
}
GLenum err = glGetError();
if(err != GL_NO_ERROR) {
result->Error("ERROR", "GL Error @ 455 %d", err);
return;
}
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = nullptr;
wglCreateContextAttribs =
(PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress(
"wglCreateContextAttribsARB");
if (!wglCreateContextAttribs) {
result->Error("ERROR", "Failed to resolve wglCreateContextAttribsARB",
nullptr);
return;
}
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;
}
glGenTextures(1, &_glTextureId);
if(_glTextureId == 0) {
result->Error("ERROR", "Failed to generate texture, OpenGL err was %d", glGetError());
return;
}
// err = eglGetError();
// if (err != EGL_SUCCESS) {
// result->Error("ERROR", "Failed to generate texture, EGL error was %d", err);
// return;
// }
glBindTexture(GL_TEXTURE_2D, _glTextureId);
// eglBindTexImage(display, surface, EGL_BACK_BUFFER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
// err = eglGetError();
// if (err != EGL_SUCCESS) {
// result->Error("ERROR", "Failed to generate texture, EGL error was %d", err);
// return;
// }
err = glGetError();
if (err != GL_NO_ERROR) {
result->Error("ERROR", "Failed to generate texture, GL error was %d", err);
return;
}
}
_pixelData.reset(new uint8_t[width * height * 4]);
_pixelBuffer = std::make_unique<FlutterDesktopPixelBuffer>();
_pixelBuffer->buffer = _pixelData.get();
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);
_pixelBuffer->width = size_t(width);
_pixelBuffer->height = size_t(height);
if (FAILED(hr)) {
result->Error("ERROR", "Failed to create D3D device", nullptr);
return;
}
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;
}
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;
_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::PixelBufferTexture(
[=](size_t width,
size_t height) -> const FlutterDesktopPixelBuffer * {
std::lock_guard<std::mutex> guard(_renderMutex);
if(!_context || !wglMakeCurrent(whdc, _context)) {
std::cout << "Failed to switch OpenGL context." << std::endl;
} else {
uint8_t* data = new uint8_t[width*height*4];
glBindTexture(GL_TEXTURE_2D, _glTextureId);
glGetTexImage(GL_TEXTURE_2D,0,GL_RGBA,GL_UNSIGNED_BYTE,data);
GLenum err = glGetError();
if(err != GL_NO_ERROR) {
if(err == GL_INVALID_OPERATION) {
std::cout << "Invalid op" << std::endl;
} else if(err == GL_INVALID_VALUE) {
std::cout << "Invalid value" << std::endl;
} else if(err == GL_OUT_OF_MEMORY) {
std::cout << "Out of mem" << std::endl;
} else if(err == GL_INVALID_ENUM ) {
std::cout << "Invalid enum" << std::endl;
} else {
std::cout << "Unknown error" << std::endl;
}
}
glFinish();
_pixelData.reset(data);
wglMakeCurrent(NULL, NULL);
}
_pixelBuffer->buffer = _pixelData.get();
return _pixelBuffer.get();
}));
// _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(); }));
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;
result->Success(flutter::EncodableValue(_flutterTextureId));
filament::backend::Platform::DriverConfig config;
// std::packaged_task<void()> lambda([&]() mutable {
// _platform->createDriver(nullptr, config);
// std::cout << glGetString(GL_VERSION) << std::endl;
// constexpr char kVertexShader[] = R"(attribute vec4 vPosition;
// void main()
// {
// gl_Position = vPosition;
// })";
// constexpr char kFragmentShader[] = R"(precision mediump float;
// void main()
// {
// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
// })";
// auto program = CompileProgram(kVertexShader, kFragmentShader);
// glEnableVertexAttribArray(0);
// glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// GLfloat vertices[] = {
// 0.0f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f,
// };
// glClear(GL_COLOR_BUFFER_BIT);
// glViewport(0, 0, width, height);
// glUseProgram(program);
// glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
// glDrawArrays(GL_TRIANGLES, 0, 3);
// glDisableVertexAttribArray(0);
// glFinish();
_D3D11DeviceContext->CopyResource(_externalD3DTexture2D.Get(),
_internalD3DTexture2D.Get());
_D3D11DeviceContext->Flush();
_textureRegistrar->MarkTextureFrameAvailable(_flutterTextureId);
result->Success(flutter::EncodableValue(_flutterTextureId));
// }
}
void PolyvoxFilamentPlugin::SetBackgroundImage(
@@ -611,11 +390,11 @@ void PolyvoxFilamentPlugin::SetBackgroundImage(
std::get_if<flutter::EncodableList>(methodCall.arguments());
const auto path = std::get_if<std::string>(&(args->at(0)));
const auto fillHeight = std::get_if<bool>(&(args->at(1)));
std::packaged_task<void()> lambda([&]() mutable {
// std::packaged_task<void()> lambda([&]() mutable {
set_background_image(_viewer, path->c_str(), *fillHeight);
});
auto fut = _tp->add_task(lambda);
fut.wait();
// });
// auto fut = _tp->add_task(lambda);
// fut.wait();
result->Success(flutter::EncodableValue(true));
}
@@ -629,12 +408,12 @@ void PolyvoxFilamentPlugin::SetBackgroundColor(
const auto g = std::get_if<double>(&(args->at(1)));
const auto b = std::get_if<double>(&(args->at(2)));
const auto a = std::get_if<double>(&(args->at(3)));
std::packaged_task<void()> lambda([&]() mutable {
// std::packaged_task<void()> lambda([&]() mutable {
set_background_color(_viewer, static_cast<float>(*r), static_cast<float>(*g),
static_cast<float>(*b), static_cast<float>(*a));
});
auto fut = _tp->add_task(lambda);
fut.wait();
// });
// auto fut = _tp->add_task(lambda);
// fut.wait();
result->Success(flutter::EncodableValue(true));
}
@@ -666,11 +445,11 @@ void PolyvoxFilamentPlugin::LoadSkybox(
const flutter::MethodCall<flutter::EncodableValue> &methodCall,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
const auto *args = std::get_if<std::string>(methodCall.arguments());
std::packaged_task<void()> lambda([&]() mutable {
// std::packaged_task<void()> lambda([&]() mutable {
load_skybox(_viewer, (*args).c_str());
});
auto fut = _tp->add_task(lambda);
fut.wait();
// });
// auto fut = _tp->add_task(lambda);
// fut.wait();
result->Success(flutter::EncodableValue("OK"));
}
@@ -1205,72 +984,3 @@ void PolyvoxFilamentPlugin::HandleMethodCall(
} // namespace polyvox_filament
// glfwInit();
// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
// GLFWwindow* window = glfwCreateWindow(1024, 768, "", nullptr, nullptr);
// if (!window) {
// std::cout << "Failed to create GLFW window" << std::endl;
// glfwTerminate();
// return;
// }
// glfwMakeContextCurrent(window);
// glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
// glClear(GL_COLOR_BUFFER_BIT);
// auto data = new uint8_t[1024*768*4];
// glReadPixels(0,0, 1024, 768, GL_RGBA, GL_UNSIGNED_BYTE, data);
// _pixelData.reset(data);
// GLuint glTextureId = 0;
// auto textureData = new uint8_t[1024*768*4];
// for(int y = 0; y < 768; y++) {
// for(int x=0; x < 1024; x++) {
// textureData[y*768 + (x*4)] = 0;
// textureData[y*768 + (x*4+1)] = 255;
// textureData[y*768 + (x*4+2)] = 0;
// textureData[y*768 + (x*4+3)] = 255;
// }
// }
// glGenTextures(1, &glTextureId);
// glBindTexture(GL_TEXTURE_2D, glTextureId);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1024, 768, 0, GL_RGBA,
// GL_UNSIGNED_BYTE, textureData);
// _pixelBuffer = std::make_unique<FlutterDesktopPixelBuffer>();
// _pixelBuffer->buffer = _pixelData.get();
// _pixelBuffer->width = 1024;
// _pixelBuffer->height = 768;
// _texture =
// std::make_unique<flutter::TextureVariant>(flutter::PixelBufferTexture(
// [=](size_t width, size_t height) -> const FlutterDesktopPixelBuffer* {
// std::cout << "Copying pixel buffer for " << width << "x" << height <<
// std::endl;
// // uint8_t* data = _pixelData.get();
// uint8_t* data = new uint8_t[height*width*4];
// glReadPixels(0,0, (GLsizei)width, (GLsizei)height, GL_RGB,
// GL_UNSIGNED_BYTE, data); return _pixelBuffer.get();
// }));
// std::cout << "Registering texture" << std::endl;
// _flutterTextureId = _textureRegistrar->RegisterTexture(_texture.get());
// _textureRegistrar->MarkTextureFrameAvailable(_flutterTextureId);
// std::cout << "Registered " << _flutterTextureId << std::endl;
-2
View File
@@ -64,8 +64,6 @@ public:
// OpenGL
// Texture handle
GLuint _glTextureId = 0;
// Shared context
HGLRC _context = NULL;
// D3D
// Device