diff --git a/com.unity.uiwidgets/Runtime/engine/UIWidgetsExternalTextureRegistry.cs b/com.unity.uiwidgets/Runtime/engine/UIWidgetsExternalTextureRegistry.cs index 31914e0a..bd4f1104 100644 --- a/com.unity.uiwidgets/Runtime/engine/UIWidgetsExternalTextureRegistry.cs +++ b/com.unity.uiwidgets/Runtime/engine/UIWidgetsExternalTextureRegistry.cs @@ -42,6 +42,7 @@ namespace Unity.UIWidgets.engine { D.assert(externalTexturePtr != IntPtr.Zero, () => "Cannot register null external texture"); if (!externalTextures.ContainsKey(externalTexturePtr)) { var internalTextureId = registerTexture(externalTexturePtr); + D.assert(internalTextureId != -1, () => "Fail to register external texture. Possible cause is that you platform and graphics backend doesn't support external texture (e.g., Metal on Mac/iOS)"); externalTextures[externalTexturePtr] = internalTextureId; } diff --git a/com.unity.uiwidgets/Runtime/rendering/texture.cs b/com.unity.uiwidgets/Runtime/rendering/texture.cs index a459691c..dfd23232 100644 --- a/com.unity.uiwidgets/Runtime/rendering/texture.cs +++ b/com.unity.uiwidgets/Runtime/rendering/texture.cs @@ -84,7 +84,11 @@ namespace Unity.UIWidgets.rendering { } return; } - + + //texture id == -1 means that the texture is not valid, we won't paint it at all + if (_textureId.Value == -1) { + return; + } _scheduleAppFrame(); context.addLayer(new TextureLayer( rect: Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height), diff --git a/engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.h b/engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.h index 2d3553ba..77dcb6d9 100644 --- a/engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.h +++ b/engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.h @@ -35,7 +35,7 @@ class UIWidgetsPanel : public fml::RefCountedThreadSafe { ~UIWidgetsPanel(); - void OnEnable(void *native_texture_ptr, size_t width, size_t height, float device_pixel_ratio, const char* streaming_assets_path, const char* settings); + void* OnEnable(void *native_texture_ptr, size_t width, size_t height, float device_pixel_ratio, const char* streaming_assets_path, const char* settings); void MonoEntrypoint(); diff --git a/engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.mm b/engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.mm index 589ba259..6cdad809 100644 --- a/engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.mm +++ b/engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.mm @@ -34,7 +34,7 @@ bool UIWidgetsPanel::NeedUpdateByEditorLoop() { return window_type_ == EditorWindowPanel; } -void UIWidgetsPanel::OnEnable(void *native_texture_ptr, size_t width, size_t height, float device_pixel_ratio, +void* UIWidgetsPanel::OnEnable(void *native_texture_ptr, size_t width, size_t height, float device_pixel_ratio, const char* streaming_assets_path, const char* settings) { fml::AutoResetWaitableEvent latch; @@ -48,11 +48,10 @@ void UIWidgetsPanel::OnEnable(void *native_texture_ptr, size_t width, size_t hei surface_manager_ = std::make_unique( UIWidgetsSystem::GetInstancePtr()->GetUnityInterfaces()); - void* metal_tex = surface_manager_->CreateRenderTexture(native_texture_ptr, width, height); + void* _tex_handler = surface_manager_->CreateRenderTexture(native_texture_ptr, width, height); CreateInternalUIWidgetsEngine(width, height, device_pixel_ratio, streaming_assets_path, settings, gfx_worker_thread_id); - - //return metal_tex; + return _tex_handler; } void UIWidgetsPanel::CreateInternalUIWidgetsEngine(size_t width, size_t height, float device_pixel_ratio, @@ -228,14 +227,24 @@ bool UIWidgetsPanel::ReleaseNativeRenderTexture() { return surface_manager_->Rel int UIWidgetsPanel::RegisterTexture(void* native_texture_ptr) { int64_t texture_identifier = reinterpret_cast(native_texture_ptr); + std::shared_ptr externalTexture = std::make_unique(texture_identifier); + + if (!externalTexture.get()->isValid()) + { + externalTexture.reset(); + return -1; + } + auto* engine = reinterpret_cast(engine_); - engine->GetShell().GetPlatformView()->RegisterTexture( - std::make_unique( - texture_identifier)); + engine->GetShell().GetPlatformView()->RegisterTexture(externalTexture); return texture_identifier; } void UIWidgetsPanel::UnregisterTexture(int texture_id) { + if (texture_id == -1) + { + return; + } auto *engine = reinterpret_cast(engine_); engine->GetShell().GetPlatformView()->UnregisterTexture(texture_id); } @@ -473,12 +482,12 @@ UIWIDGETS_API(void) UIWidgetsPanel_dispose(UIWidgetsPanel* panel) { panel->Release(); } -UIWIDGETS_API(void) +UIWIDGETS_API(void*) UIWidgetsPanel_onEnable(UIWidgetsPanel* panel, void *native_texture_ptr, size_t width, size_t height, float device_pixel_ratio, const char* streaming_assets_path, const char* settings) { - panel->OnEnable(native_texture_ptr, width, height, device_pixel_ratio, + return panel->OnEnable(native_texture_ptr, width, height, device_pixel_ratio, streaming_assets_path, settings); } @@ -490,10 +499,10 @@ UIWIDGETS_API(bool) UIWidgetsPanel_releaseNativeTexture(UIWidgetsPanel* panel) { return panel->ReleaseNativeRenderTexture(); } -UIWIDGETS_API(void) +UIWIDGETS_API(void*) UIWidgetsPanel_onRenderTexture(UIWidgetsPanel* panel, void *native_texture_ptr, int width, int height, float dpi) { - panel->OnRenderTexture(native_texture_ptr, width, height, dpi); + return panel->OnRenderTexture(native_texture_ptr, width, height, dpi); } UIWIDGETS_API(int) diff --git a/engine/src/shell/platform/unity/darwin/macos/unity_external_texture_gl.h b/engine/src/shell/platform/unity/darwin/macos/unity_external_texture_gl.h index c4089f1b..2968f744 100644 --- a/engine/src/shell/platform/unity/darwin/macos/unity_external_texture_gl.h +++ b/engine/src/shell/platform/unity/darwin/macos/unity_external_texture_gl.h @@ -13,10 +13,13 @@ class UnityExternalTextureGL : public Texture { UnityExternalTextureGL(int64_t texture_identifier); ~UnityExternalTextureGL() override; + + bool isValid() { return valid; }; private: GLuint gl_texture_; sk_sp last_image_; + bool valid; // |flutter::Texture| void Paint(SkCanvas& canvas, const SkRect& bounds, bool freeze, diff --git a/engine/src/shell/platform/unity/darwin/macos/unity_external_texture_gl.mm b/engine/src/shell/platform/unity/darwin/macos/unity_external_texture_gl.mm index 2fd914fb..4fc781bf 100644 --- a/engine/src/shell/platform/unity/darwin/macos/unity_external_texture_gl.mm +++ b/engine/src/shell/platform/unity/darwin/macos/unity_external_texture_gl.mm @@ -18,7 +18,7 @@ UnityExternalTextureGL::UnityExternalTextureGL( ->GetUnityInterfaces() ->Get(); UnityGfxRenderer renderer = graphics->GetRenderer(); - FML_DCHECK(renderer == kUnityGfxRendererOpenGLCore); + valid = renderer == kUnityGfxRendererOpenGLCore; gl_texture_ = texture_identifier; } diff --git a/engine/src/shell/platform/unity/darwin/macos/unity_surface_manager.mm b/engine/src/shell/platform/unity/darwin/macos/unity_surface_manager.mm index 2c1653d2..bdc43f95 100644 --- a/engine/src/shell/platform/unity/darwin/macos/unity_surface_manager.mm +++ b/engine/src/shell/platform/unity/darwin/macos/unity_surface_manager.mm @@ -116,30 +116,14 @@ void* UnitySurfaceManager::CreateRenderTexture(void *native_texture_ptr, size_t const GLuint ConstGLType = GL_UNSIGNED_INT_8_8_8_8_REV; if (useOpenGLCore) { - gl_tex_ = static_cast(reinterpret_cast(native_texture_ptr)); - + gl_tex_ = static_cast(reinterpret_cast(native_texture_ptr)); + NSOpenGLContext* _pre_context = [NSOpenGLContext currentContext]; GLint old_texture_binding_2d; glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_texture_binding_2d); [gl_context_ makeCurrentContext]; - //glGenTextures(1, &gl_tex_); glBindTexture(GL_TEXTURE_2D, gl_tex_); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - //test data - // unsigned char* data = new unsigned char[4 * width * height * sizeof(unsigned char)]; - // for (unsigned int i = 0; i < (int)(width * height * sizeof(unsigned char)); i++) { - // data[i * 4] = 255; - // data[i * 4 + 1] = 255; - // data[i * 4 + 2] = 0; - // data[i * 4 + 3] = 255; - // } - - //glTexImage2D(GL_TEXTURE_2D, 0, ConstGLInternalFormat, width, height, 0, ConstGLFormat, ConstGLType, data); glGenFramebuffers(1, &default_fbo_); GLint old_framebuffer_binding; @@ -151,48 +135,47 @@ void* UnitySurfaceManager::CreateRenderTexture(void *native_texture_ptr, size_t FML_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); - //unbind stuffs + //reset gl states glBindFramebuffer(GL_FRAMEBUFFER, old_framebuffer_binding); glBindTexture(GL_TEXTURE_2D, old_texture_binding_2d); - - //recover current gl context if (_pre_context != nil) { [_pre_context makeCurrentContext]; } return (void*) gl_tex_; } + else + { + //render context must be available + FML_DCHECK(metal_device_ != nullptr && gl_context_ != nullptr); + + //render textures must be released already + FML_DCHECK(pixelbuffer_ref == nullptr && default_fbo_ == 0 && gl_tex_ == 0 && gl_tex_cache_ref_ == nullptr && gl_tex_ref_ == nullptr && metal_tex_ == nullptr && metal_tex_ref_ == nullptr && metal_tex_cache_ref_ == nullptr); + //create pixel buffer + auto gl_pixelformat_ = gl_context_.pixelFormat.CGLPixelFormatObj; - //render context must be available - FML_DCHECK(metal_device_ != nullptr && gl_context_ != nullptr); + NSDictionary* cvBufferProperties = @{ + (__bridge NSString*)kCVPixelBufferOpenGLCompatibilityKey : @YES, + (__bridge NSString*)kCVPixelBufferMetalCompatibilityKey : @YES, + }; - //render textures must be released already - FML_DCHECK(pixelbuffer_ref == nullptr && default_fbo_ == 0 && gl_tex_ == 0 && gl_tex_cache_ref_ == nullptr && gl_tex_ref_ == nullptr && metal_tex_ == nullptr && metal_tex_ref_ == nullptr && metal_tex_cache_ref_ == nullptr); - //create pixel buffer - auto gl_pixelformat_ = gl_context_.pixelFormat.CGLPixelFormatObj; - - NSDictionary* cvBufferProperties = @{ - (__bridge NSString*)kCVPixelBufferOpenGLCompatibilityKey : @YES, - (__bridge NSString*)kCVPixelBufferMetalCompatibilityKey : @YES, - }; - - CVReturn cvret = CVPixelBufferCreate(kCFAllocatorDefault, + CVReturn cvret = CVPixelBufferCreate(kCFAllocatorDefault, width, height, ConstCVPixelFormat, (__bridge CFDictionaryRef)cvBufferProperties, &pixelbuffer_ref); - FML_DCHECK(cvret == kCVReturnSuccess); + FML_DCHECK(cvret == kCVReturnSuccess); - //create metal texture - cvret = CVMetalTextureCacheCreate( + //create metal texture + cvret = CVMetalTextureCacheCreate( kCFAllocatorDefault, nil, metal_device_, nil, &metal_tex_cache_ref_); - FML_DCHECK(cvret == kCVReturnSuccess); + FML_DCHECK(cvret == kCVReturnSuccess); - cvret = CVMetalTextureCacheCreateTextureFromImage( + cvret = CVMetalTextureCacheCreateTextureFromImage( kCFAllocatorDefault, metal_tex_cache_ref_, pixelbuffer_ref, nil, @@ -200,40 +183,41 @@ void* UnitySurfaceManager::CreateRenderTexture(void *native_texture_ptr, size_t width, height, 0, &metal_tex_ref_); - FML_DCHECK(cvret == kCVReturnSuccess); + FML_DCHECK(cvret == kCVReturnSuccess); - metal_tex_ = CVMetalTextureGetTexture(metal_tex_ref_); - FML_DCHECK(metal_tex_ != nullptr); + metal_tex_ = CVMetalTextureGetTexture(metal_tex_ref_); + FML_DCHECK(metal_tex_ != nullptr); - //create opengl texture - cvret = CVOpenGLTextureCacheCreate( + //create opengl texture + cvret = CVOpenGLTextureCacheCreate( kCFAllocatorDefault, nil, gl_context_.CGLContextObj, gl_pixelformat_, nil, &gl_tex_cache_ref_); - FML_DCHECK(cvret == kCVReturnSuccess); + FML_DCHECK(cvret == kCVReturnSuccess); - cvret = CVOpenGLTextureCacheCreateTextureFromImage( + cvret = CVOpenGLTextureCacheCreateTextureFromImage( kCFAllocatorDefault, gl_tex_cache_ref_, pixelbuffer_ref, nil, &gl_tex_ref_); - FML_DCHECK(cvret == kCVReturnSuccess); + FML_DCHECK(cvret == kCVReturnSuccess); - gl_tex_ = CVOpenGLTextureGetName(gl_tex_ref_); + gl_tex_ = CVOpenGLTextureGetName(gl_tex_ref_); - //initialize gl renderer - [gl_context_ makeCurrentContext]; - glGenFramebuffers(1, &default_fbo_); - glBindFramebuffer(GL_FRAMEBUFFER, default_fbo_); + //initialize gl renderer + [gl_context_ makeCurrentContext]; + glGenFramebuffers(1, &default_fbo_); + glBindFramebuffer(GL_FRAMEBUFFER, default_fbo_); - const GLenum texType = GL_TEXTURE_RECTANGLE; - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texType, gl_tex_, 0); + const GLenum texType = GL_TEXTURE_RECTANGLE; + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texType, gl_tex_, 0); - return (__bridge void*)metal_tex_; + return (__bridge void*)metal_tex_; + } } bool UnitySurfaceManager::ClearCurrentContext() @@ -253,11 +237,7 @@ bool UnitySurfaceManager::MakeCurrentContext() if (_pre_context != nil && _pre_context != gl_context_ && _pre_context != gl_resource_context_) { - if(unity_previous_gl_context_ != nil) - { - int u = 100; - } - unity_previous_gl_context_ = _pre_context; + unity_previous_gl_context_ = _pre_context; } [gl_context_ makeCurrentContext]; @@ -270,10 +250,6 @@ bool UnitySurfaceManager::MakeCurrentResourceContext() if (_pre_context != nil && _pre_context != gl_context_ && _pre_context != gl_resource_context_) { - if(unity_previous_gl_context_ != nil) - { - int u = 100; - } unity_previous_gl_context_ = _pre_context; }