!2288 enable image upload to gpu

Merge pull request !2288 from 何溯/dev
This commit is contained in:
openharmony_ci
2022-04-22 10:04:05 +00:00
committed by Gitee
11 changed files with 208 additions and 39 deletions
+4
View File
@@ -87,6 +87,10 @@ if (disable_gpu || enable_rosen_backend) {
defines += [ "GPU_DISABLED" ]
}
if (disable_gpu) {
defines += [ "UPLOAD_GPU_DISABLED" ]
}
if (form_components_support) {
defines += [ "FORM_SUPPORTED" ]
}
+4 -1
View File
@@ -52,7 +52,10 @@ template("ace_ohos_standard_source_set") {
configs = [ "$ace_root:ace_config" ]
if (defined(config.enable_rosen_backend) && config.enable_rosen_backend) {
configs += [ "//foundation/graphic/standard/rosen/modules/render_service_client:render_service_client_config" ]
configs += [
"//foundation/graphic/standard/rosen/modules/render_service_base:export_config",
"//foundation/graphic/standard/rosen/modules/render_service_client:render_service_client_config",
]
}
include_dirs = [
+20 -16
View File
@@ -184,6 +184,13 @@ void AceAbility::OnStart(const Want& want)
ImageCache::SetCacheFileInfo();
});
OHOS::sptr<OHOS::Rosen::Window> window = Ability::GetWindow();
std::shared_ptr<OHOS::Rosen::RSUIDirector> rsUiDirector;
if (SystemProperties::GetRosenBackendEnabled()) {
rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
rsUiDirector->SetRSSurfaceNode(window->GetSurfaceNode());
rsUiDirector->Init();
}
// register surface change callback and window mode change callback
OHOS::sptr<OHOS::Rosen::IWindowChangeListener> thisAbility(this);
window->RegisterWindowChangeListener(thisAbility);
@@ -330,23 +337,20 @@ void AceAbility::OnStart(const Want& want)
Ace::Platform::UIEnvCallback callback = nullptr;
#ifdef ENABLE_ROSEN_BACKEND
callback = [window, id = abilityId_](const OHOS::Ace::RefPtr<OHOS::Ace::PipelineContext>& context) mutable {
if (SystemProperties::GetRosenBackendEnabled()) {
auto rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
if (rsUiDirector != nullptr) {
rsUiDirector->SetRSSurfaceNode(window->GetSurfaceNode());
rsUiDirector->SetUITaskRunner(
[taskExecutor = Platform::AceContainer::GetContainer(id)->GetTaskExecutor(), id](
const std::function<void()>& task) {
ContainerScope scope(id);
taskExecutor->PostTask(task, TaskExecutor::TaskType::UI);
});
if (context != nullptr) {
context->SetRSUIDirector(rsUiDirector);
}
rsUiDirector->Init();
LOGI("Init Rosen Backend");
callback = [window, id = abilityId_, flutterAceView, rsUiDirector](
const OHOS::Ace::RefPtr<OHOS::Ace::PipelineContext>& context) mutable {
if (rsUiDirector) {
rsUiDirector->SetUITaskRunner(
[taskExecutor = Platform::AceContainer::GetContainer(id)->GetTaskExecutor(), id](
const std::function<void()>& task) {
ContainerScope scope(id);
taskExecutor->PostTask(task, TaskExecutor::TaskType::UI);
});
if (context != nullptr) {
context->SetRSUIDirector(rsUiDirector);
}
flutterAceView->InitIOManager(Platform::AceContainer::GetContainer(id)->GetTaskExecutor());
LOGI("Init Rosen Backend");
} else {
LOGI("not Init Rosen Backend");
}
+60
View File
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_ACE_ADAPTER_OHOS_CPP_ACE_ROSEN_SYNC_TASK_H
#define FOUNDATION_ACE_ADAPTER_OHOS_CPP_ACE_ROSEN_SYNC_TASK_H
#include "render_service_client/core/ui/rs_ui_director.h"
#include "transaction/rs_transaction_proxy.h"
namespace OHOS::Ace::Platform {
class AceRosenSyncTask : public Rosen::RSSyncTask {
public:
explicit AceRosenSyncTask(std::function<void()>&& task, unsigned long long timeoutNS = 50e6)
: Rosen::RSSyncTask(timeoutNS), task_(std::move(task))
{}
virtual ~AceRosenSyncTask() = default;
#ifdef ROSEN_OHOS
bool CheckHeader(Parcel& parcel) const override
{
return true;
}
bool ReadFromParcel(Parcel& parcel) override
{
return true;
}
bool Marshalling(Parcel& parcel) const override
{
return true;
}
#endif // ROSEN_OHOS
void Process(Rosen::RSContext& context) override
{
if (task_) {
task_();
}
}
private:
std::function<void()> task_;
};
} // namespace OHOS::Ace::Platform
#endif // FOUNDATION_ACE_ADAPTER_OHOS_CPP_ACE_ROSEN_SYNC_TASK_H
@@ -15,12 +15,21 @@
#include "adapter/ohos/entrance/flutter_ace_view.h"
#include <EGL/egl.h>
#include <algorithm>
#include <fstream>
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/shell/common/shell_io_manager.h"
#include "flutter/shell/gpu/gpu_surface_gl_delegate.h"
#include "key_event.h"
#include "pointer_event.h"
#if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
#include "adapter/ohos/entrance/ace_rosen_sync_task.h"
#endif
#include "base/log/ace_trace.h"
#include "base/log/dump_log.h"
#include "base/log/event_report.h"
#include "base/log/log.h"
@@ -700,4 +709,82 @@ std::unique_ptr<PlatformWindow> FlutterAceView::GetPlatformWindow()
return nullptr;
}
void FlutterAceView::InitIOManager(RefPtr<TaskExecutor> taskExecutor)
{
#if defined(ENABLE_ROSEN_BACKEND) and !defined(UPLOAD_GPU_DISABLED)
ACE_SCOPED_TRACE("InitIOManager");
EGLContext shareContext = nullptr;
EGLSurface surface = nullptr;
auto callback = [&shareContext, &surface]() {
ACE_SCOPED_TRACE("create egl ");
EGLContext context = eglGetCurrentContext();
if (context == EGL_NO_CONTEXT) {
LOGE("eglGetCurrentContext failed errorCode = [%{public}d]", eglGetError());
return;
}
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (display == EGL_NO_DISPLAY) {
LOGE("eglGetDisplay failed errorCode = [%{public}d]", eglGetError());
return;
}
EGLint attributes[] = {
// clang-format off
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_NONE, // termination sentinel
// clang-format on
};
EGLint config_count = 0;
EGLConfig egl_config = nullptr;
if (eglChooseConfig(display, attributes, &egl_config, 1, &config_count) != EGL_TRUE) {
LOGE("Get EGLConfig failed errorCode = [%{public}d]", eglGetError());
return;
}
EGLint contextAttr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
shareContext = eglCreateContext(display, egl_config, context, contextAttr);
if (shareContext == EGL_NO_CONTEXT) {
LOGE("eglCreateContext failed errorCode = [%{public}d]", eglGetError());
return;
}
const EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
surface = eglCreatePbufferSurface(display, egl_config, attribs);
if (surface == EGL_NO_SURFACE) {
LOGE("eglCreatePbufferSurface failed errorCode = [%{public}d]", eglGetError());
return;
}
LOGI("create egl success");
};
auto task = std::make_shared<AceRosenSyncTask>(std::move(callback));
Rosen::RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(task);
if (shareContext == EGL_NO_CONTEXT || surface == EGL_NO_SURFACE) {
LOGW("create egl env failed, image should not upload to gpu.");
return;
}
auto state = flutter::UIDartState::Current()->GetStateById(instanceId_);
if (state == nullptr) {
LOGE("state is nullptr");
return;
}
fml::WeakPtr<flutter::ShellIOManager> ioManager = state->GetIOManager();
taskExecutor->PostSyncTask(
[surface, shareContext, ioManager]() {
ACE_SCOPED_TRACE("create resource_context ");
if (eglMakeCurrent(eglGetDisplay(EGL_DEFAULT_DISPLAY), surface, surface, shareContext) == EGL_TRUE) {
sk_sp<GrContext> resource_context = flutter::ShellIOManager::CreateCompatibleResourceLoadingContext(
GrBackend::kOpenGL_GrBackend, flutter::GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface());
ioManager->NotifyResourceContextAvailable(resource_context);
}
},
TaskExecutor::TaskType::IO);
#endif
}
} // namespace OHOS::Ace::Platform
+2
View File
@@ -131,6 +131,8 @@ public:
bool Dump(const std::vector<std::string>& params) override;
const void* GetNativeWindowById(uint64_t textureId) override;
void InitIOManager(RefPtr<TaskExecutor> taskExecutor);
private:
void NotifySurfaceChanged(int width, int height, WindowSizeChangeReason type)
{
+14 -7
View File
@@ -39,6 +39,7 @@
#include "adapter/ohos/entrance/plugin_utils_impl.h"
#include "base/geometry/rect.h"
#include "base/log/log.h"
#include "base/log/ace_trace.h"
#include "base/subwindow/subwindow_manager.h"
#include "base/utils/system_properties.h"
#include "core/common/ace_engine.h"
@@ -238,6 +239,7 @@ std::string UIContentImpl::GetContentInfo() const
void UIContentImpl::CommonInitialize(OHOS::Rosen::Window* window, const std::string& contentInfo, NativeValue* storage)
{
ACE_FUNCTION_TRACE();
window_ = window;
startUrl_ = contentInfo;
if (!window_) {
@@ -267,6 +269,13 @@ void UIContentImpl::CommonInitialize(OHOS::Rosen::Window* window, const std::str
ImageCache::SetCacheFileInfo();
});
std::shared_ptr<OHOS::Rosen::RSUIDirector> rsUiDirector;
if (SystemProperties::GetRosenBackendEnabled()) {
rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
rsUiDirector->SetRSSurfaceNode(window->GetSurfaceNode());
rsUiDirector->Init();
}
int32_t deviceWidth = 0;
int32_t deviceHeight = 0;
float density = 1.0f;
@@ -477,11 +486,10 @@ void UIContentImpl::CommonInitialize(OHOS::Rosen::Window* window, const std::str
Ace::Platform::UIEnvCallback callback = nullptr;
#ifdef ENABLE_ROSEN_BACKEND
callback = [window, id = instanceId_, container](const OHOS::Ace::RefPtr<OHOS::Ace::PipelineContext>& context) {
if (SystemProperties::GetRosenBackendEnabled()) {
auto rsUiDirector = OHOS::Rosen::RSUIDirector::Create();
if (rsUiDirector != nullptr) {
rsUiDirector->SetRSSurfaceNode(window->GetSurfaceNode());
callback = [window, id = instanceId_, container, flutterAceView, rsUiDirector](
const OHOS::Ace::RefPtr<OHOS::Ace::PipelineContext>& context) {
if (rsUiDirector) {
ACE_SCOPED_TRACE("OHOS::Rosen::RSUIDirector::Create()");
rsUiDirector->SetUITaskRunner(
[taskExecutor = container->GetTaskExecutor(), id](const std::function<void()>& task) {
ContainerScope scope(id);
@@ -491,9 +499,8 @@ void UIContentImpl::CommonInitialize(OHOS::Rosen::Window* window, const std::str
if (context != nullptr) {
context->SetRSUIDirector(rsUiDirector);
}
rsUiDirector->Init();
flutterAceView->InitIOManager(container->GetTaskExecutor());
LOGI("UIContent Init Rosen Backend");
}
}
};
#endif
@@ -234,7 +234,7 @@ void RosenRenderImage::ImageDataPaintSuccess(const fml::RefPtr<flutter::CanvasIm
return;
}
UpdateLoadSuccessState();
image_ = image->image();
image_ = image;
skiaDom_ = nullptr;
svgDom_ = nullptr;
if (imageDataNotReady_) {
@@ -453,7 +453,9 @@ void RosenRenderImage::ProcessPixmapForPaint()
skImage = SkImage::MakeFromRaster(imagePixmap, nullptr, nullptr);
#endif
}
image_ = std::move(skImage);
auto canvasImage = flutter::CanvasImage::Create();
canvasImage->set_image(flutter::SkiaGPUObject<SkImage>(skImage, renderTaskHolder_->unrefQueue));
image_ = canvasImage;
if (!VerifySkImageDataFromPixmap(pixmap)) {
LOGE("pixmap paint failed due to SkImage data verification fail. rawImageSize: %{public}s",
rawImageSize_.ToString().c_str());
@@ -601,7 +603,7 @@ void RosenRenderImage::Paint(RenderContext& context, const Offset& offset)
ApplyInterpolation(paint);
sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
if (image_) {
colorSpace = image_->refColorSpace();
colorSpace = image_->image()->refColorSpace();
}
#ifdef USE_SYSTEM_SKIA
paint.setColor4f(paint.getColor4f(), colorSpace.get());
@@ -697,7 +699,7 @@ void RosenRenderImage::CanvasDrawImageRect(
if (GetBackgroundImageFlag()) {
return;
}
if (!image_) {
if (!image_ || !image_->image()) {
imageDataNotReady_ = true;
LOGI("image data is not ready, rawImageSize_: %{public}s, image source: %{private}s",
rawImageSize_.ToString().c_str(), sourceInfo_.ToString().c_str());
@@ -711,7 +713,7 @@ void RosenRenderImage::CanvasDrawImageRect(
if (GetAdaptiveFrameRectFlag()) {
recordingCanvas->translate(imageRenderPosition_.GetX() * -1, imageRenderPosition_.GetY() * -1);
Rosen::RsImageInfo rsImageInfo(fitNum, repeatNum, radius, scale_);
recordingCanvas->DrawImageWithParm(image_, rsImageInfo, paint);
recordingCanvas->DrawImageWithParm(image_->image(), rsImageInfo, paint);
return;
}
bool isLoading = ((imageLoadingStatus_ == ImageLoadingStatus::LOADING) ||
@@ -738,7 +740,7 @@ void RosenRenderImage::CanvasDrawImageRect(
SkRect::MakeXYWH(realDstRect.Left() - imageRenderPosition_.GetX(),
realDstRect.Top() - imageRenderPosition_.GetY(),
realDstRect.Width(), realDstRect.Height());
canvas->drawImageRect(image_, skSrcRect, skDstRect, &paint);
canvas->drawImageRect(image_->image(), skSrcRect, skDstRect, &paint);
LOGD("dstRect params: %{public}s", realDstRect.ToString().c_str());
LOGD("scaledSrcRect params: %{public}s", scaledSrcRect.ToString().c_str());
#endif
@@ -779,14 +781,14 @@ void RosenRenderImage::DrawImageOnCanvas(const Rect& srcRect, const Rect& dstRec
recordingCanvas->save();
recordingCanvas->concat(sampleMatrix);
recordingCanvas->drawImageRect(image_, skSrcRect, skDstRect, &paint, SkCanvas::kFast_SrcRectConstraint);
recordingCanvas->drawImageRect(image_->image(), skSrcRect, skDstRect, &paint, SkCanvas::kFast_SrcRectConstraint);
recordingCanvas->restore();
#endif
}
bool RosenRenderImage::VerifySkImageDataFromPixmap(const RefPtr<PixelMap>& pixmap) const
{
if (!image_) {
if (!image_ || !image_->image()) {
LOGE("image data made from pixmap is null");
return false;
}
@@ -818,7 +820,7 @@ void RosenRenderImage::PaintBgImage(const std::shared_ptr<RSNode>& rsNode)
if (!GetBackgroundImageFlag()) {
return;
}
if (currentDstRectList_.empty() || !image_) {
if (currentDstRectList_.empty() || !image_ || !image_->image()) {
return;
}
@@ -827,7 +829,7 @@ void RosenRenderImage::PaintBgImage(const std::shared_ptr<RSNode>& rsNode)
}
#ifdef OHOS_PLATFORM
auto rosenImage = std::make_shared<Rosen::RSImage>();
rosenImage->SetImage(image_);
rosenImage->SetImage(image_->image());
rosenImage->SetImageRepeat(static_cast<int>(imageRepeat_));
rsNode->SetBgImageWidth(imageRenderSize_.Width());
rsNode->SetBgImageHeight(imageRenderSize_.Height());
@@ -1164,10 +1166,10 @@ void RosenRenderImage::ClearRenderObject()
bool RosenRenderImage::IsSourceWideGamut() const
{
if (sourceInfo_.IsSvg() || !image_) {
if (sourceInfo_.IsSvg() || !image_ || !image_->image()) {
return false;
}
return ImageProvider::IsWideGamut(image_->refColorSpace());
return ImageProvider::IsWideGamut(image_->image()->refColorSpace());
}
bool RosenRenderImage::RetryLoading()
@@ -120,7 +120,7 @@ private:
sk_sp<SkSVGDOM> skiaDom_;
RefPtr<SvgDom> svgDom_;
sk_sp<SkImage> image_;
fml::RefPtr<flutter::CanvasImage> image_;
bool loadSvgAfterLayout_ = false;
bool loadSvgOnPaint_ = false; // only load svg trees without box and bind
SkVector radii_[4] = { { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 } };
+1 -1
View File
@@ -260,7 +260,7 @@ void ImageProvider::UploadImageToGPUForRender(
LOGW("renderTaskHolder has been released.");
return;
}
#if defined(DUMP_DRAW_CMD) || defined(GPU_DISABLED)
#ifdef UPLOAD_GPU_DISABLED
// If want to dump draw command or gpu disabled, should use CPU image.
callback({ image, renderTaskHolder->unrefQueue });
#else
@@ -199,13 +199,13 @@ void PipelineContext::FlushPipelineWithoutAnimation()
FlushPostAnimation();
FlushLayout();
FlushRender();
FlushMessages();
FlushRenderFinish();
FlushWindowBlur();
FlushFocus();
FireVisibleChangeEvent();
ProcessPostFlush();
ClearDeactivateElements();
FlushMessages();
}
void PipelineContext::FlushMessages()