浏览代码

Merge pull request #153 from Unity-Technologies/zxw/windows_use_externalTex

[#BreakingChanges] Use Native d3d11Texture2D and CreateExternalTexture API for texture sharing on Windows
/main
GitHub 3 年前
当前提交
d8d43812
共有 5 个文件被更改,包括 91 次插入112 次删除
  1. 63
      com.unity.uiwidgets/Runtime/engine/UIWidgetsPanelWrapper.cs
  2. 51
      engine/src/shell/platform/unity/windows/uiwidgets_panel.cc
  3. 6
      engine/src/shell/platform/unity/windows/uiwidgets_panel.h
  4. 71
      engine/src/shell/platform/unity/windows/unity_surface_manager.cc
  5. 12
      engine/src/shell/platform/unity/windows/unity_surface_manager.h

63
com.unity.uiwidgets/Runtime/engine/UIWidgetsPanelWrapper.cs


using Path = Unity.UIWidgets.ui.Path;
namespace Unity.UIWidgets.engine {
#region Platform: Windows Specific Functionalities
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
public partial class UIWidgetsPanelWrapper {
public RenderTexture renderTexture { get; private set; }
void _createRenderTexture(int width, int height, float devicePixelRatio) {
D.assert(renderTexture == null);
var desc = new RenderTextureDescriptor(
width: width, height: height, colorFormat: RenderTextureFormat.ARGB32, 0) {
useMipMap = false,
autoGenerateMips = false
};
renderTexture = new RenderTexture(desc: desc) {hideFlags = HideFlags.HideAndDontSave};
renderTexture.Create();
_width = width;
_height = height;
this.devicePixelRatio = devicePixelRatio;
}
void _destroyRenderTexture() {
D.assert(renderTexture != null);
ObjectUtils.SafeDestroy(obj: renderTexture);
renderTexture = null;
}
#region Platform: MacOs/iOS/Windows Specific Functionalities
void _enableUIWidgetsPanel(string font_settings) {
UIWidgetsPanel_onEnable(ptr: _ptr, renderTexture.GetNativeTexturePtr(),
width: _width, height: _height, dpi: devicePixelRatio,
streamingAssetsPath: Application.streamingAssetsPath, font_settings: font_settings);
}
void _resizeUIWidgetsPanel() {
UIWidgetsPanel_onRenderTexture(ptr: _ptr,
renderTexture.GetNativeTexturePtr(),
width: _width, height: _height, dpi: devicePixelRatio);
}
void _disableUIWidgetsPanel() {
renderTexture = null;
}
[DllImport(dllName: NativeBindings.dllName)]
static extern void UIWidgetsPanel_onEnable(IntPtr ptr,
IntPtr nativeTexturePtr, int width, int height, float dpi, string streamingAssetsPath,
string font_settings);
[DllImport(dllName: NativeBindings.dllName)]
static extern void UIWidgetsPanel_onRenderTexture(
IntPtr ptr, IntPtr nativeTexturePtr, int width, int height, float dpi);
}
#endif
#endregion
#region Platform: MacOs/iOS Specific Functionalities
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
public partial class UIWidgetsPanelWrapper {
Texture _renderTexture;

51
engine/src/shell/platform/unity/windows/uiwidgets_panel.cc


return window_type_ == EditorWindowPanel;
}
void UIWidgetsPanel::OnEnable(void* native_texture_ptr, size_t width,
void* UIWidgetsPanel::OnEnable(size_t width,
size_t height, float device_pixel_ratio,
const char* streaming_assets_path,
const char* settings) {

FML_DCHECK(fbo_ == 0);
surface_manager_->MakeCurrent(EGL_NO_DISPLAY);
fbo_ = surface_manager_->CreateRenderSurface(native_texture_ptr);
fbo_ = surface_manager_->CreateRenderSurface(width, height);
void* d3dtexture = surface_manager_->GetD3DInnerTexture();
surface_manager_->ClearCurrent();
fml::AutoResetWaitableEvent latch;

if (result != kSuccess || engine == nullptr) {
std::cerr << "Failed to start UIWidgets engine: error " << result
<< std::endl;
return;
return nullptr;
}
engine_ = engine;

process_events_ = true;
return static_cast<void*>(d3dtexture);
}
void UIWidgetsPanel::MonoEntrypoint() { entrypoint_callback_(handle_); }

if (fbo_) {
surface_manager_->MakeCurrent(EGL_NO_DISPLAY);
surface_manager_->DestroyRenderSurface();
surface_manager_->ReleaseNativeRenderTexture();
fbo_ = 0;
surface_manager_->ClearCurrent();

}
void UIWidgetsPanel::OnRenderTexture(void* native_texture_ptr, size_t width,
void* UIWidgetsPanel::OnRenderTexture(size_t width,
fml::AutoResetWaitableEvent latch;
reinterpret_cast<EmbedderEngine*>(engine_)->PostRenderThreadTask(
[&latch, this, native_texture_ptr]() -> void {
surface_manager_->MakeCurrent(EGL_NO_DISPLAY);
if (fbo_) {
surface_manager_->DestroyRenderSurface();
fbo_ = 0;
}
fbo_ = surface_manager_->CreateRenderSurface(native_texture_ptr);
surface_manager_->ClearCurrent();
latch.Signal();
});
latch.Wait();
fbo_ = surface_manager_->CreateRenderSurface(width, height);
return static_cast<void*>(surface_manager_->GetD3DInnerTexture());
bool UIWidgetsPanel::ReleaseNativeRenderTexture() { return surface_manager_->ReleaseNativeRenderTexture(); }
int UIWidgetsPanel::RegisterTexture(void* native_texture_ptr) {
int texture_identifier = 0;

panel->Release();
}
UIWIDGETS_API(void)
UIWidgetsPanel_onEnable(UIWidgetsPanel* panel, void* native_texture_ptr,
UIWIDGETS_API(void*)
UIWidgetsPanel_onEnable(UIWidgetsPanel* panel,
panel->OnEnable(native_texture_ptr, width, height, device_pixel_ratio,
return panel->OnEnable(width, height, device_pixel_ratio,
streaming_assets_path, settings);
}

UIWIDGETS_API(void)
UIWidgetsPanel_onRenderTexture(UIWidgetsPanel* panel, void* native_texture_ptr,
UIWIDGETS_API(bool) UIWidgetsPanel_releaseNativeTexture(UIWidgetsPanel* panel) {
return panel->ReleaseNativeRenderTexture();
}
UIWIDGETS_API(void*)
UIWidgetsPanel_onRenderTexture(UIWidgetsPanel* panel,
panel->OnRenderTexture(native_texture_ptr, width, height, dpi);
return panel->OnRenderTexture(width, height, dpi);
}
UIWIDGETS_API(int)

6
engine/src/shell/platform/unity/windows/uiwidgets_panel.h


~UIWidgetsPanel();
void OnEnable(void* native_texture_ptr, size_t width, size_t height,
void* OnEnable(size_t width, size_t height,
float device_pixel_ratio, const char* streaming_assets_path,
const char* settings);

void OnRenderTexture(void* native_texture_ptr, size_t width, size_t height,
void* OnRenderTexture(size_t width, size_t height,
bool ReleaseNativeRenderTexture();
int RegisterTexture(void* native_texture_ptr);

71
engine/src/shell/platform/unity/windows/unity_surface_manager.cc


UnitySurfaceManager::~UnitySurfaceManager() { CleanUp(); }
GLuint UnitySurfaceManager::CreateRenderSurface(void* native_texture_ptr) {
ID3D11Texture2D* d3d11_texture =
static_cast<ID3D11Texture2D*>(native_texture_ptr);
void UnitySurfaceManager::CreateRenderTexture(size_t width, size_t height) {
D3D11_TEXTURE2D_DESC desc = {0};
desc.Width = width;
desc.Height = height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
HRESULT hr = d3d11_device_->CreateTexture2D(&desc, nullptr, &d3d11_texture);
FML_CHECK(SUCCEEDED(hr)) << "UnitySurfaceManager: Create Native d3d11Texture2D failed";
}
GLuint UnitySurfaceManager::CreateRenderSurface(size_t width, size_t height) {
CreateRenderTexture(width, height);
IDXGIResource* image_resource;
HRESULT hr = d3d11_texture->QueryInterface(
__uuidof(IDXGIResource), reinterpret_cast<void**>(&image_resource));

"D3D11_RESOURCE_MISC_SHARED is needed";
IDXGIResource* dxgi_resource;
hr = d3d11_device_->OpenSharedResource(
hr = d3d11_angle_device_->OpenSharedResource(
shared_image_handle, __uuidof(ID3D11Resource),
reinterpret_cast<void**>(&dxgi_resource));
FML_CHECK(SUCCEEDED(hr))

dxgi_resource->Release();
MakeCurrent(EGL_NO_DISPLAY);
const EGLint attribs[] = {EGL_NONE};
FML_DCHECK(fbo_egl_image_ == nullptr);
fbo_egl_image_ =

glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
fbo_texture_, 0);
FML_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) ==
GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, old_framebuffer_binding);

void UnitySurfaceManager::DestroyRenderSurface() {
FML_DCHECK(fbo_ != 0);
glDeleteFramebuffers(1, &fbo_);
fbo_ = 0;
FML_DCHECK(fbo_texture_ != 0);
glDeleteTextures(1, &fbo_texture_);
fbo_texture_ = 0;
FML_DCHECK(fbo_egl_image_ != nullptr);
eglDestroyImageKHR(egl_display_, fbo_egl_image_);
fbo_egl_image_ = nullptr;
}
bool UnitySurfaceManager::ClearCurrent() {
return eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT) == EGL_TRUE;

IUnityGraphicsD3D11* d3d11 = unity_interfaces->Get<IUnityGraphicsD3D11>();
ID3D11Device* d3d11_device = d3d11->GetDevice();
d3d11_device_ = d3d11_device;
IDXGIDevice* dxgi_device;
HRESULT hr = d3d11_device->QueryInterface(

EGLAttrib angle_device = 0;
eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(egl_device),
EGL_D3D11_DEVICE_ANGLE, &angle_device);
d3d11_device_ = reinterpret_cast<ID3D11Device*>(angle_device);
d3d11_angle_device_ = reinterpret_cast<ID3D11Device*>(angle_device);
const EGLint configAttributes[] = {EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,

}
d3d11_device_ = nullptr;
d3d11_angle_device_ = nullptr;
}
bool UnitySurfaceManager::ReleaseNativeRenderTexture() {
if (d3d11_texture == nullptr) {
return true;
}
FML_DCHECK(fbo_ != 0);
glDeleteFramebuffers(1, &fbo_);
fbo_ = 0;
FML_DCHECK(fbo_texture_ != 0);
glDeleteTextures(1, &fbo_texture_);
fbo_texture_ = 0;
FML_DCHECK(fbo_egl_image_ != nullptr);
eglDestroyImageKHR(egl_display_, fbo_egl_image_);
fbo_egl_image_ = nullptr;
d3d11_texture->Release();
d3d11_texture = nullptr;
return true;

12
engine/src/shell/platform/unity/windows/unity_surface_manager.h


UnitySurfaceManager(IUnityInterfaces* unity_interfaces);
~UnitySurfaceManager();
GLuint CreateRenderSurface(void* native_texture_ptr);
void DestroyRenderSurface();
GLuint CreateRenderSurface(size_t width, size_t height);
bool ReleaseNativeRenderTexture();
bool ClearCurrent();

EGLDisplay GetEGLDisplay() const { return egl_display_; }
ID3D11Device* GetD3D11Device() const { return d3d11_device_; }
ID3D11Device* GetD3D11Device() const { return d3d11_angle_device_; }
void* GetD3DInnerTexture() const { return static_cast<void*>(d3d11_texture); }
void CreateRenderTexture(size_t width, size_t height);
void CleanUp();
EGLDisplay egl_display_;

bool initialize_succeeded_;
ID3D11Device* d3d11_device_;
ID3D11Device* d3d11_angle_device_;
ID3D11Texture2D* d3d11_texture;
EGLImage fbo_egl_image_ = nullptr;
GLuint fbo_texture_ = 0;

正在加载...
取消
保存