|
|
|
|
|
|
#include "src/shell/gpu/gpu_surface_gl_delegate.h"
|
|
|
|
namespace uiwidgets |
|
|
|
{ |
|
|
|
#ifdef VulkanX
|
|
|
|
#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
|
|
|
|
} |
|
|
|
#else
|
|
|
|
#endif
|
|
|
|
#ifdef VulkanX
|
|
|
|
m_UnityVulkan(NULL) |
|
|
|
#else
|
|
|
|
// egl_config_(nullptr)
|
|
|
|
#endif
|
|
|
|
{ |
|
|
|
initialize_succeeded_ = Initialize(unity_interfaces); |
|
|
|
} |
|
|
|
|
|
|
GLuint UnitySurfaceManager::CreateRenderSurface(void *native_texture_ptr, size_t width, size_t height) |
|
|
|
{ |
|
|
|
#ifdef VulkanX
|
|
|
|
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); |
|
|
|
|
|
|
|
GrBackendTexture backendTex(width, height, info); |
|
|
|
m_SkSurface = SkSurface::MakeFromBackendTexture( |
|
|
|
gr_context_.get(), backendTex, kBottomLeft_GrSurfaceOrigin, 1, |
|
|
|
kRGBA_8888_SkColorType, nullptr, nullptr); |
|
|
|
|
|
|
|
SkCanvas *canvas = m_SkSurface->getCanvas(); |
|
|
|
|
|
|
|
canvas->drawColor(SK_ColorBLUE); |
|
|
|
SkPaint paint; |
|
|
|
|
|
|
|
SkRect rect = SkRect::MakeXYWH(50, 50, 40, 60); |
|
|
|
canvas->drawRect(rect, paint); |
|
|
|
|
|
|
|
// SkPaint paint2;
|
|
|
|
// auto text = SkTextBlob::MakeFromString("Hello, Skia!", SkFont(nullptr, 18));
|
|
|
|
// canvas->drawTextBlob(text.get(), 50, 25, paint2);
|
|
|
|
canvas->flush(); |
|
|
|
#else
|
|
|
|
// unsigned int texture;
|
|
|
|
// glGenTextures(1, &texture);
|
|
|
|
int rowPitch = width * 4; |
|
|
|
|
|
|
GLuint gltex = (GLuint)(size_t)(native_texture_ptr); |
|
|
|
glBindTexture(GL_TEXTURE_2D, gltex); |
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); |
|
|
|
|
|
|
|
// glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, native_texture_ptr);
|
|
|
|
// glGenerateMipmap(GL_TEXTURE_2D);
|
|
|
|
// glClearColor(1,0,0,1.0);
|
|
|
|
// glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
|
|
|
// gr_context_ = ShellIOManager::CreateCompatibleResourceLoadingContext(
|
|
|
|
// GrBackend::kOpenGL_GrBackend,
|
|
|
|
// GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface());
|
|
|
|
|
|
|
|
// GrGLTextureInfo textureInfo;
|
|
|
|
// textureInfo.fTarget = GR_GL_TEXTURE_2D;
|
|
|
|
// textureInfo.fID = GrGLuint((long)native_texture_ptr);
|
|
|
|
// textureInfo.fFormat = GR_GL_RGBA8;
|
|
|
|
|
|
|
|
// // egl_context_
|
|
|
|
|
|
|
|
// GrBackendTexture m_backendTex =
|
|
|
|
// GrBackendTexture(width, height, GrMipMapped::kNo, textureInfo);
|
|
|
|
|
|
|
|
// m_SkSurface = SkSurface::MakeFromBackendTexture(
|
|
|
|
// gr_context_.get(), m_backendTex, kBottomLeft_GrSurfaceOrigin, 1,
|
|
|
|
// kRGBA_8888_SkColorType, nullptr, nullptr);
|
|
|
|
|
|
|
|
// SkCanvas *canvas = m_SkSurface->getCanvas();
|
|
|
|
|
|
|
|
// canvas->drawColor(SK_ColorBLUE);
|
|
|
|
// SkPaint paint;
|
|
|
|
|
|
|
|
// SkRect rect = SkRect::MakeXYWH(50, 50, 40, 60);
|
|
|
|
// canvas->drawRect(rect, paint);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return fbo_; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
bool UnitySurfaceManager::ClearCurrent() |
|
|
|
{ |
|
|
|
UnityConsole::WriteLine("test c++: make current"); |
|
|
|
#ifdef VulkanX
|
|
|
|
return true; |
|
|
|
#else
|
|
|
|
#endif
|
|
|
|
} |
|
|
|
|
|
|
|
bool UnitySurfaceManager::MakeCurrent(const EGLSurface surface) |
|
|
|
|
|
|
#ifdef Vulkanx
|
|
|
|
return true; |
|
|
|
#else
|
|
|
|
#endif
|
|
|
|
#ifdef VulkanX
|
|
|
|
return true; |
|
|
|
#else
|
|
|
|
#endif
|
|
|
|
#ifdef VulkanX
|
|
|
|
static VKAPI_ATTR VkResult VKAPI_CALL Hook_vkCreateInstance( |
|
|
|
const VkInstanceCreateInfo *pCreateInfo, |
|
|
|
const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) |
|
|
|
{ |
|
|
|
my_vkCreateInstance = (PFN_vkCreateInstance)my_vkGetInstanceProcAddr( |
|
|
|
VK_NULL_HANDLE, "vkCreateInstance"); |
|
|
|
VkResult result = my_vkCreateInstance(pCreateInfo, pAllocator, pInstance); |
|
|
|
if (result == VK_SUCCESS) |
|
|
|
LoadVulkanAPI(my_vkGetInstanceProcAddr, *pInstance); |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL |
|
|
|
Hook_vkGetInstanceProcAddr(VkInstance device, const char *funcName) |
|
|
|
{ |
|
|
|
if (!funcName) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
#define INTERCEPT(fn) \
|
|
|
|
if (strcmp(funcName, #fn) == 0) \ |
|
|
|
return (PFN_vkVoidFunction)&Hook_##fn |
|
|
|
INTERCEPT(vkCreateInstance); |
|
|
|
#undef INTERCEPT
|
|
|
|
|
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
static PFN_vkGetInstanceProcAddr UNITY_INTERFACE_API |
|
|
|
InterceptVulkanInitialization(PFN_vkGetInstanceProcAddr getInstanceProcAddr, |
|
|
|
void *) |
|
|
|
{ |
|
|
|
my_vkGetInstanceProcAddr = getInstanceProcAddr; |
|
|
|
return Hook_vkGetInstanceProcAddr; |
|
|
|
} |
|
|
|
#else
|
|
|
|
// static GLuint CreateShader(GLenum type, const char *sourceText)
|
|
|
|
// {
|
|
|
|
// GLuint ret = glCreateShader(type);
|
|
|
|
// glShaderSource(ret, 1, &sourceText, NULL);
|
|
|
|
// glCompileShader(ret);
|
|
|
|
// return ret;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// static void updatePixel(void *textureDataPtr, int width, int height, int textureRowPitch)
|
|
|
|
// {
|
|
|
|
|
|
|
|
// if (!textureDataPtr)
|
|
|
|
// return;
|
|
|
|
|
|
|
|
// unsigned char *dst = (unsigned char *)textureDataPtr;
|
|
|
|
// for (int y = 0; y < height; ++y)
|
|
|
|
// {
|
|
|
|
// unsigned char *ptr = dst;
|
|
|
|
// for (int x = 0; x < width; ++x)
|
|
|
|
// {
|
|
|
|
// // Simple "plasma effect": several combined sine waves
|
|
|
|
// int vv = 255;
|
|
|
|
|
|
|
|
// // Write the texture pixel
|
|
|
|
// ptr[0] = vv;
|
|
|
|
// // ptr[1] = vv;
|
|
|
|
// // ptr[2] = vv;
|
|
|
|
// ptr[3] = vv;
|
|
|
|
|
|
|
|
// // To next pixel (our pixels are 4 bpp)
|
|
|
|
// ptr += 4;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // To next image row
|
|
|
|
// dst += textureRowPitch;
|
|
|
|
// }
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
static EGLResult<EGLConfig> ChooseEGLConfiguration(EGLDisplay display) |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
return {success, success ? egl_config : nullptr}; |
|
|
|
} |
|
|
|
#endif
|
|
|
|
#ifdef VulkanX
|
|
|
|
IUnityGraphics *graphics = unity_interfaces->Get<IUnityGraphics>(); |
|
|
|
auto result = graphics->GetRenderer(); |
|
|
|
|
|
|
|
FML_CHECK(graphics->GetRenderer() == kUnityGfxRendererVulkan) |
|
|
|
<< "Renderer type is invalid"; |
|
|
|
|
|
|
|
m_UnityVulkan = unity_interfaces->Get<IUnityGraphicsVulkan>(); |
|
|
|
m_UnityVulkan->InterceptInitialization( |
|
|
|
InterceptVulkanInitialization, NULL); |
|
|
|
m_Instance = m_UnityVulkan->Instance(); |
|
|
|
LoadVulkanAPI(m_Instance.getInstanceProcAddr, m_Instance.instance); |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
// alternative way to intercept API
|
|
|
|
// m_UnityVulkan->InterceptVulkanAPI("vkCmdBeginRenderPass",
|
|
|
|
// (PFN_vkVoidFunction)Hook_vkCmdBeginRenderPass);
|
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
#endif
|
|
|
|
egl_display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
|
|
|
FML_CHECK(egl_display_ != EGL_NO_DISPLAY) |
|
|
|
<< "Renderer type is invalid"; |
|
|
|
|
|
|
|
|
|
|
void UnitySurfaceManager::CleanUp() |
|
|
|
{ |
|
|
|
#ifdef VulkanX
|
|
|
|
#else
|
|
|
|
// EGLBoolean result = EGL_FALSE;
|
|
|
|
|
|
|
|
// if (egl_display_ != EGL_NO_DISPLAY && egl_context_ != EGL_NO_CONTEXT)
|
|
|
|
// {
|
|
|
|
// result = eglDestroyContext(egl_display_, egl_context_);
|
|
|
|
// egl_context_ = EGL_NO_CONTEXT;
|
|
|
|
|
|
|
|
// if (result == EGL_FALSE)
|
|
|
|
// {
|
|
|
|
// FML_LOG(ERROR) << "EGL: Failed to destroy context";
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // d3d11_device_ = nullptr;
|
|
|
|
|
|
|
|
// if (egl_display_ != EGL_NO_DISPLAY &&
|
|
|
|
// egl_resource_context_ != EGL_NO_CONTEXT)
|
|
|
|
// {
|
|
|
|
// result = eglDestroyContext(egl_display_, egl_resource_context_);
|
|
|
|
// egl_resource_context_ = EGL_NO_CONTEXT;
|
|
|
|
|
|
|
|
// if (result == EGL_FALSE)
|
|
|
|
// {
|
|
|
|
// FML_LOG(ERROR) << "EGL : Failed to destroy resource context";
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if (egl_display_ != EGL_NO_DISPLAY)
|
|
|
|
// {
|
|
|
|
// result = eglTerminate(egl_display_);
|
|
|
|
// egl_display_ = EGL_NO_DISPLAY;
|
|
|
|
|
|
|
|
// if (result == EGL_FALSE)
|
|
|
|
// {
|
|
|
|
// FML_LOG(ERROR) << "EGL : Failed to terminate EGL";
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
#endif
|
|
|
|
// int width_ = 100;
|
|
|
|
// int height_ = 100;
|
|
|
|
// int i = 0;
|
|
|
|
// sk_sp<GrContext> gr_context_ = GrContext::MakeGL();
|
|
|
|
// UnityConsole::WriteLine(("test c++" + std::to_string(i++)).c_str());
|
|
|
|
|
|
|
|
// sk_sp<SkSurface> m_SkSurface = SkSurface::MakeFromBackendTexture(
|
|
|
|
// gr_context_.get(), m_backendTex, kBottomLeft_GrSurfaceOrigin, 1,
|
|
|
|
// kRGBA_8888_SkColorType, nullptr, nullptr);
|
|
|
|
// UnityConsole::WriteLine(("test c++" + std::to_string(i++)).c_str());
|
|
|
|
|
|
|
|
// SkCanvas* canvas = m_SkSurface->getCanvas();
|
|
|
|
// UnityConsole::WriteLine(("test c++" + std::to_string(i++)).c_str());
|
|
|
|
|
|
|
|
// canvas->drawColor(SK_ColorBLUE);
|
|
|
|
// SkPaint paint;
|
|
|
|
// UnityConsole::WriteLine(("test c++" + std::to_string(i++)).c_str());
|
|
|
|
|
|
|
|
// SkRect rect = SkRect::MakeXYWH(50, 50, 40, 60);
|
|
|
|
// canvas->drawRect(rect, paint);
|
|
|
|
|
|
|
|
// SkPaint paint2;
|
|
|
|
// auto text = SkTextBlob::MakeFromString("Hello, Skia!", SkFont(nullptr, 18));
|
|
|
|
// canvas->drawTextBlob(text.get(), 50, 25, paint2);
|
|
|
|
|
|
|
|
// GrBackendTexture m_backendTex =
|
|
|
|
// GrBackendTexture(width_, height_, GrMipMapped::kNo, textureInfo);
|
|
|
|
|
|
|
|
// m_SkSurface = SkSurface::MakeFromBackendTexture(
|
|
|
|
// gr_context_.get(), m_backendTex, kBottomLeft_GrSurfaceOrigin, 1,
|
|
|
|
// kRGBA_8888_SkColorType, nullptr, nullptr);
|
|
|
|
} |
|
|
|
|
|
|
|
static void *g_TextureHandle = NULL; |
|
|
|