diff --git a/engine/flutter/shell/common/rasterizer.cc b/engine/flutter/shell/common/rasterizer.cc index ef2224b2a04c01a65f737e1df440bef9746914f4..f4733017dc1e7ab89032f913cddcfb1f94ace7ab 100644 --- a/engine/flutter/shell/common/rasterizer.cc +++ b/engine/flutter/shell/common/rasterizer.cc @@ -18,7 +18,7 @@ namespace flutter { -#ifndef OHOS_STANDARD_SYSTEM +#ifndef GPU_DISABLED // The rasterizer will tell Skia to purge cached resources that have not been // used within this interval. static constexpr std::chrono::milliseconds kSkiaCleanupExpiration(15000); @@ -265,7 +265,7 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) { } FireNextFrameCallbackIfPresent(); -#ifndef OHOS_STANDARD_SYSTEM +#ifndef GPU_DISABLED if (surface_->GetContext()) { surface_->GetContext()->performDeferredCleanup(kSkiaCleanupExpiration); } @@ -451,7 +451,7 @@ void Rasterizer::SetResourceCacheMaxBytes(size_t max_bytes, bool from_user) { if (!surface_) { return; } -#ifndef OHOS_STANDARD_SYSTEM +#ifndef GPU_DISABLED GrContext* context = surface_->GetContext(); if (context) { int max_resources; @@ -465,12 +465,14 @@ std::optional Rasterizer::GetResourceCacheMaxBytes() const { if (!surface_) { return std::nullopt; } +#ifndef GPU_DISABLED GrContext* context = surface_->GetContext(); if (context) { size_t max_bytes; context->getResourceCacheLimits(nullptr, &max_bytes); return max_bytes; } +#endif return std::nullopt; } diff --git a/engine/flutter/shell/platform/ohos/ohos_surface.h b/engine/flutter/shell/platform/ohos/ohos_surface.h index da77bf15d1aa9024d317dcb5f6120718e6cac09a..e18496f12c796ec874b1e40a7f0a1c4d5ec6aa55 100644 --- a/engine/flutter/shell/platform/ohos/ohos_surface.h +++ b/engine/flutter/shell/platform/ohos/ohos_surface.h @@ -28,6 +28,12 @@ public: virtual bool OnScreenSurfaceResize(const SkISize& size) = 0; virtual void SetPlatformWindow(const ::OHOS::sptr<::OHOS::Window> &window) = 0; + + virtual bool ResourceContextMakeCurrent() = 0; + + virtual bool ResourceContextClearCurrent() = 0; + + virtual void TeardownOnScreenContext() = 0; }; } // namespace flutter diff --git a/engine/flutter/shell/platform/ohos/ohos_surface_gl.cc b/engine/flutter/shell/platform/ohos/ohos_surface_gl.cc new file mode 100644 index 0000000000000000000000000000000000000000..3d941fae007380b67da95986c014f0cb89dcb48a --- /dev/null +++ b/engine/flutter/shell/platform/ohos/ohos_surface_gl.cc @@ -0,0 +1,231 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// 2021.4.30 platform view adapt ohos. +// Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + +#include "flutter/shell/platform/ohos/ohos_surface_gl.h" + +#include "flutter/fml/logging.h" +#include "flutter/fml/memory/ref_ptr.h" + +namespace flutter { +OhosSurfaceGL::OhosSurfaceGL() + : window_(nullptr), + eglRenderSurface_(nullptr), + eglDisplay_(nullptr), + eglContext_(nullptr), + eglSurface_(nullptr), + valid_(false) +{ + FML_LOG(ERROR) << "OhosSurfaceGL Constructor"; +} + +bool OhosSurfaceGL::IsValid() const +{ + return valid_; +} + +std::unique_ptr OhosSurfaceGL::CreateGPUSurface() +{ + auto surface = std::make_unique(this, true); + return surface->IsValid() ? std::move(surface) : nullptr; +} + +void OhosSurfaceGL::SetPlatformWindow(const OHOS::sptr& window) +{ + if (window == nullptr) { + FML_LOG(ERROR) << "Ohos window is nullptr"; + return; + } + + window_ = window; + + // init render surface + if (!this->InitRenderSurface()) { + FML_LOG(ERROR) << "Failed to init render surface."; + } +} + +bool OhosSurfaceGL::OnScreenSurfaceResize(const SkISize& size) +{ + if (!IsValid()) { + FML_LOG(ERROR) << "OnScreenSurfaceResize surface invalid"; + return false; + } + + eglRenderSurface_->SetWidthAndHeight(size.width(), size.height()); + + return true; +} + +void OhosSurfaceGL::TeardownOnScreenContext() +{ + if (!IsValid()) { + FML_LOG(ERROR) << "TeardownOnScreenContext surface invalid"; + return; + } + + if (eglGetCurrentContext() != eglContext_) { + FML_LOG(INFO) << "Egl context is diff"; + return; + } + + if (eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) { + FML_LOG(ERROR) << "Could not clear the current context"; + return; + } +} + +bool OhosSurfaceGL::ResourceContextMakeCurrent() +{ + return false; +} + +bool OhosSurfaceGL::ResourceContextClearCurrent() +{ + return false; +} + +bool OhosSurfaceGL::GLContextPresent() +{ + if (!IsValid()) { + FML_LOG(ERROR) << "GLContextPresent surface invalid"; + return false; + } + + OHOS::SurfaceError errorCode = eglRenderSurface_->SwapBuffers(); + if (errorCode != OHOS::SURFACE_ERROR_OK) { + FML_LOG(ERROR) << "Failed to swap buffers. code is " << errorCode; + return false; + } + + return true; +} + +intptr_t OhosSurfaceGL::GLContextFBO() const +{ + if (!IsValid()) { + FML_LOG(ERROR) << "GLContextFBO surface invalid"; + return 0; + } + + return static_cast(eglRenderSurface_->GetEglFbo()); +} + +bool OhosSurfaceGL::GLContextFBOResetAfterPresent() const +{ + return true; +} + +bool OhosSurfaceGL::UseOffscreenSurface() const +{ + return true; +} + +SkMatrix OhosSurfaceGL::GLContextSurfaceTransformation() const +{ + SkMatrix matrix; + matrix.setIdentity(); + // Mirror flip + double y = window_->GetHeight() / 2.0; + matrix.postTranslate(0, -y); + matrix.postScale(1, -1); + matrix.postTranslate(0, y); + return matrix; +} + +bool OhosSurfaceGL::GLContextMakeCurrent() +{ + if (!IsValid()) { + FML_LOG(ERROR) << "GLContextMakeCurrent surface invalid"; + return false; + } + + // Avoid unused egl called. + if (eglGetCurrentContext() == eglContext_) { + FML_LOG(INFO) << "Egl context is same"; + return true; + } + + if ((eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_) != EGL_TRUE)) { + FML_LOG(ERROR) << "Could not make the context current. code is " << eglGetError(); + return false; + } + + return true; +} + +bool OhosSurfaceGL::GLContextClearCurrent() +{ + if (!IsValid()) { + FML_LOG(ERROR) << "GLContextClearCurrent surface invalid"; + return false; + } + + if (eglGetCurrentContext() != eglContext_) { + FML_LOG(INFO) << "Egl context is diff"; + return true; + } + + if (eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) { + FML_LOG(ERROR) << "Could not clear the current context. code is " << eglGetError(); + return false; + } + + return true; +} + +ExternalViewEmbedder* OhosSurfaceGL::GetExternalViewEmbedder() +{ + return nullptr; +} + +bool OhosSurfaceGL::InitRenderSurface() +{ + if (!window_) { + FML_LOG(ERROR) << "window_ is nullptr"; + return false; + } + + OHOS::sptr bufferProducer = window_->GetProducer(); + if (bufferProducer == nullptr) { + FML_LOG(ERROR) << "bufferProducer is nullptr"; + return false; + } + + eglRenderSurface_ = OHOS::EglRenderSurface::CreateEglRenderSurfaceAsProducer(bufferProducer); + if (eglRenderSurface_ == nullptr) { + FML_LOG(ERROR) << "eglRenderSurface_ is nullptr"; + return false; + } + + OHOS::SurfaceError errorCode = eglRenderSurface_->InitContext(); + if (errorCode != OHOS::SURFACE_ERROR_OK) { + FML_LOG(ERROR) << "Failed to init render context. code is " << errorCode; + return false; + } + + if ((eglGetCurrentContext() == eglContext_) && + (eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE)) { + FML_LOG(ERROR) << "Could not clear the current context. code is " << eglGetError(); + } + + eglDisplay_ = eglRenderSurface_->GetEglDisplay(); + if (eglDisplay_ == EGL_NO_DISPLAY) { + FML_LOG(ERROR) << "EglDisplay_ is nullptr"; + return false; + } + + eglContext_ = eglRenderSurface_->GetEglContext(); + if (eglContext_ == EGL_NO_CONTEXT) { + FML_LOG(ERROR) << "EglContext_ is nullptr"; + return false; + } + + // surface default EGL_NO_SURFACE + eglSurface_ = eglRenderSurface_->GetEglSurface(); + valid_ = true; + return true; +} +} // namespace flutter diff --git a/engine/flutter/shell/platform/ohos/ohos_surface_gl.h b/engine/flutter/shell/platform/ohos/ohos_surface_gl.h new file mode 100644 index 0000000000000000000000000000000000000000..f3591a54a1c182881f37bd60856e9b7a0c5fc6db --- /dev/null +++ b/engine/flutter/shell/platform/ohos/ohos_surface_gl.h @@ -0,0 +1,83 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// 2021.4.30 platform view adapt ohos. +// Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + +#ifndef FLUTTER_SHELL_PLATFORM_OHOS_OHOS_SURFACE_GL_H_ +#define FLUTTER_SHELL_PLATFORM_OHOS_OHOS_SURFACE_GL_H_ + +#include + +#include "flutter/fml/macros.h" +#include "flutter/shell/gpu/gpu_surface_gl.h" +#include "flutter/shell/platform/ohos/ohos_surface.h" + +#include "egl_surface.h" + +namespace flutter { +class OhosSurfaceGL final : public GPUSurfaceGLDelegate, public OhosSurface { +public: + OhosSurfaceGL(); + + ~OhosSurfaceGL() override = default; + + // |OhosSurface| + bool IsValid() const override; + + // |OhosSurface| + std::unique_ptr CreateGPUSurface() override; + + // |OhosSurface| + void SetPlatformWindow(const ::OHOS::sptr& window) override; + + // |OhosSurface| + bool OnScreenSurfaceResize(const SkISize& size) override; + + // |OhosSurface| + void TeardownOnScreenContext() override; + + // |OhosSurface| + bool ResourceContextMakeCurrent() override; + + // |OhosSurface| + bool ResourceContextClearCurrent() override; + + // |GPUSurfaceGLDelegate| + bool GLContextPresent() override; + + // |GPUSurfaceGLDelegate| + intptr_t GLContextFBO() const override; + + // |GPUSurfaceGLDelegate| + bool GLContextFBOResetAfterPresent() const override; + + // |GPUSurfaceGLDelegate| + bool UseOffscreenSurface() const override; + + // |GPUSurfaceGLDelegate| + SkMatrix GLContextSurfaceTransformation() const override; + + // |GPUSurfaceGLDelegate| + bool GLContextMakeCurrent() override; + + // |GPUSurfaceGLDelegate| + bool GLContextClearCurrent() override; + + // |GPUSurfaceGLDelegate| + ExternalViewEmbedder* GetExternalViewEmbedder() override; + +private: + OHOS::sptr window_; + OHOS::sptr eglRenderSurface_; + EGLDisplay eglDisplay_; + EGLContext eglContext_; + EGLSurface eglSurface_; + bool valid_ = false; + + bool InitRenderSurface(); + + FML_DISALLOW_COPY_AND_ASSIGN(OhosSurfaceGL); +}; +} // namespace flutter +#endif // FLUTTER_SHELL_PLATFORM_OHOS_OHOS_SURFACE_GL_H_ diff --git a/engine/flutter/shell/platform/ohos/ohos_surface_software.cc b/engine/flutter/shell/platform/ohos/ohos_surface_software.cc index 1452cd7fcee1e6d4f620348f917be77093c67a57..67ae871a726274ff560c2f099f0b573ca8e0a1f0 100644 --- a/engine/flutter/shell/platform/ohos/ohos_surface_software.cc +++ b/engine/flutter/shell/platform/ohos/ohos_surface_software.cc @@ -41,6 +41,7 @@ bool GetSkColorType(int32_t buffer_format, OhosSurfaceSoftware::OhosSurfaceSoftware() { + FML_LOG(ERROR) << "OhosSurfaceSoftware Constructor"; GetSkColorType(PIXEL_FMT_RGBA_8888, &target_color_type_, &target_alpha_type_); } @@ -202,4 +203,22 @@ ExternalViewEmbedder* OhosSurfaceSoftware::GetExternalViewEmbedder() { return nullptr; } + +bool OhosSurfaceSoftware::ResourceContextMakeCurrent() +{ + // implement in ohos surface gl + return false; +} + +bool OhosSurfaceSoftware::ResourceContextClearCurrent() +{ + // implement in ohos surface gl + return false; +} + +void OhosSurfaceSoftware::TeardownOnScreenContext() +{ + // implement in ohos surface gl +} + } // namespace flutter diff --git a/engine/flutter/shell/platform/ohos/ohos_surface_software.h b/engine/flutter/shell/platform/ohos/ohos_surface_software.h index 89fa1fbc8c2a1d2fcf150f34fbab34be09ead410..059c4c0ed3ad5736d6775c41b6aa573a9957a3a3 100644 --- a/engine/flutter/shell/platform/ohos/ohos_surface_software.h +++ b/engine/flutter/shell/platform/ohos/ohos_surface_software.h @@ -38,6 +38,15 @@ public: ExternalViewEmbedder* GetExternalViewEmbedder() override; + // |OhosSurface| + virtual bool ResourceContextMakeCurrent() override; + + // |OhosSurface| + virtual bool ResourceContextClearCurrent() override; + + // |OhosSurface| + virtual void TeardownOnScreenContext() override; + private: sk_sp sk_surface_; SkColorType target_color_type_; diff --git a/engine/flutter/shell/platform/ohos/platform_view_ohos.cc b/engine/flutter/shell/platform/ohos/platform_view_ohos.cc index 862e1a251cb9c410767b97a7ea172eb08f7068b6..58b4ad56723f796f3ac4521638c1734e064c6c25 100644 --- a/engine/flutter/shell/platform/ohos/platform_view_ohos.cc +++ b/engine/flutter/shell/platform/ohos/platform_view_ohos.cc @@ -6,10 +6,10 @@ #include "flutter/shell/platform/ohos/platform_view_ohos.h" -#include -#include - #include "flutter/common/settings.h" +#ifndef GPU_DISABLED +#include "flutter/shell/platform/ohos/ohos_surface_gl.h" +#endif #include "flutter/shell/platform/ohos/ohos_surface_software.h" #include "flutter/shell/platform/ohos/vsync_waiter_embedder.h" @@ -21,15 +21,28 @@ PlatformViewOhos::PlatformViewOhos( bool use_software_rendering) : PlatformView(delegate, std::move(task_runners)) { - if (use_software_rendering) { - surface_ = std::make_unique(); - } +#ifndef GPU_DISABLED + surface_ = std::make_shared(); +#else + surface_ = std::make_shared(); +#endif } void PlatformViewOhos::NotifyCreated(const ::OHOS::sptr<::OHOS::Window> &window) { if (surface_) { +#ifndef GPU_DISABLED + fml::AutoResetWaitableEvent latch; + fml::TaskRunner::RunNowOrPostTask( + task_runners_.GetGPUTaskRunner(), + [&latch, surface = surface_.get(), &window]() mutable { + surface->SetPlatformWindow(window); + latch.Signal(); + }); + latch.Wait(); +#else surface_->SetPlatformWindow(window); +#endif } PlatformView::NotifyCreated(); @@ -38,7 +51,18 @@ void PlatformViewOhos::NotifyCreated(const ::OHOS::sptr<::OHOS::Window> &window) void PlatformViewOhos::NotifyChanged(const SkISize& size) { if (surface_) { +#ifndef GPU_DISABLED + fml::AutoResetWaitableEvent latch; + fml::TaskRunner::RunNowOrPostTask( + task_runners_.GetGPUTaskRunner(), + [&latch, surface = surface_.get(), &size]() mutable { + surface->OnScreenSurfaceResize(size); + latch.Signal(); + }); + latch.Wait(); +#else surface_->OnScreenSurfaceResize(size); +#endif } } diff --git a/engine/flutter/shell/platform/ohos/platform_view_ohos.h b/engine/flutter/shell/platform/ohos/platform_view_ohos.h index 1db430537c059eb93ab351a3b4af7ea35e60aeac..65983ae69a2fe42953db461cf348c96364ea58e6 100644 --- a/engine/flutter/shell/platform/ohos/platform_view_ohos.h +++ b/engine/flutter/shell/platform/ohos/platform_view_ohos.h @@ -22,7 +22,7 @@ public: std::unique_ptr CreateVSyncWaiter(int32_t platform); private: - std::unique_ptr surface_; + std::shared_ptr surface_; FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewOhos); };