浏览代码

add vulkan

/siyaoH-1.17-vulkan
siyao 4 年前
当前提交
26f0c3e9
共有 3 个文件被更改,包括 269 次插入22 次删除
  1. 5
      engine/Build.bee.cs
  2. 278
      engine/src/shell/platform/unity/android/unity_surface_manager.cc
  3. 8
      engine/src/shell/platform/unity/android/unity_surface_manager.h

5
engine/Build.bee.cs


"GR_TEST_UTILS=1",
"SKIA_IMPLEMENTATION=1",
"SK_GL",
"VK_USE_PLATFORM_ANDROID_KHR",
"EGL_EGLEXT_PROTOTYPES",
"GL_GLEXT_PROTOTYPES",
"SK_ENABLE_DUMP_GPU",
"SK_SUPPORT_PDF",
"SK_CODEC_DECODES_JPEG",

"-Wl,--warn-shared-textrel",
"-nostdlib",
"--sysroot="+ flutterRoot+"/third_party/android_tools/ndk/platforms/android-16/arch-arm",
"--sysroot="+ flutterRoot+"/third_party/android_tools/ndk/platforms/android-28/arch-arm",
"-L"+ flutterRoot + "/third_party/android_tools/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a",
"-Wl,--build-id=sha1",
"-g",

new SystemLibrary("EGL"),
new SystemLibrary("GLESv2"),
new SystemLibrary("log"),
new SystemLibrary("vulkan"),
};
});
}

278
engine/src/shell/platform/unity/android/unity_surface_manager.cc


#include <flutter/fml/logging.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2ext.h>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_core.h>
#include <android/hardware_buffer.h>
#define UNITY_USED_VULKAN_API_FUNCTIONS(apply) \
apply(vkGetDeviceProcAddr); \
apply(vkCreateInstance); \
apply(vkCmdBeginRenderPass); \
apply(vkCreateBuffer); \
apply(vkGetPhysicalDeviceMemoryProperties); \
apply(vkGetBufferMemoryRequirements); \
apply(vkMapMemory); \
apply(vkBindBufferMemory); \
apply(vkAllocateMemory); \
apply(vkDestroyBuffer); \
apply(vkFreeMemory); \
apply(vkUnmapMemory); \
apply(vkQueueWaitIdle); \
apply(vkDeviceWaitIdle); \
apply(vkCmdCopyBufferToImage); \
apply(vkFlushMappedMemoryRanges); \
apply(vkCreatePipelineLayout); \
apply(vkCreateShaderModule); \
apply(vkDestroyShaderModule); \
apply(vkCreateGraphicsPipelines); \
apply(vkCmdBindPipeline); \
apply(vkCmdDraw); \
apply(vkCmdPushConstants); \
apply(vkCmdBindVertexBuffers); \
apply(vkDestroyPipeline); \
apply(vkDestroyPipelineLayout);
#define VULKAN_DEFINE_API_FUNCPTR(func) static PFN_##func my_##func
VULKAN_DEFINE_API_FUNCPTR(vkGetInstanceProcAddr);
UNITY_USED_VULKAN_API_FUNCTIONS(VULKAN_DEFINE_API_FUNCPTR);
#undef VULKAN_DEFINE_API_FUNCPTR
static void LoadVulkanAPI(PFN_vkGetInstanceProcAddr getInstanceProcAddr,
VkInstance instance)
{
if (!my_vkGetInstanceProcAddr && getInstanceProcAddr)
my_vkGetInstanceProcAddr = getInstanceProcAddr;
if (!my_vkCreateInstance)
my_vkCreateInstance = (PFN_vkCreateInstance)my_vkGetInstanceProcAddr(
VK_NULL_HANDLE, "vkCreateInstance");
#define LOAD_VULKAN_FUNC(fn) \
if (!my_##fn) \
my_##fn = (PFN_##fn)my_vkGetInstanceProcAddr(instance, #fn)
UNITY_USED_VULKAN_API_FUNCTIONS(LOAD_VULKAN_FUNC);
#undef LOAD_VULKAN_FUNC
}
namespace uiwidgets
{

GLuint UnitySurfaceManager::CreateRenderSurface(void *native_texture_ptr)
{
GLint old_framebuffer_binding;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_framebuffer_binding);
if (m_UnityVulkan != nullptr)
{
UnityVulkanImage image;
m_UnityVulkan->AccessTexture(
native_texture_ptr, UnityVulkanWholeImage, VkImageLayout::VK_IMAGE_LAYOUT_UNDEFINED, 0,
0, UnityVulkanResourceAccessMode::kUnityVulkanResourceAccess_ObserveOnly,
&image);
GrVkImageInfo info(
image.image, GrVkAlloc(image.memory.memory, image.memory.offset, image.memory.size, image.memory.flags),
image.tiling,
image.layout,
image.format,
image.mipCount);
glGenFramebuffers(1, &fbo_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
int width = 100;
int height = 100;
GrBackendTexture backendTex(width, height, info);
GLuint gltex = (GLuint)(size_t)(native_texture_ptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gltex, 0);
FML_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
m_SkSurface = SkSurface::MakeFromBackendTexture(
gr_context_.get(), backendTex, kBottomLeft_GrSurfaceOrigin, 1,
kRGBA_8888_SkColorType, nullptr, nullptr);
return 0;
}
else
{
GLint old_framebuffer_binding;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_framebuffer_binding);
glBindFramebuffer(GL_FRAMEBUFFER, old_framebuffer_binding);
glGenFramebuffers(1, &fbo_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
return fbo_;
GLuint gltex = (GLuint)(size_t)(native_texture_ptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gltex, 0);
FML_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, old_framebuffer_binding);
return fbo_;
}
}
void UnitySurfaceManager::DestroyRenderSurface()

void UnitySurfaceManager::GetUnityContext()
{
if(egl_unity_context_ != nullptr){
if (egl_unity_context_ != nullptr)
{
return;
}
egl_display_ = eglGetCurrentDisplay();

}
static const int DEV_W = 16, DEV_H = 16;
FML_CHECK(egl_display_ != EGL_NO_DISPLAY)
<< "Renderer type is invalid";
auto *graphics = unity_interfaces->Get<IUnityGraphics>();
UnityGfxRenderer renderer = graphics->GetRenderer();
FML_DCHECK(renderer == kUnityGfxRendererOpenGLES30 ||
renderer == kUnityGfxRendererOpenGLES20 ||
renderer == kUnityGfxRendererVulkan);
// Initialize the display connection.
FML_CHECK(eglInitialize(egl_display_, nullptr, nullptr) == EGL_TRUE)
<< "Renderer type is invalid";
if (renderer == kUnityGfxRendererVulkan)
{
auto valid_ = true;
m_UnityVulkan = unity_interfaces->Get<IUnityGraphicsVulkan>();
m_Instance = m_UnityVulkan->Instance();
LoadVulkanAPI(m_Instance.getInstanceProcAddr, m_Instance.instance);
bool success = false;
// // AHarewareBuffer android api >= 26
// AHardwareBuffer* buffer = nullptr;
std::tie(success, egl_config_) = ChooseEGLConfiguration(egl_display_);
FML_CHECK(success) << "Could not choose an EGL configuration.";
// AHardwareBuffer_Desc hwbDesc;
// hwbDesc.width = DEV_W;
// hwbDesc.height = DEV_H;
// hwbDesc.layers = 1;
std::tie(success, egl_context_) = CreateContext(egl_display_, egl_config_, egl_unity_context_);
// hwbDesc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
// AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
// AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
// AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
// hwbDesc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
// // The following three are not used in the allocate
// hwbDesc.stride = 0;
// hwbDesc.rfu0= 0;
// hwbDesc.rfu1= 0;
// if (int error = AHardwareBuffer_allocate(&hwbDesc, &buffer)) {
// ERRORF(reporter, "Failed to allocated hardware buffer, error: %d", error);
// AHardwareBuffer_release(buffer);
// return;
// }
auto device = m_Instance.device;
auto physicalDevice = m_Instance.physicalDevice;
VkImage image = 0;
// ... // create the image as normal
VkMemoryRequirements memReqs; // = device->getImageMemoryRequirements(image);
vkGetImageMemoryRequirements(device, image, &memReqs);
VkMemoryAllocateInfo memAllocInfo;
const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
VkExportMemoryAllocateInfoKHR exportAllocInfo{
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR, nullptr, handle_type};
memAllocInfo.pNext = &exportAllocInfo;
memAllocInfo.allocationSize = memReqs.size;
uint32_t memoryTypeIndex = 0;
bool foundHeap = false;
VkPhysicalDeviceMemoryProperties phyDevMemProps;
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &phyDevMemProps);
for (uint32_t i = 0; i < phyDevMemProps.memoryTypeCount && !foundHeap; ++i)
{
if (VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT & (1 << i))
{
// Map host-visible memory.
if (phyDevMemProps.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
{
memoryTypeIndex = i;
foundHeap = true;
}
}
}
memAllocInfo.memoryTypeIndex = memoryTypeIndex;
// physicalDevice->set_memory_type(
// memReqs.memoryTypeBits, &memAllocInfo, VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VkDeviceMemory memory;
vkAllocateMemory(device, &memAllocInfo, NULL, &memory);
// memory = device->allocateMemory(memAllocInfo);
vkBindImageMemory(device, image, memory, 0);
AHardwareBuffer *buffer = nullptr;
VkMemoryGetAndroidHardwareBufferInfoANDROID meminfo;
meminfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
meminfo.pNext = nullptr;
meminfo.memory = memory;
vkGetMemoryAndroidHardwareBufferANDROID(device, &meminfo, &buffer); // android api level 28
// HANDLE sharedMemoryHandle = device->getMemoryWin32HandleKHR({
// texture.memory, VkExternalMemoryHandleTypeFlags::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
// });
EGLDisplay display = eglGetCurrentDisplay();
EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(buffer);
bool isProtectedContent = true;
EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
isProtectedContent ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
isProtectedContent ? EGL_TRUE : EGL_NONE,
EGL_NONE};
EGLImageKHR imagekhr = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attribs);
GLint old_framebuffer_binding;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_framebuffer_binding);
std::tie(success, egl_resource_context_) = CreateContext(egl_display_, egl_config_, egl_context_);
glGenFramebuffers(1, &fbo_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
GLuint mTexture = 0;
glGenTextures(1, &mTexture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, imagekhr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
FML_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, old_framebuffer_binding);
//-------------------
UnityVulkanPluginEventConfig config_1;
config_1.graphicsQueueAccess = kUnityVulkanGraphicsQueueAccess_DontCare;
config_1.renderPassPrecondition = kUnityVulkanRenderPass_EnsureInside;
config_1.flags =
kUnityVulkanEventConfigFlag_EnsurePreviousFrameSubmission |
kUnityVulkanEventConfigFlag_ModifiesCommandBuffersState;
m_UnityVulkan->ConfigureEvent(1, &config_1);
GrVkBackendContext vk_backend_context;
vk_backend_context.fInstance = m_Instance.instance;
vk_backend_context.fPhysicalDevice = m_Instance.physicalDevice;
vk_backend_context.fDevice = m_Instance.device;
vk_backend_context.fQueue = m_Instance.graphicsQueue;
vk_backend_context.fGraphicsQueueIndex = m_Instance.queueFamilyIndex;
vk_backend_context.fGetProc =
[getInstanceProc = m_Instance.getInstanceProcAddr,
getDeviceProc = my_vkGetDeviceProcAddr](
const char *proc_name, VkInstance instance, VkDevice device) {
if (device != VK_NULL_HANDLE)
{
return getDeviceProc(device, proc_name);
}
return getInstanceProc(instance, proc_name);
};
gr_context_ = GrContext::MakeVulkan(vk_backend_context);
auto valid_ = true;
bool success = false;
return success;
}
else
{
// Make sure Vulkan API functions are loaded
return success;
FML_CHECK(egl_display_ != EGL_NO_DISPLAY)
<< "Renderer type is invalid";
// Initialize the display connection.
FML_CHECK(eglInitialize(egl_display_, nullptr, nullptr) == EGL_TRUE)
<< "Renderer type is invalid";
auto valid_ = true;
bool success = false;
std::tie(success, egl_config_) = ChooseEGLConfiguration(egl_display_);
FML_CHECK(success) << "Could not choose an EGL configuration.";
std::tie(success, egl_context_) = CreateContext(egl_display_, egl_config_, egl_unity_context_);
std::tie(success, egl_resource_context_) = CreateContext(egl_display_, egl_config_, egl_context_);
return success;
}
}
void UnitySurfaceManager::CleanUp()

8
engine/src/shell/platform/unity/android/unity_surface_manager.h


#include "Unity/IUnityGraphics.h"
#include "Unity/IUnityGraphicsVulkan.h"
#include "include/gpu/vk/GrVkBackendContext.h"
namespace uiwidgets
{

EGLContext egl_context_;
EGLContext egl_resource_context_;
EGLConfig egl_config_;
IUnityGraphicsVulkan* m_UnityVulkan;
UnityVulkanInstance m_Instance;
sk_sp<GrContext> gr_context_;
sk_sp<SkSurface> m_SkSurface;
bool initialize_succeeded_;

正在加载...
取消
保存