mirror of
https://gitee.com/openharmony/graphic_graphic_2d
synced 2025-02-17 02:20:59 +00:00
merge conflict fix Signed-off-by: s30029175 <shiqiwei4@huawei.com>
Signed-off-by: sqwlly <shiqiwei4@huawei.com> Change-Id: Ic2d66bc32e9b39d357ba3242b433544248f1918c
This commit is contained in:
commit
3daa68cc77
14
.gitee/CODEOWNERS
Normal file
14
.gitee/CODEOWNERS
Normal file
@ -0,0 +1,14 @@
|
||||
# Code owners for graphic_2d
|
||||
[graphic_2d base]
|
||||
.gitee/CODEOWNERS @lijj01
|
||||
bundle.json @lijj01
|
||||
|
||||
[cross-platform]
|
||||
rosen/modules/glfw_render_context/ @aslklw
|
||||
|
||||
[drawing]
|
||||
rosen/modules/2d_graphics/BUILD.gn @ustc-tianyu
|
||||
rosen/modules/2d_graphics/include/ @ustc-tianyu
|
||||
rosen/modules/2d_graphics/src/drawing/ @ustc-tianyu
|
||||
rosen/modules/2d_graphics/drawing_ndk/ @ustc-tianyu
|
||||
interfaces/kits/napi/graphic/drawing/ @ustc-tianyu
|
@ -80,7 +80,6 @@
|
||||
"accessibility",
|
||||
"frame_aware_sched",
|
||||
"memmgr",
|
||||
"memmgr_override",
|
||||
"sensor",
|
||||
"qos_manager",
|
||||
"video_processing_engine",
|
||||
@ -90,8 +89,6 @@
|
||||
"node",
|
||||
"vulkan-headers",
|
||||
"vulkan-loader",
|
||||
"hiview",
|
||||
"battery_manager",
|
||||
"cJSON",
|
||||
"jsoncpp",
|
||||
"openssl",
|
||||
@ -450,7 +447,7 @@
|
||||
],
|
||||
"test": [
|
||||
"//foundation/graphic/graphic_2d:graphic_common_test",
|
||||
"//foundation/graphic/graphic_2d/frameworks/surfaceimage/test/unittest/:unittest",
|
||||
"//foundation/graphic/graphic_2d/frameworks/surfaceimage/test/unittest:unittest",
|
||||
"//foundation/graphic/graphic_2d/rosen/modules/render_service_client:test",
|
||||
"//foundation/graphic/graphic_2d/rosen/test/2d_graphics:test",
|
||||
"//foundation/graphic/graphic_2d/rosen/modules/animation/window_animation/test:test",
|
||||
|
@ -19,3 +19,4 @@ persist.rosen.sethgmrefreshratemode.enabled = graphics:graphics:0775
|
||||
persist.graphic.bootsound.enabled = graphics:servicectrl:0775
|
||||
rosen.dirtyregiondebug.enabled = graphics:servicectrl:0775
|
||||
rosen.drawingCache.enabledDfx = graphics:servicectrl:0775
|
||||
bootevent.renderservice.ready = graphics:graphics:0777
|
||||
|
@ -25,28 +25,64 @@ group("unittest") {
|
||||
ohos_unittest("bootanimation_test") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
sources = [ "bootanimation_utils_test.cpp" ]
|
||||
sources = [
|
||||
"$graphic_2d_root/frameworks/bootanimation/src/boot_animation_controller.cpp",
|
||||
"$graphic_2d_root/frameworks/bootanimation/src/boot_animation_operation.cpp",
|
||||
"$graphic_2d_root/frameworks/bootanimation/src/boot_animation_strategy.cpp",
|
||||
"$graphic_2d_root/frameworks/bootanimation/src/boot_picture_player.cpp",
|
||||
"$graphic_2d_root/frameworks/bootanimation/src/boot_sound_player.cpp",
|
||||
"$graphic_2d_root/frameworks/bootanimation/src/boot_video_player.cpp",
|
||||
"$graphic_2d_root/frameworks/bootanimation/src/util.cpp",
|
||||
"boot_animation_controller_test.cpp",
|
||||
"boot_animation_operation_test.cpp",
|
||||
"boot_animation_utils_test.cpp",
|
||||
"boot_picture_player_test.cpp",
|
||||
]
|
||||
|
||||
configs = [ ":bootanimation_test_config" ]
|
||||
|
||||
deps = [
|
||||
"$graphic_2d_root:libbootanimation_utils",
|
||||
"$graphic_2d_root/rosen/modules/2d_graphics:2d_graphics",
|
||||
"$graphic_2d_root/rosen/modules/composer:libcomposer",
|
||||
"$graphic_2d_root/rosen/modules/render_service:librender_service",
|
||||
"$graphic_2d_root/rosen/modules/render_service_base/src/platform:platform",
|
||||
"$graphic_2d_root/rosen/modules/render_service_client:librender_service_client",
|
||||
"//third_party/googletest:gtest_main",
|
||||
]
|
||||
|
||||
if (defined(use_new_render_context) && use_new_render_context) {
|
||||
deps += [ "$graphic_2d_root/rosen/modules/render_service_base/src/render_backend:librender_backend" ]
|
||||
}
|
||||
|
||||
external_deps = [
|
||||
"cJSON:cjson_static",
|
||||
"c_utils:utils",
|
||||
"hilog:libhilog",
|
||||
"config_policy:configpolicy_util",
|
||||
"init:libbegetutil",
|
||||
"zlib:libz",
|
||||
]
|
||||
|
||||
if (player_framework_enable) {
|
||||
external_deps += [ "player_framework:media_client" ]
|
||||
}
|
||||
|
||||
if (is_standard_system) {
|
||||
external_deps += [ "init:libbegetutil" ]
|
||||
} else {
|
||||
external_deps += [ "startup:syspara" ]
|
||||
}
|
||||
|
||||
subsystem_name = "graphic"
|
||||
part_name = "graphic_2d"
|
||||
}
|
||||
|
||||
config("bootanimation_test_config") {
|
||||
visibility = [ ":*" ]
|
||||
include_dirs = []
|
||||
include_dirs = [
|
||||
"$graphic_2d_root/frameworks/bootanimation/include",
|
||||
"$graphic_2d_root/interfaces/inner_api/bootanimation",
|
||||
]
|
||||
|
||||
cflags = [
|
||||
"-Wall",
|
||||
@ -55,4 +91,14 @@ config("bootanimation_test_config") {
|
||||
"-Dprivate=public",
|
||||
"-Dprotected=public",
|
||||
]
|
||||
|
||||
defines = []
|
||||
defines += gpu_defines
|
||||
if (player_framework_enable) {
|
||||
defines += [ "PLAYER_FRAMEWORK_ENABLE" ]
|
||||
}
|
||||
|
||||
if (defined(use_rosen_drawing) && use_rosen_drawing) {
|
||||
defines += [ "USE_ROSEN_DRAWING" ]
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "boot_animation_controller.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
class BootAnimationControllerTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase();
|
||||
static void TearDownTestCase();
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
};
|
||||
|
||||
void BootAnimationControllerTest::SetUpTestCase() {}
|
||||
void BootAnimationControllerTest::TearDownTestCase() {}
|
||||
void BootAnimationControllerTest::SetUp() {}
|
||||
void BootAnimationControllerTest::TearDown() {}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationControllerTest_001
|
||||
* @tc.desc: Verify the CreateDefaultBootConfig
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationControllerTest, BootAnimationControllerTest_001, TestSize.Level1)
|
||||
{
|
||||
BootAnimationController controller;
|
||||
controller.CreateDefaultBootConfig();
|
||||
EXPECT_EQ(1, controller.animationConfigs_.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationControllerTest_002
|
||||
* @tc.desc: Verify the GetBootType
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationControllerTest, BootAnimationControllerTest_002, TestSize.Level1)
|
||||
{
|
||||
BootAnimationController controller;
|
||||
controller.isCompatible_ = true;
|
||||
BootStrategyType type = controller.GetBootType();
|
||||
EXPECT_EQ(type, BootStrategyType::COMPATIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationControllerTest_003
|
||||
* @tc.desc: Verify the GetBootType
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationControllerTest, BootAnimationControllerTest_003, TestSize.Level1)
|
||||
{
|
||||
BootAnimationController controller;
|
||||
controller.isCompatible_ = true;
|
||||
BootStrategyType type = controller.GetBootType();
|
||||
EXPECT_EQ(type, BootStrategyType::COMPATIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationControllerTest_004
|
||||
* @tc.desc: Verify the GetBootType
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationControllerTest, BootAnimationControllerTest_004, TestSize.Level1)
|
||||
{
|
||||
BootAnimationController controller;
|
||||
controller.isMultiDisplay_ = true;
|
||||
BootStrategyType type = controller.GetBootType();
|
||||
EXPECT_EQ(type, BootStrategyType::INDEPENDENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationControllerTest_005
|
||||
* @tc.desc: Verify the GetBootType
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationControllerTest, BootAnimationControllerTest_005, TestSize.Level1)
|
||||
{
|
||||
BootAnimationController controller;
|
||||
BootAnimationConfig config;
|
||||
controller.animationConfigs_.emplace_back(config);
|
||||
BootStrategyType type = controller.GetBootType();
|
||||
EXPECT_EQ(type, BootStrategyType::INDEPENDENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationControllerTest_006
|
||||
* @tc.desc: Verify the GetBootType
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationControllerTest, BootAnimationControllerTest_006, TestSize.Level1)
|
||||
{
|
||||
BootAnimationController controller;
|
||||
BootAnimationConfig first_config;
|
||||
controller.animationConfigs_.emplace_back(first_config);
|
||||
BootAnimationConfig second_config;
|
||||
controller.animationConfigs_.emplace_back(second_config);
|
||||
BootStrategyType type = controller.GetBootType();
|
||||
EXPECT_EQ(type, BootStrategyType::ASSOCIATIVE);
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "boot_animation_operation.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
class BootAnimationOperationTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase();
|
||||
static void TearDownTestCase();
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
};
|
||||
|
||||
void BootAnimationOperationTest::SetUpTestCase() {}
|
||||
void BootAnimationOperationTest::TearDownTestCase() {}
|
||||
void BootAnimationOperationTest::SetUp() {}
|
||||
void BootAnimationOperationTest::TearDown() {}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationOperationTest_001
|
||||
* @tc.desc: Verify the SetSoundEnable
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationOperationTest, BootAnimationOperationTest_001, TestSize.Level1)
|
||||
{
|
||||
BootAnimationOperation operation;
|
||||
operation.SetSoundEnable(true);
|
||||
EXPECT_EQ(operation.isSoundEnabled_, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationOperationTest_002
|
||||
* @tc.desc: Verify the SetSoundEnable
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationOperationTest, BootAnimationOperationTest_002, TestSize.Level1)
|
||||
{
|
||||
BootAnimationOperation operation;
|
||||
operation.SetSoundEnable(false);
|
||||
EXPECT_EQ(operation.isSoundEnabled_, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationOperationTest_003
|
||||
* @tc.desc: Verify the InitRsDisplayNode
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationOperationTest, BootAnimationOperationTest_003, TestSize.Level1)
|
||||
{
|
||||
BootAnimationOperation operation;
|
||||
operation.InitRsDisplayNode();
|
||||
ASSERT_NE(nullptr, operation.rsDisplayNode_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationOperationTest_004
|
||||
* @tc.desc: Verify the InitRsSurfaceNode
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationOperationTest, BootAnimationOperationTest_004, TestSize.Level1)
|
||||
{
|
||||
BootAnimationOperation operation;
|
||||
int32_t degree = 0;
|
||||
operation.InitRsSurfaceNode(degree);
|
||||
ASSERT_NE(nullptr, operation.rsSurfaceNode_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationOperationTest_005
|
||||
* @tc.desc: Verify the InitRsSurface
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationOperationTest, BootAnimationOperationTest_005, TestSize.Level1)
|
||||
{
|
||||
BootAnimationOperation operation;
|
||||
int32_t degree = 0;
|
||||
operation.InitRsSurfaceNode(degree);
|
||||
operation.InitRsSurface();
|
||||
ASSERT_NE(nullptr, operation.rsSurface_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationOperationTest_006
|
||||
* @tc.desc: Verify the IsBootVideoEnabled
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationOperationTest, BootAnimationOperationTest_006, TestSize.Level1)
|
||||
{
|
||||
BootAnimationOperation operation;
|
||||
BootAnimationConfig config;
|
||||
config.picZipPath = "abc";
|
||||
EXPECT_EQ(false, operation.IsBootVideoEnabled(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootAnimationOperationTest_007
|
||||
* @tc.desc: Verify the IsBootVideoEnabled
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootAnimationOperationTest, BootAnimationOperationTest_007, TestSize.Level1)
|
||||
{
|
||||
BootAnimationOperation operation;
|
||||
BootAnimationConfig config;
|
||||
config.videoDefaultPath = "abc";
|
||||
EXPECT_EQ(true, operation.IsBootVideoEnabled(config));
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "boot_animation_utils.h"
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "boot_picture_player.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
class BootPicturePlayerTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase();
|
||||
static void TearDownTestCase();
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
};
|
||||
|
||||
void BootPicturePlayerTest::SetUpTestCase() {}
|
||||
void BootPicturePlayerTest::TearDownTestCase() {}
|
||||
void BootPicturePlayerTest::SetUp() {}
|
||||
void BootPicturePlayerTest::TearDown() {}
|
||||
|
||||
/**
|
||||
* @tc.name: BootPicturePlayerTest_001
|
||||
* @tc.desc: Verify the ReadPicZipFile
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootPicturePlayerTest, BootPicturePlayerTest_001, TestSize.Level1)
|
||||
{
|
||||
PlayerParams params;
|
||||
std::shared_ptr<BootPicturePlayer> player = std::make_shared<BootPicturePlayer>(params);
|
||||
ImageStructVec imgVec;
|
||||
int32_t freq = 30;
|
||||
EXPECT_EQ(player->ReadPicZipFile(imgVec, freq), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootPicturePlayerTest_002
|
||||
* @tc.desc: Verify the CheckFrameRateValid
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootPicturePlayerTest, BootPicturePlayerTest_002, TestSize.Level1)
|
||||
{
|
||||
PlayerParams params;
|
||||
std::shared_ptr<BootPicturePlayer> player = std::make_shared<BootPicturePlayer>(params);
|
||||
int32_t frameRate = 0;
|
||||
EXPECT_EQ(player->CheckFrameRateValid(frameRate), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: BootPicturePlayerTest_003
|
||||
* @tc.desc: Verify the CheckFrameRateValid
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(BootPicturePlayerTest, BootPicturePlayerTest_003, TestSize.Level1)
|
||||
{
|
||||
PlayerParams params;
|
||||
std::shared_ptr<BootPicturePlayer> player = std::make_shared<BootPicturePlayer>(params);
|
||||
int32_t frameRate = 30;
|
||||
EXPECT_EQ(player->CheckFrameRateValid(frameRate), true);
|
||||
}
|
||||
}
|
@ -105,7 +105,9 @@ if (current_os != "ohos") {
|
||||
if (defined(graphic_2d_ext_configs.vendor_root)) {
|
||||
install_enable = false
|
||||
}
|
||||
|
||||
if (is_emulator) {
|
||||
defines += [ "IS_EMULATOR" ]
|
||||
}
|
||||
output_name = "EGL"
|
||||
output_extension = "so"
|
||||
|
||||
|
@ -393,6 +393,23 @@ EGLBoolean EglQueryContextImpl(EGLDisplay dpy, EGLContext ctx,
|
||||
const char *EglQueryStringImpl(EGLDisplay dpy, EGLint name)
|
||||
{
|
||||
ClearError();
|
||||
#ifdef IS_EMULATOR
|
||||
EGLDisplay actualDpy = EGL_NO_DISPLAY;
|
||||
if (dpy != EGL_NO_DISPLAY) {
|
||||
EglWrapperDisplay *display = ValidateDisplay(dpy);
|
||||
if (!display) {
|
||||
return nullptr;
|
||||
}
|
||||
actualDpy = display->GetEglDisplay();
|
||||
}
|
||||
EglWrapperDispatchTablePtr table = &gWrapperHook;
|
||||
if (table->isLoad && table->egl.eglQueryString) {
|
||||
return table->egl.eglQueryString(actualDpy, name);
|
||||
} else {
|
||||
WLOGE("eglQueryString is not found.");
|
||||
}
|
||||
return nullptr;
|
||||
#else
|
||||
EglWrapperDisplay *display = ValidateDisplay(dpy);
|
||||
if (!display) {
|
||||
return nullptr;
|
||||
@ -410,6 +427,7 @@ const char *EglQueryStringImpl(EGLDisplay dpy, EGLint name)
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
#endif // IS_EMULATOR
|
||||
}
|
||||
|
||||
EGLBoolean EglQuerySurfaceImpl(EGLDisplay dpy, EGLSurface surf,
|
||||
|
@ -29,6 +29,9 @@
|
||||
"uid" : "graphics",
|
||||
"gid" : ["system", "tp_host"],
|
||||
"caps" : ["SYS_NICE"],
|
||||
"bootevents": [
|
||||
"bootevent.renderservice.ready"
|
||||
],
|
||||
"permission" : [
|
||||
"ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT"
|
||||
],
|
||||
|
@ -46,7 +46,7 @@ declare_args() {
|
||||
graphic_2d_feature_use_igraphics_extend_hooks = false
|
||||
graphic_2d_feature_use_aps_igameservice_func = false
|
||||
graphic_2d_feature_enable_chipset_vsync = false
|
||||
graphic_2d_feature_enable_rspipeline = false
|
||||
graphic_2d_feature_enable_rspipeline = true
|
||||
|
||||
if (defined(is_arkui_x) && is_arkui_x) {
|
||||
use_new_render_context = false
|
||||
@ -129,7 +129,8 @@ if (graphic_2d_feature_ace_enable_gpu) {
|
||||
}
|
||||
|
||||
if (graphic_2d_feature_parallel_upload_enable &&
|
||||
graphic_2d_feature_rs_enable_uni_render) {
|
||||
graphic_2d_feature_rs_enable_uni_render &&
|
||||
graphic_2d_feature_product == "phone") {
|
||||
rs_enable_parallel_upload = true
|
||||
gpu_defines += [ "RS_ENABLE_PARALLEL_UPLOAD" ]
|
||||
} else {
|
||||
|
@ -51,6 +51,7 @@ enum GSError {
|
||||
GSERROR_BUFFER_IS_INCACHE = 41208000,
|
||||
GSERROR_BUFFER_QUEUE_FULL = 41209000,
|
||||
GSERROR_BUFFER_NOT_INCACHE = 41210000,
|
||||
GSERROR_CONSUMER_DISCONNECTED = 41211000,
|
||||
|
||||
// 500 INTERNAL ERROR
|
||||
GSERROR_API_FAILED = 50001000,
|
||||
|
@ -148,7 +148,7 @@ napi_value JsTypeface::MakeFromFile(napi_env env, napi_callback_info info)
|
||||
CHECK_PARAM_NUMBER_WITH_OPTIONAL_PARAMS(argv, argc, ARGC_ONE, ARGC_ONE);
|
||||
|
||||
std::string text = "";
|
||||
GET_JSVALUE_PARAM(argc, text);
|
||||
GET_JSVALUE_PARAM(ARGC_ZERO, text);
|
||||
|
||||
auto typeface = new(std::nothrow) JsTypeface(Typeface::MakeFromFile(text.c_str()));
|
||||
|
||||
@ -165,6 +165,10 @@ napi_value JsTypeface::MakeFromFile(napi_env env, napi_callback_info info)
|
||||
ROSEN_LOGE("JsTypeface::MakeFromFile failed to wrap native instance");
|
||||
return nullptr;
|
||||
}
|
||||
napi_property_descriptor resultFuncs[] = {
|
||||
DECLARE_NAPI_FUNCTION("getFamilyName", JsTypeface::GetFamilyName),
|
||||
};
|
||||
napi_define_properties(env, jsObj, sizeof(resultFuncs) / sizeof(resultFuncs[0]), resultFuncs);
|
||||
return jsObj;
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ napi_value ColorPickerNapi::Constructor(napi_env env, napi_callback_info info)
|
||||
IMG_JS_NO_ARGS(env, info, status, thisVar);
|
||||
|
||||
IMG_NAPI_CHECK_RET(IMG_IS_READY(status, thisVar), undefineVar);
|
||||
std::unique_ptr<ColorPickerNapi> pColorPickerNapi = std::make_unique<ColorPickerNapi>();
|
||||
ColorPickerNapi* pColorPickerNapi = new ColorPickerNapi();
|
||||
|
||||
IMG_NAPI_CHECK_RET(IMG_NOT_NULL(pColorPickerNapi), undefineVar);
|
||||
|
||||
@ -179,7 +179,7 @@ napi_value ColorPickerNapi::Constructor(napi_env env, napi_callback_info info)
|
||||
pColorPickerNapi->nativeColorPicker_ = sColorPicker_;
|
||||
|
||||
status = napi_wrap(env, thisVar,
|
||||
reinterpret_cast<void*>(pColorPickerNapi.get()),
|
||||
reinterpret_cast<void*>(pColorPickerNapi),
|
||||
ColorPickerNapi::Destructor,
|
||||
nullptr,
|
||||
nullptr);
|
||||
@ -187,7 +187,6 @@ napi_value ColorPickerNapi::Constructor(napi_env env, napi_callback_info info)
|
||||
undefineVar,
|
||||
EFFECT_LOG_E("Failure wrapping js to native napi"));
|
||||
|
||||
pColorPickerNapi.release();
|
||||
sColorPicker_ = nullptr;
|
||||
|
||||
return thisVar;
|
||||
|
@ -347,7 +347,7 @@ void FilterNapi::GetPixelMapAsyncExecute(napi_env env, void* data)
|
||||
}
|
||||
managerFlag = (*manager).second.load();
|
||||
}
|
||||
|
||||
|
||||
if (!managerFlag) {
|
||||
std::lock_guard<std::mutex> lock2(getPixelMapAsyncExecuteMutex_);
|
||||
ctx->filterNapi->Render(ctx->forceCPU);
|
||||
@ -368,7 +368,7 @@ napi_value FilterNapi::GetPixelMapAsync(napi_env env, napi_callback_info info)
|
||||
{
|
||||
napi_value result = nullptr;
|
||||
napi_get_undefined(env, &result);
|
||||
|
||||
|
||||
size_t argc = 1;
|
||||
napi_value argv[1];
|
||||
napi_status status;
|
||||
@ -385,7 +385,7 @@ napi_value FilterNapi::GetPixelMapAsync(napi_env env, napi_callback_info info)
|
||||
EFFECT_LOG_I("FilterNapi: GetPixelMapAsync parse forceCPU failed");
|
||||
}
|
||||
}
|
||||
ctx->forceCPU = true;
|
||||
ctx->forceCPU = false;
|
||||
|
||||
if (argc >= NUM_1) {
|
||||
if (Media::ImageNapiUtils::getType(env, argv[argc - 1]) == napi_function) {
|
||||
@ -403,8 +403,9 @@ napi_value FilterNapi::GetPixelMapAsync(napi_env env, napi_callback_info info)
|
||||
}
|
||||
|
||||
if (ctx->errorMsg != nullptr) {
|
||||
IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetPixelMapAsyncError", [](napi_env env, void* data) {},
|
||||
GetPixelMapAsyncErrorComplete, ctx, ctx->work);
|
||||
IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetPixelMapAsyncError", [](napi_env env, void* data) {
|
||||
EFFECT_LOG_E("FilterNapi: GetPixelMapAsync fail to extract param");
|
||||
}, GetPixelMapAsyncErrorComplete, ctx, ctx->work);
|
||||
} else {
|
||||
IMG_CREATE_CREATE_ASYNC_WORK(env, status, "GetPixelMapAsync", GetPixelMapAsyncExecute,
|
||||
GetPixelMapAsyncComplete, ctx, ctx->work);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "filter/include/filter.h"
|
||||
#include "filter/include/filter_blur_para.h"
|
||||
#include "filter/include/filter_pixel_stretch_para.h"
|
||||
#include "filter/include/filter_water_ripple_para.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
@ -49,8 +50,11 @@ private:
|
||||
static napi_value CreateFilter(napi_env env, napi_callback_info info);
|
||||
static napi_value SetBlur(napi_env env, napi_callback_info info);
|
||||
static napi_value SetPixelStretch(napi_env env, napi_callback_info info);
|
||||
static napi_value SetWaterRipple(napi_env env, napi_callback_info info);
|
||||
static Drawing::TileMode ParserArgumentType(napi_env env, napi_value argv);
|
||||
|
||||
static float GetSpecialValue(napi_env env, napi_value argValue);
|
||||
|
||||
std::shared_ptr<Filter> m_FilterObj = nullptr;
|
||||
};
|
||||
} // namespace Rosen
|
||||
|
@ -157,6 +157,7 @@ napi_value FilterNapi::CreateFilter(napi_env env, napi_callback_info info)
|
||||
napi_property_descriptor resultFuncs[] = {
|
||||
DECLARE_NAPI_FUNCTION("blur", SetBlur),
|
||||
DECLARE_NAPI_FUNCTION("pixelStretch", SetPixelStretch),
|
||||
DECLARE_NAPI_FUNCTION("waterRipple", SetWaterRipple),
|
||||
};
|
||||
NAPI_CALL(env, napi_define_properties(env, object, sizeof(resultFuncs) / sizeof(resultFuncs[0]), resultFuncs));
|
||||
return object;
|
||||
@ -283,6 +284,59 @@ napi_value FilterNapi::SetPixelStretch(napi_env env, napi_callback_info info)
|
||||
return thisVar;
|
||||
}
|
||||
|
||||
float FilterNapi::GetSpecialValue(napi_env env, napi_value argValue)
|
||||
{
|
||||
double tmp = 0.0f;
|
||||
if (UIEffectNapiUtils::getType(env, argValue) == napi_number &&
|
||||
UIEFFECT_IS_OK(napi_get_value_double(env, argValue, &tmp)) && tmp >= 0) {
|
||||
return static_cast<float>(tmp);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
napi_value FilterNapi::SetWaterRipple(napi_env env, napi_callback_info info)
|
||||
{
|
||||
napi_value result = nullptr;
|
||||
napi_get_undefined(env, &result);
|
||||
napi_status status;
|
||||
napi_value thisVar = nullptr;
|
||||
napi_value argValue[NUM_4] = {0};
|
||||
size_t argCount = NUM_4;
|
||||
UIEFFECT_JS_ARGS(env, info, status, argCount, argValue, thisVar);
|
||||
UIEFFECT_NAPI_CHECK_RET_D(UIEFFECT_IS_OK(status), nullptr, FILTER_LOG_E("fail to napi_get_water_ripple_info"));
|
||||
|
||||
std::shared_ptr<WaterRipplePara> para = std::make_shared<WaterRipplePara>();
|
||||
|
||||
float progress = 0.0f;
|
||||
float waveCount = 0.0f;
|
||||
float rippleCenterX = 0.0f;
|
||||
float rippleCenterY = 0.0f;
|
||||
|
||||
if (argCount != NUM_4) {
|
||||
FILTER_LOG_E("Args number less than 4");
|
||||
}
|
||||
|
||||
progress = GetSpecialValue(env, argValue[NUM_0]);
|
||||
waveCount = GetSpecialValue(env, argValue[NUM_1]);
|
||||
rippleCenterX = GetSpecialValue(env, argValue[NUM_2]);
|
||||
rippleCenterY = GetSpecialValue(env, argValue[NUM_3]);
|
||||
|
||||
para->SetProgress(progress);
|
||||
para->SetWaveCount(waveCount);
|
||||
para->SetRippleCenterX(rippleCenterX);
|
||||
para->SetRippleCenterY(rippleCenterY);
|
||||
|
||||
Filter* filterObj = nullptr;
|
||||
NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&filterObj)));
|
||||
if (filterObj == nullptr) {
|
||||
FILTER_LOG_E("filterNapi is nullptr");
|
||||
return thisVar;
|
||||
}
|
||||
filterObj->AddPara(para);
|
||||
|
||||
return thisVar;
|
||||
}
|
||||
|
||||
Drawing::TileMode FilterNapi::ParserArgumentType(napi_env env, napi_value argv)
|
||||
{
|
||||
int32_t mode = 0;
|
||||
|
@ -36,6 +36,7 @@ static RoundRect* CastToRoundRect(OH_Drawing_RoundRect* cRoundRect)
|
||||
OH_Drawing_RoundRect* OH_Drawing_RoundRectCreate(const OH_Drawing_Rect* cRect, float xRad, float yRad)
|
||||
{
|
||||
if (cRect == nullptr) {
|
||||
g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
|
||||
return nullptr;
|
||||
}
|
||||
return (OH_Drawing_RoundRect*)new RoundRect(CastToRect(*cRect), xRad, yRad);
|
||||
|
@ -48,6 +48,10 @@ OH_Drawing_Typeface* OH_Drawing_TypefaceCreateDefault()
|
||||
|
||||
OH_Drawing_Typeface* OH_Drawing_TypefaceCreateFromFile(const char* path, int index)
|
||||
{
|
||||
if (path == nullptr) {
|
||||
g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
|
||||
return nullptr;
|
||||
}
|
||||
std::shared_ptr<Typeface> typeface = Typeface::MakeFromFile(path, index);
|
||||
if (typeface == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -69,16 +69,6 @@ enum class PathMeasureMatrixFlags {
|
||||
GET_POS_AND_TAN_MATRIX,
|
||||
};
|
||||
|
||||
enum class PathVerb {
|
||||
Move = 0,
|
||||
Line,
|
||||
Quad,
|
||||
Conic,
|
||||
Cubic,
|
||||
Close,
|
||||
Done
|
||||
};
|
||||
|
||||
class DRAWING_API Path {
|
||||
public:
|
||||
Path() noexcept;
|
||||
@ -510,9 +500,6 @@ public:
|
||||
bool GetMatrix(bool forceClosed, float distance, Matrix* matrix,
|
||||
PathMeasureMatrixFlags flags = PathMeasureMatrixFlags::GET_POS_AND_TAN_MATRIX);
|
||||
|
||||
int GetVerbsCount() const;
|
||||
std::vector<PathVerb> GetVerbs() const;
|
||||
|
||||
std::shared_ptr<Data> Serialize() const;
|
||||
bool Deserialize(std::shared_ptr<Data> data);
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
#include <shared_mutex>
|
||||
#include <mutex>
|
||||
#include <stack>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
@ -36,7 +36,6 @@ namespace OHOS {
|
||||
namespace Rosen {
|
||||
namespace Drawing {
|
||||
class DrawCmdList;
|
||||
class DrawImageRectOpItem;
|
||||
class DRAWING_API DrawOpItem : public OpItem {
|
||||
public:
|
||||
explicit DrawOpItem(uint32_t type) : OpItem(type) {}
|
||||
@ -118,7 +117,7 @@ public:
|
||||
static std::function<std::shared_ptr<Drawing::Typeface>(uint64_t)> customTypefaceQueryfunc_;
|
||||
};
|
||||
|
||||
static std::shared_timed_mutex UnmarshallingFuncMapMutex_;
|
||||
static std::mutex UnmarshallingFuncMapMutex_;
|
||||
class UnmarshallingPlayer {
|
||||
public:
|
||||
using UnmarshallingFunc = std::shared_ptr<DrawOpItem>(*)(const DrawCmdList& cmdList, void* handle);
|
||||
@ -460,7 +459,6 @@ public:
|
||||
static std::shared_ptr<DrawOpItem> Unmarshalling(const DrawCmdList& cmdList, void* handle);
|
||||
void Marshalling(DrawCmdList& cmdList) override;
|
||||
void Playback(Canvas* canvas, const Rect* rect) override;
|
||||
std::shared_ptr<DrawImageRectOpItem> GenerateQuadCachedOpItem(Canvas* canvas);
|
||||
private:
|
||||
std::shared_ptr<Path> path_;
|
||||
};
|
||||
|
@ -183,9 +183,6 @@ public:
|
||||
void UpdateNodeIdToPicture(NodeId nodeId);
|
||||
|
||||
size_t CountTextBlobNum();
|
||||
|
||||
void CacheQuadPath();
|
||||
|
||||
private:
|
||||
void ClearCache();
|
||||
void GenerateCacheByVector(Canvas* canvas, const Rect* rect);
|
||||
|
@ -20,6 +20,78 @@
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
#define DRAW_API_WITH_PAINT(func, ...) \
|
||||
do { \
|
||||
bool brushValid = paintBrush_.IsValid(); \
|
||||
bool penValid = paintPen_.IsValid(); \
|
||||
if (!brushValid && !penValid) { \
|
||||
impl_->func(__VA_ARGS__, defaultPaint_); \
|
||||
return; \
|
||||
} \
|
||||
if (brushValid && penValid && Paint::CanCombinePaint(paintBrush_, paintPen_)) { \
|
||||
paintPen_.SetStyle(Paint::PaintStyle::PAINT_FILL_STROKE); \
|
||||
impl_->func(__VA_ARGS__, paintPen_); \
|
||||
paintPen_.SetStyle(Paint::PaintStyle::PAINT_STROKE); \
|
||||
return; \
|
||||
} \
|
||||
if (brushValid) { \
|
||||
impl_->func(__VA_ARGS__, paintBrush_); \
|
||||
} \
|
||||
if (penValid) { \
|
||||
impl_->func(__VA_ARGS__, paintPen_); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define DRAW_API_WITH_PAINT_LOOPER(func, ...) \
|
||||
do { \
|
||||
bool brushValid = paintBrush_.IsValid(); \
|
||||
bool penValid = paintPen_.IsValid(); \
|
||||
if (!brushValid && !penValid) { \
|
||||
impl_->func(__VA_ARGS__, defaultPaint_); \
|
||||
return; \
|
||||
} \
|
||||
if (brushValid && penValid && Paint::CanCombinePaint(paintBrush_, paintPen_)) { \
|
||||
paintPen_.SetStyle(Paint::PaintStyle::PAINT_FILL_STROKE); \
|
||||
std::shared_ptr looper = paintPen_.GetLooper(); \
|
||||
if (looper != nullptr) { \
|
||||
Paint looperPaint; \
|
||||
GetLooperPaint(paintPen_, looperPaint); \
|
||||
impl_->Save(); \
|
||||
impl_->Translate(looper->GetXOffset(), looper->GetYOffset()); \
|
||||
impl_->func(__VA_ARGS__, looperPaint); \
|
||||
impl_->Restore(); \
|
||||
} \
|
||||
impl_->func(__VA_ARGS__, paintPen_); \
|
||||
paintPen_.SetStyle(Paint::PaintStyle::PAINT_STROKE); \
|
||||
return; \
|
||||
} \
|
||||
if (brushValid) { \
|
||||
std::shared_ptr looper = paintBrush_.GetLooper(); \
|
||||
if (looper != nullptr) { \
|
||||
Paint looperPaint; \
|
||||
GetLooperPaint(paintBrush_, looperPaint); \
|
||||
impl_->Save(); \
|
||||
impl_->Translate(looper->GetXOffset(), looper->GetYOffset()); \
|
||||
impl_->func(__VA_ARGS__, looperPaint); \
|
||||
impl_->Restore(); \
|
||||
} \
|
||||
impl_->func(__VA_ARGS__, paintBrush_); \
|
||||
} \
|
||||
if (penValid) { \
|
||||
std::shared_ptr looper = paintPen_.GetLooper(); \
|
||||
if (looper != nullptr) { \
|
||||
Paint looperPaint; \
|
||||
GetLooperPaint(paintPen_, looperPaint); \
|
||||
impl_->Save(); \
|
||||
impl_->Translate(looper->GetXOffset(), looper->GetYOffset()); \
|
||||
impl_->func(__VA_ARGS__, looperPaint); \
|
||||
impl_->Restore(); \
|
||||
} \
|
||||
impl_->func(__VA_ARGS__, paintPen_); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
namespace Drawing {
|
||||
CoreCanvas::CoreCanvas() : impl_(ImplFactory::CreateCoreCanvasImpl())
|
||||
{
|
||||
@ -102,74 +174,62 @@ bool CoreCanvas::ReadPixels(const Bitmap& dstBitmap, int srcX, int srcY)
|
||||
|
||||
void CoreCanvas::DrawPoint(const Point& point)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawPoint(point);
|
||||
DRAW_API_WITH_PAINT(DrawPoint, point);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawSdf(const SDFShapeBase& shape)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawSdf(shape);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawPoints(PointMode mode, size_t count, const Point pts[])
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawPoints(mode, count, pts);
|
||||
DRAW_API_WITH_PAINT(DrawPoints, mode, count, pts);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawLine(const Point& startPt, const Point& endPt)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawLine(startPt, endPt);
|
||||
DRAW_API_WITH_PAINT(DrawLine, startPt, endPt);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawRect(const Rect& rect)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawRect(rect);
|
||||
DRAW_API_WITH_PAINT(DrawRect, rect);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawRoundRect(const RoundRect& roundRect)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawRoundRect(roundRect);
|
||||
DRAW_API_WITH_PAINT(DrawRoundRect, roundRect);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawNestedRoundRect(outer, inner);
|
||||
DRAW_API_WITH_PAINT(DrawNestedRoundRect, outer, inner);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawArc(oval, startAngle, sweepAngle);
|
||||
DRAW_API_WITH_PAINT(DrawArc, oval, startAngle, sweepAngle);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawPie(oval, startAngle, sweepAngle);
|
||||
DRAW_API_WITH_PAINT(DrawPie, oval, startAngle, sweepAngle);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawOval(const Rect& oval)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawOval(oval);
|
||||
DRAW_API_WITH_PAINT(DrawOval, oval);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawCircle(const Point& centerPt, scalar radius)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawCircle(centerPt, radius);
|
||||
DRAW_API_WITH_PAINT(DrawCircle, centerPt, radius);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawPath(const Path& path)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawPath(path);
|
||||
DRAW_API_WITH_PAINT(DrawPath, path);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawBackground(const Brush& brush)
|
||||
@ -197,20 +257,17 @@ void CoreCanvas::DrawColor(ColorQuad color, BlendMode mode)
|
||||
|
||||
void CoreCanvas::DrawRegion(const Region& region)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawRegion(region);
|
||||
DRAW_API_WITH_PAINT(DrawRegion, region);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawPatch(const Point cubics[12], const ColorQuad colors[4], const Point texCoords[4], BlendMode mode)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawPatch(cubics, colors, texCoords, mode);
|
||||
DRAW_API_WITH_PAINT(DrawPatch, cubics, colors, texCoords, mode);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawVertices(const Vertices& vertices, BlendMode mode)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawVertices(vertices, mode);
|
||||
DRAW_API_WITH_PAINT(DrawVertices, vertices, mode);
|
||||
}
|
||||
|
||||
bool CoreCanvas::OpCalculateBefore(const Matrix& matrix)
|
||||
@ -226,13 +283,12 @@ std::shared_ptr<Drawing::OpListHandle> CoreCanvas::OpCalculateAfter(const Rect&
|
||||
void CoreCanvas::DrawAtlas(const Image* atlas, const RSXform xform[], const Rect tex[], const ColorQuad colors[],
|
||||
int count, BlendMode mode, const SamplingOptions& sampling, const Rect* cullRect)
|
||||
{
|
||||
impl_->DrawAtlas(atlas, xform, tex, colors, count, mode, sampling, cullRect);
|
||||
DRAW_API_WITH_PAINT(DrawAtlas, atlas, xform, tex, colors, count, mode, sampling, cullRect);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawBitmap(bitmap, px, py);
|
||||
DRAW_API_WITH_PAINT(DrawBitmap, bitmap, px, py);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawImageNine(const Image* image, const RectI& center, const Rect& dst,
|
||||
@ -244,27 +300,23 @@ void CoreCanvas::DrawImageNine(const Image* image, const RectI& center, const Re
|
||||
void CoreCanvas::DrawImageLattice(const Image* image, const Lattice& lattice, const Rect& dst,
|
||||
FilterMode filter)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawImageLattice(image, lattice, dst, filter);
|
||||
DRAW_API_WITH_PAINT(DrawImageLattice, image, lattice, dst, filter);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawImage(const Image& image, const scalar px, const scalar py, const SamplingOptions& sampling)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawImage(image, px, py, sampling);
|
||||
DRAW_API_WITH_PAINT(DrawImage, image, px, py, sampling);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawImageRect(
|
||||
const Image& image, const Rect& src, const Rect& dst, const SamplingOptions& sampling, SrcRectConstraint constraint)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawImageRect(image, src, dst, sampling, constraint);
|
||||
DRAW_API_WITH_PAINT(DrawImageRect, image, src, dst, sampling, constraint);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawImageRect(const Image& image, const Rect& dst, const SamplingOptions& sampling)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawImageRect(image, dst, sampling);
|
||||
DRAW_API_WITH_PAINT(DrawImageRect, image, dst, sampling);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawPicture(const Picture& picture)
|
||||
@ -279,13 +331,12 @@ void CoreCanvas::DrawSVGDOM(const sk_sp<SkSVGDOM>& svgDom)
|
||||
|
||||
void CoreCanvas::DrawTextBlob(const TextBlob* blob, const scalar x, const scalar y)
|
||||
{
|
||||
ApplyDrawLooper([&]() { impl_->DrawTextBlob(blob, x, y); });
|
||||
DRAW_API_WITH_PAINT_LOOPER(DrawTextBlob, blob, x, y);
|
||||
}
|
||||
|
||||
void CoreCanvas::DrawSymbol(const DrawingHMSymbolData& symbol, Point locate)
|
||||
{
|
||||
AttachPaint();
|
||||
impl_->DrawSymbol(symbol, locate);
|
||||
DRAW_API_WITH_PAINT(DrawSymbol, symbol, locate);
|
||||
}
|
||||
|
||||
void CoreCanvas::ClipRect(const Rect& rect, ClipOp op, bool doAntiAlias)
|
||||
@ -475,82 +526,6 @@ int CoreCanvas::GetAlphaSaveCount() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CoreCanvas::ApplyDrawProc(const Paint& paint, const std::function<void()>& proc)
|
||||
{
|
||||
impl_->AttachPaint(paint);
|
||||
proc();
|
||||
}
|
||||
|
||||
void CoreCanvas::ApplyBlurDrawProc(const Paint& paint, const std::function<void()>& proc)
|
||||
{
|
||||
std::shared_ptr<BlurDrawLooper> looper = paint.GetLooper();
|
||||
if (looper == nullptr) {
|
||||
return;
|
||||
}
|
||||
Paint tmpPaint(paint);
|
||||
tmpPaint.SetColor(looper->GetColor());
|
||||
Filter filter = tmpPaint.GetFilter();
|
||||
filter.SetMaskFilter(looper->GetMaskFilter());
|
||||
tmpPaint.SetFilter(filter);
|
||||
impl_->Save();
|
||||
impl_->Translate(looper->GetXOffset(), looper->GetYOffset());
|
||||
ApplyDrawProc(tmpPaint, proc);
|
||||
impl_->Restore();
|
||||
}
|
||||
|
||||
void CoreCanvas::ApplyDrawLooper(const std::function<void()> drawProc)
|
||||
{
|
||||
bool brushValid = paintBrush_.IsValid();
|
||||
bool penValid = paintPen_.IsValid();
|
||||
if (!brushValid && !penValid) {
|
||||
ApplyDrawProc(defaultPaint_, drawProc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (brushValid && penValid && Paint::CanCombinePaint(paintBrush_, paintPen_)) {
|
||||
paintPen_.SetStyle(Paint::PaintStyle::PAINT_FILL_STROKE);
|
||||
ApplyBlurDrawProc(paintPen_, drawProc);
|
||||
ApplyDrawProc(paintPen_, drawProc);
|
||||
paintPen_.SetStyle(Paint::PaintStyle::PAINT_STROKE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (brushValid) {
|
||||
ApplyBlurDrawProc(paintBrush_, drawProc);
|
||||
ApplyDrawProc(paintBrush_, drawProc);
|
||||
}
|
||||
|
||||
if (penValid) {
|
||||
ApplyBlurDrawProc(paintPen_, drawProc);
|
||||
ApplyDrawProc(paintPen_, drawProc);
|
||||
}
|
||||
}
|
||||
|
||||
void CoreCanvas::AttachPaint()
|
||||
{
|
||||
bool brushValid = paintBrush_.IsValid();
|
||||
bool penValid = paintPen_.IsValid();
|
||||
if (!brushValid && !penValid) {
|
||||
impl_->AttachPaint(defaultPaint_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (brushValid && penValid && Paint::CanCombinePaint(paintBrush_, paintPen_)) {
|
||||
paintPen_.SetStyle(Paint::PaintStyle::PAINT_FILL_STROKE);
|
||||
impl_->AttachPaint(paintPen_);
|
||||
paintPen_.SetStyle(Paint::PaintStyle::PAINT_STROKE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (brushValid) {
|
||||
impl_->AttachPaint(paintBrush_);
|
||||
}
|
||||
|
||||
if (penValid) {
|
||||
impl_->AttachPaint(paintPen_);
|
||||
}
|
||||
}
|
||||
|
||||
void CoreCanvas::BuildOverDraw(std::shared_ptr<Canvas> canvas)
|
||||
{
|
||||
if (impl_ && canvas) {
|
||||
@ -572,6 +547,16 @@ bool CoreCanvas::DrawBlurImage(const Image& image, const HpsBlurParameter& blurP
|
||||
{
|
||||
return impl_->DrawBlurImage(image, blurParams);
|
||||
}
|
||||
|
||||
void CoreCanvas::GetLooperPaint(const Paint& paint, Paint& looperPaint)
|
||||
{
|
||||
looperPaint = paint;
|
||||
std::shared_ptr looper = paint.GetLooper();
|
||||
looperPaint.SetColor(looper->GetColor());
|
||||
Filter filter = looperPaint.GetFilter();
|
||||
filter.SetMaskFilter(looper->GetMaskFilter());
|
||||
looperPaint.SetFilter(filter);
|
||||
}
|
||||
} // namespace Drawing
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -727,11 +727,8 @@ protected:
|
||||
Paint defaultPaint_;
|
||||
|
||||
private:
|
||||
void ApplyDrawProc(const Paint& paint, const std::function<void()>& proc);
|
||||
void ApplyBlurDrawProc(const Paint& paint, const std::function<void()>& proc);
|
||||
void ApplyDrawLooper(const std::function<void()> drawProc);
|
||||
void GetLooperPaint(const Paint& paint, Paint& looperPaint);
|
||||
|
||||
void AttachPaint();
|
||||
std::shared_ptr<CoreCanvasImpl> impl_;
|
||||
#ifdef ACE_ENABLE_GPU
|
||||
std::shared_ptr<GPUContext> gpuContext_;
|
||||
|
@ -285,16 +285,6 @@ bool Path::GetMatrix(bool forceClosed, float distance, Matrix* matrix, PathMeasu
|
||||
return impl_->GetMatrix(forceClosed, distance, matrix, flag);
|
||||
}
|
||||
|
||||
int Path::GetVerbsCount() const
|
||||
{
|
||||
return impl_->GetVerbsCount();
|
||||
}
|
||||
|
||||
std::vector<PathVerb> Path::GetVerbs() const
|
||||
{
|
||||
return impl_->GetVerbs();
|
||||
}
|
||||
|
||||
std::shared_ptr<Data> Path::Serialize() const
|
||||
{
|
||||
return impl_->Serialize();
|
||||
|
@ -81,32 +81,32 @@ public:
|
||||
int srcX, int srcY) = 0;
|
||||
virtual bool ReadPixels(const Bitmap& dstBitmap, int srcX, int srcY) = 0;
|
||||
// shapes
|
||||
virtual void DrawPoint(const Point& point) = 0;
|
||||
virtual void DrawPoint(const Point& point, const Paint& paint) = 0;
|
||||
virtual void DrawSdf(const SDFShapeBase& shape) = 0;
|
||||
virtual void DrawPoints(PointMode mode, size_t count, const Point pts[]) = 0;
|
||||
virtual void DrawLine(const Point& startPt, const Point& endPt) = 0;
|
||||
virtual void DrawRect(const Rect& rect) = 0;
|
||||
virtual void DrawRoundRect(const RoundRect& roundRect) = 0;
|
||||
virtual void DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner) = 0;
|
||||
virtual void DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle) = 0;
|
||||
virtual void DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle) = 0;
|
||||
virtual void DrawOval(const Rect& oval) = 0;
|
||||
virtual void DrawCircle(const Point& centerPt, scalar radius) = 0;
|
||||
virtual void DrawPath(const Path& path) = 0;
|
||||
virtual void DrawPoints(PointMode mode, size_t count, const Point pts[], const Paint& paint) = 0;
|
||||
virtual void DrawLine(const Point& startPt, const Point& endPt, const Paint& paint) = 0;
|
||||
virtual void DrawRect(const Rect& rect, const Paint& paint) = 0;
|
||||
virtual void DrawRoundRect(const RoundRect& roundRect, const Paint& paint) = 0;
|
||||
virtual void DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner, const Paint& paint) = 0;
|
||||
virtual void DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle, const Paint& paint) = 0;
|
||||
virtual void DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle, const Paint& paint) = 0;
|
||||
virtual void DrawOval(const Rect& oval, const Paint& paint) = 0;
|
||||
virtual void DrawCircle(const Point& centerPt, scalar radius, const Paint& paint) = 0;
|
||||
virtual void DrawPath(const Path& path, const Paint& paint) = 0;
|
||||
virtual void DrawBackground(const Brush& brush) = 0;
|
||||
virtual void DrawShadow(const Path& path, const Point3& planeParams, const Point3& devLightPos, scalar lightRadius,
|
||||
Color ambientColor, Color spotColor, ShadowFlags flag) = 0;
|
||||
virtual void DrawShadowStyle(const Path& path, const Point3& planeParams, const Point3& devLightPos,
|
||||
scalar lightRadius, Color ambientColor, Color spotColor, ShadowFlags flag, bool isLimitElevation) = 0;
|
||||
virtual void DrawRegion(const Region& region) = 0;
|
||||
virtual void DrawRegion(const Region& region, const Paint& paint) = 0;
|
||||
virtual void DrawPatch(const Point cubics[12], const ColorQuad colors[4],
|
||||
const Point texCoords[4], BlendMode mode) = 0;
|
||||
virtual void DrawVertices(const Vertices& vertices, BlendMode mode) = 0;
|
||||
const Point texCoords[4], BlendMode mode, const Paint& paint) = 0;
|
||||
virtual void DrawVertices(const Vertices& vertices, BlendMode mode, const Paint& paint) = 0;
|
||||
|
||||
virtual void DrawImageNine(const Image* image, const RectI& center, const Rect& dst,
|
||||
FilterMode filter, const Brush* brush = nullptr) = 0;
|
||||
virtual void DrawImageLattice(const Image* image, const Lattice& lattice, const Rect& dst,
|
||||
FilterMode filter) = 0;
|
||||
FilterMode filter, const Paint& paint) = 0;
|
||||
|
||||
// color
|
||||
virtual void DrawColor(ColorQuad color, BlendMode mode) = 0;
|
||||
@ -117,22 +117,24 @@ public:
|
||||
|
||||
// image
|
||||
virtual void DrawAtlas(const Image* atlas, const RSXform xform[], const Rect tex[], const ColorQuad colors[],
|
||||
int count, BlendMode mode, const SamplingOptions& sampling, const Rect* cullRect) = 0;
|
||||
virtual void DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py) = 0;
|
||||
virtual void DrawImage(const Image& image, const scalar px, const scalar p, const SamplingOptions& sampling) = 0;
|
||||
int count, BlendMode mode, const SamplingOptions& sampling, const Rect* cullRect, const Paint& paint) = 0;
|
||||
virtual void DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py, const Paint& paint) = 0;
|
||||
virtual void DrawImage(const Image& image, const scalar px, const scalar p, const SamplingOptions& sampling,
|
||||
const Paint& paint) = 0;
|
||||
virtual void DrawImageRect(const Image& image, const Rect& src, const Rect& dst, const SamplingOptions& sampling,
|
||||
SrcRectConstraint constraint) = 0;
|
||||
virtual void DrawImageRect(const Image& image, const Rect& dst, const SamplingOptions& sampling) = 0;
|
||||
SrcRectConstraint constraint, const Paint& paint) = 0;
|
||||
virtual void DrawImageRect(const Image& image, const Rect& dst, const SamplingOptions& sampling,
|
||||
const Paint& paint) = 0;
|
||||
virtual void DrawPicture(const Picture& picture) = 0;
|
||||
|
||||
// temporary interface. Support drawing of SkSVGDOM
|
||||
virtual void DrawSVGDOM(const sk_sp<SkSVGDOM>& svgDom) = 0;
|
||||
|
||||
// text
|
||||
virtual void DrawTextBlob(const TextBlob* blob, const scalar x, const scalar y) = 0;
|
||||
virtual void DrawTextBlob(const TextBlob* blob, const scalar x, const scalar y, const Paint& paint) = 0;
|
||||
|
||||
// symbol
|
||||
virtual void DrawSymbol(const DrawingHMSymbolData& symbol, Point locate) = 0;
|
||||
virtual void DrawSymbol(const DrawingHMSymbolData& symbol, Point locate, const Paint& paint) = 0;
|
||||
|
||||
// clip
|
||||
virtual void ClipRect(const Rect& rect, ClipOp op, bool doAntiAlias = false) = 0;
|
||||
@ -163,9 +165,6 @@ public:
|
||||
virtual uint32_t GetSaveCount() const = 0;
|
||||
virtual void Discard() = 0;
|
||||
|
||||
// paint
|
||||
virtual void AttachPaint(const Paint& paint) = 0;
|
||||
|
||||
virtual void BuildOverDraw(std::shared_ptr<Canvas> canvas) = 0;
|
||||
|
||||
virtual void BuildNoDraw(int32_t width, int32_t height) = 0;
|
||||
|
@ -37,7 +37,6 @@ enum class PathOp;
|
||||
enum class ArcSize;
|
||||
enum class PathAddMode;
|
||||
enum class PathMeasureMatrixFlags;
|
||||
enum class PathVerb;
|
||||
class PathImpl : public BaseImpl {
|
||||
public:
|
||||
PathImpl() noexcept {}
|
||||
@ -102,10 +101,6 @@ public:
|
||||
virtual bool GetPositionAndTangent(scalar distance, Point& position, Point& tangent, bool forceClosed) = 0;
|
||||
virtual bool IsClosed(bool forceClosed) = 0;
|
||||
virtual bool GetMatrix(bool forceClosed, float distance, Matrix* matrix, PathMeasureMatrixFlags flag) = 0;
|
||||
|
||||
virtual int GetVerbsCount() const;
|
||||
virtual std::vector<PathVerb> GetVerbs() const;
|
||||
|
||||
virtual std::shared_ptr<Data> Serialize() const = 0;
|
||||
virtual bool Deserialize(std::shared_ptr<Data> data) = 0;
|
||||
};
|
||||
|
@ -42,18 +42,18 @@
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
namespace Drawing {
|
||||
SkiaCanvas::SkiaCanvas() : skiaCanvas_(std::make_shared<SkCanvas>()), skiaPaint_()
|
||||
SkiaCanvas::SkiaCanvas() : skiaCanvas_(std::make_shared<SkCanvas>())
|
||||
{
|
||||
skCanvas_ = skiaCanvas_.get();
|
||||
}
|
||||
|
||||
SkiaCanvas::SkiaCanvas(const std::shared_ptr<SkCanvas>& skCanvas) : skiaCanvas_(skCanvas), skiaPaint_()
|
||||
SkiaCanvas::SkiaCanvas(const std::shared_ptr<SkCanvas>& skCanvas) : skiaCanvas_(skCanvas)
|
||||
{
|
||||
skCanvas_ = skiaCanvas_.get();
|
||||
}
|
||||
|
||||
SkiaCanvas::SkiaCanvas(int32_t width, int32_t height)
|
||||
: skiaCanvas_(std::make_shared<SkCanvas>(width, height)), skiaPaint_()
|
||||
: skiaCanvas_(std::make_shared<SkCanvas>(width, height))
|
||||
{
|
||||
skCanvas_ = skiaCanvas_.get();
|
||||
}
|
||||
@ -237,90 +237,73 @@ void SkiaCanvas::DrawSdf(const SDFShapeBase& shape)
|
||||
skCanvas_->drawPaint(paint);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawPoint(const Point& point)
|
||||
void SkiaCanvas::DrawPoint(const Point& point, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
const SkPoint* skPoint = reinterpret_cast<const SkPoint*>(&point);
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawPoint(*skPoint, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawPoint(*skPoint, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawPoints(PointMode mode, size_t count, const Point pts[])
|
||||
void SkiaCanvas::DrawPoints(PointMode mode, size_t count, const Point pts[], const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
const SkPoint* skPts = reinterpret_cast<const SkPoint*>(pts);
|
||||
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawPoints(static_cast<SkCanvas::PointMode>(mode), count, skPts, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawPoints(static_cast<SkCanvas::PointMode>(mode), count, skPts, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawLine(const Point& startPt, const Point& endPt)
|
||||
void SkiaCanvas::DrawLine(const Point& startPt, const Point& endPt, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
const SkPoint* skStartPt = reinterpret_cast<const SkPoint*>(&startPt);
|
||||
const SkPoint* skEndPt = reinterpret_cast<const SkPoint*>(&endPt);
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawLine(*skStartPt, *skEndPt, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawLine(*skStartPt, *skEndPt, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawRect(const Rect& rect)
|
||||
void SkiaCanvas::DrawRect(const Rect& rect, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
const SkRect* skRect = reinterpret_cast<const SkRect*>(&rect);
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawRect(*skRect, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawRect(*skRect, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawRoundRect(const RoundRect& roundRect)
|
||||
void SkiaCanvas::DrawRoundRect(const RoundRect& roundRect, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
SkRRect rRect;
|
||||
RoundRectCastToSkRRect(roundRect, rRect);
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawRRect(rRect, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawRRect(rRect, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner)
|
||||
void SkiaCanvas::DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
SkRRect outerRRect;
|
||||
@ -329,89 +312,71 @@ void SkiaCanvas::DrawNestedRoundRect(const RoundRect& outer, const RoundRect& in
|
||||
SkRRect innerRRect;
|
||||
RoundRectCastToSkRRect(inner, innerRRect);
|
||||
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawDRRect(outerRRect, innerRRect, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawDRRect(outerRRect, innerRRect, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle)
|
||||
void SkiaCanvas::DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
const SkRect* arcRect = reinterpret_cast<const SkRect*>(&oval);
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawArc(*arcRect, startAngle, sweepAngle, false, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawArc(*arcRect, startAngle, sweepAngle, false, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle)
|
||||
void SkiaCanvas::DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
const SkRect* pieRect = reinterpret_cast<const SkRect*>(&oval);
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawArc(*pieRect, startAngle, sweepAngle, true, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawArc(*pieRect, startAngle, sweepAngle, true, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawOval(const Rect& oval)
|
||||
void SkiaCanvas::DrawOval(const Rect& oval, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
const SkRect* ovalRect = reinterpret_cast<const SkRect*>(&oval);
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawOval(*ovalRect, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawOval(*ovalRect, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawCircle(const Point& centerPt, scalar radius)
|
||||
void SkiaCanvas::DrawCircle(const Point& centerPt, scalar radius, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawCircle(centerPt.GetX(), centerPt.GetY(), radius, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawCircle(centerPt.GetX(), centerPt.GetY(), radius, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawPath(const Path& path)
|
||||
void SkiaCanvas::DrawPath(const Path& path, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
auto skPathImpl = path.GetImpl<SkiaPath>();
|
||||
if (skPathImpl == nullptr) {
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawPath(skPathImpl->GetPath(), *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawPath(skPathImpl->GetPath(), skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawBackground(const Brush& brush)
|
||||
@ -473,27 +438,23 @@ void SkiaCanvas::DrawColor(ColorQuad color, BlendMode mode)
|
||||
skCanvas_->drawColor(static_cast<SkColor>(color), static_cast<SkBlendMode>(mode));
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawRegion(const Region& region)
|
||||
void SkiaCanvas::DrawRegion(const Region& region, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawRegion(*region.GetImpl<SkiaRegion>()->GetSkRegion(), *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawRegion(*region.GetImpl<SkiaRegion>()->GetSkRegion(), skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawPatch(const Point cubics[12], const ColorQuad colors[4],
|
||||
const Point texCoords[4], BlendMode mode)
|
||||
const Point texCoords[4], BlendMode mode, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -526,22 +487,19 @@ void SkiaCanvas::DrawPatch(const Point cubics[12], const ColorQuad colors[4],
|
||||
}
|
||||
}
|
||||
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawPatch(
|
||||
skiaCubics.empty() ? nullptr : skiaCubics.data(),
|
||||
skiaColors.empty() ? nullptr : skiaColors.data(),
|
||||
skiaTexCoords.empty() ? nullptr : skiaTexCoords.data(),
|
||||
static_cast<SkBlendMode>(mode), *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawPatch(
|
||||
skiaCubics.empty() ? nullptr : skiaCubics.data(),
|
||||
skiaColors.empty() ? nullptr : skiaColors.data(),
|
||||
skiaTexCoords.empty() ? nullptr : skiaTexCoords.data(),
|
||||
static_cast<SkBlendMode>(mode), skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawVertices(const Vertices& vertices, BlendMode mode)
|
||||
void SkiaCanvas::DrawVertices(const Vertices& vertices, BlendMode mode, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -551,11 +509,9 @@ void SkiaCanvas::DrawVertices(const Vertices& vertices, BlendMode mode)
|
||||
verts = skVerticesImpl->GetVertices();
|
||||
}
|
||||
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawVertices(verts, static_cast<SkBlendMode>(mode), *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawVertices(verts, static_cast<SkBlendMode>(mode), skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawImageNine(const Image* image, const RectI& center, const Rect& dst,
|
||||
@ -585,11 +541,10 @@ void SkiaCanvas::DrawImageNine(const Image* image, const RectI& center, const Re
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawImageLattice(const Image* image, const Lattice& lattice, const Rect& dst,
|
||||
FilterMode filter)
|
||||
FilterMode filter, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -599,7 +554,6 @@ void SkiaCanvas::DrawImageLattice(const Image* image, const Lattice& lattice, co
|
||||
img = skImageImpl->GetImage();
|
||||
if (img == nullptr) {
|
||||
LOGD("img is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -621,16 +575,9 @@ void SkiaCanvas::DrawImageLattice(const Image* image, const Lattice& lattice, co
|
||||
|
||||
SkFilterMode skFilterMode = static_cast<SkFilterMode>(filter);
|
||||
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
if (paints.count_ == 0) {
|
||||
skCanvas_->drawImageLattice(img.get(), skLattice, *skDst, skFilterMode);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawImageLattice(img.get(), skLattice, *skDst, skFilterMode, paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawImageLattice(img.get(), skLattice, *skDst, skFilterMode, &skPaint_);
|
||||
}
|
||||
|
||||
bool SkiaCanvas::OpCalculateBefore(const Matrix& matrix)
|
||||
@ -695,7 +642,7 @@ std::shared_ptr<Drawing::OpListHandle> SkiaCanvas::OpCalculateAfter(const Rect&
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawAtlas(const Image* atlas, const RSXform xform[], const Rect tex[], const ColorQuad colors[],
|
||||
int count, BlendMode mode, const SamplingOptions& sampling, const Rect* cullRect)
|
||||
int count, BlendMode mode, const SamplingOptions& sampling, const Rect* cullRect, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_ || !atlas || !xform || !tex) {
|
||||
LOGD("skCanvas_ or atlas, xform or tex is null, return on line %{public}d", __LINE__);
|
||||
@ -735,52 +682,34 @@ void SkiaCanvas::DrawAtlas(const Image* atlas, const RSXform xform[], const Rect
|
||||
|
||||
const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
|
||||
const SkRect* skCullRect = reinterpret_cast<const SkRect*>(cullRect);
|
||||
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
if (paints.count_ == 0) {
|
||||
skCanvas_->drawAtlas(img.get(), skRSXform, skTex, skColors.empty() ? nullptr : skColors.data(), count,
|
||||
static_cast<SkBlendMode>(mode), *samplingOptions, skCullRect, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawAtlas(img.get(), skRSXform, skTex, skColors.empty() ? nullptr : skColors.data(), count,
|
||||
static_cast<SkBlendMode>(mode), *samplingOptions, skCullRect, paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawAtlas(img.get(), skRSXform, skTex, skColors.empty() ? nullptr : skColors.data(), count,
|
||||
static_cast<SkBlendMode>(mode), *samplingOptions, skCullRect, &skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py)
|
||||
void SkiaCanvas::DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
SkBitmap bmp;
|
||||
|
||||
auto skBitmapImpl = bitmap.GetImpl<SkiaBitmap>();
|
||||
if (skBitmapImpl != nullptr) {
|
||||
bmp = skBitmapImpl->ExportSkiaBitmap();
|
||||
}
|
||||
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
if (paints.count_ == 0) {
|
||||
skCanvas_->drawImage(bmp.asImage(), px, py);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawImage(bmp.asImage(), px, py, SkSamplingOptions(), paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawImage(bmp.asImage(), px, py, SkSamplingOptions(), &skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawImage(const Image& image, const scalar px, const scalar py, const SamplingOptions& sampling)
|
||||
void SkiaCanvas::DrawImage(const Image& image, const scalar px, const scalar py,
|
||||
const SamplingOptions& sampling, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
sk_sp<SkImage> img;
|
||||
@ -790,31 +719,21 @@ void SkiaCanvas::DrawImage(const Image& image, const scalar px, const scalar py,
|
||||
img = skImageImpl->GetImage();
|
||||
if (img == nullptr) {
|
||||
LOGD("img is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
if (paints.count_ == 0) {
|
||||
skCanvas_->drawImage(img, px, py);
|
||||
return;
|
||||
}
|
||||
|
||||
const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
|
||||
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawImage(img, px, py, *samplingOptions, paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawImage(img, px, py, *samplingOptions, &skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawImageRect(
|
||||
const Image& image, const Rect& src, const Rect& dst, const SamplingOptions& sampling, SrcRectConstraint constraint)
|
||||
void SkiaCanvas::DrawImageRect(const Image& image, const Rect& src, const Rect& dst,
|
||||
const SamplingOptions& sampling, SrcRectConstraint constraint, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
sk_sp<SkImage> img;
|
||||
@ -823,7 +742,6 @@ void SkiaCanvas::DrawImageRect(
|
||||
img = skImageImpl->GetImage();
|
||||
if (img == nullptr) {
|
||||
LOGD("img is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -831,25 +749,18 @@ void SkiaCanvas::DrawImageRect(
|
||||
const SkRect* srcRect = reinterpret_cast<const SkRect*>(&src);
|
||||
const SkRect* dstRect = reinterpret_cast<const SkRect*>(&dst);
|
||||
const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
if (paints.count_ == 0) {
|
||||
skCanvas_->drawImageRect(
|
||||
img, *srcRect, *dstRect, *samplingOptions, nullptr, static_cast<SkCanvas::SrcRectConstraint>(constraint));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawImageRect(img, *srcRect, *dstRect, *samplingOptions, paint,
|
||||
static_cast<SkCanvas::SrcRectConstraint>(constraint));
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawImageRect(img, *srcRect, *dstRect, *samplingOptions, &skPaint_,
|
||||
static_cast<SkCanvas::SrcRectConstraint>(constraint));
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawImageRect(const Image& image, const Rect& dst, const SamplingOptions& sampling)
|
||||
void SkiaCanvas::DrawImageRect(const Image& image, const Rect& dst,
|
||||
const SamplingOptions& sampling, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
sk_sp<SkImage> img;
|
||||
@ -858,23 +769,15 @@ void SkiaCanvas::DrawImageRect(const Image& image, const Rect& dst, const Sampli
|
||||
img = skImageImpl->GetImage();
|
||||
if (img == nullptr) {
|
||||
LOGD("img is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const SkRect* dstRect = reinterpret_cast<const SkRect*>(&dst);
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
|
||||
if (paints.count_ == 0) {
|
||||
skCanvas_->drawImageRect(img, *dstRect, *samplingOptions, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawImageRect(img, *dstRect, *samplingOptions, paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawImageRect(img, *dstRect, *samplingOptions, &skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawPicture(const Picture& picture)
|
||||
@ -905,59 +808,50 @@ void SkiaCanvas::DrawSVGDOM(const sk_sp<SkSVGDOM>& svgDom)
|
||||
svgDom->render(skCanvas_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawTextBlob(const TextBlob* blob, const scalar x, const scalar y)
|
||||
void SkiaCanvas::DrawTextBlob(const TextBlob* blob, const scalar x, const scalar y, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
if (!blob) {
|
||||
LOGD("blob is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
auto skiaTextBlob = blob->GetImpl<SkiaTextBlob>();
|
||||
if (!skiaTextBlob) {
|
||||
LOGD("skiaTextBlob is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
SkTextBlob* skTextBlob = skiaTextBlob->GetTextBlob().get();
|
||||
if (!skTextBlob) {
|
||||
skiaPaint_.Reset();
|
||||
LOGD("skTextBlob is null, return on line %{public}d", __LINE__);
|
||||
return;
|
||||
}
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawTextBlob(skTextBlob, x, y, *paint);
|
||||
}
|
||||
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawTextBlob(skTextBlob, x, y, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::DrawSymbol(const DrawingHMSymbolData& symbol, Point locate)
|
||||
void SkiaCanvas::DrawSymbol(const DrawingHMSymbolData& symbol, Point locate, const Paint& paint)
|
||||
{
|
||||
if (!skCanvas_) {
|
||||
LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
HMSymbolData skSymbol;
|
||||
if (!ConvertToHMSymbolData(symbol, skSymbol)) {
|
||||
LOGD("ConvertToHMSymbolData failed, return on line %{public}d", __LINE__);
|
||||
skiaPaint_.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
const SkPoint* skLocate = reinterpret_cast<const SkPoint*>(&locate);
|
||||
|
||||
SortedPaints& paints = skiaPaint_.GetSortedPaints();
|
||||
for (int i = 0; i < paints.count_; i++) {
|
||||
const SkPaint* paint = paints.paints_[i];
|
||||
skCanvas_->drawSymbol(skSymbol, *skLocate, *paint);
|
||||
}
|
||||
skPaint_ = defaultPaint_;
|
||||
SkiaPaint::PaintToSkPaint(paint, skPaint_);
|
||||
skCanvas_->drawSymbol(skSymbol, *skLocate, skPaint_);
|
||||
}
|
||||
|
||||
void SkiaCanvas::ClipRect(const Rect& rect, ClipOp op, bool doAntiAlias)
|
||||
@ -1199,11 +1093,6 @@ void SkiaCanvas::Discard()
|
||||
skCanvas_->discard();
|
||||
}
|
||||
|
||||
void SkiaCanvas::AttachPaint(const Paint& paint)
|
||||
{
|
||||
skiaPaint_.ApplyPaint(paint);
|
||||
}
|
||||
|
||||
void SkiaCanvas::RoundRectCastToSkRRect(const RoundRect& roundRect, SkRRect& skRRect) const
|
||||
{
|
||||
const SkRect* outer = reinterpret_cast<const SkRect*>(&roundRect.GetRect());
|
||||
|
@ -75,31 +75,31 @@ public:
|
||||
|
||||
// shapes
|
||||
void DrawSdf(const SDFShapeBase& shape) override;
|
||||
void DrawPoint(const Point& point) override;
|
||||
void DrawPoints(PointMode mode, size_t count, const Point pts[]) override;
|
||||
void DrawLine(const Point& startPt, const Point& endPt) override;
|
||||
void DrawRect(const Rect& rect) override;
|
||||
void DrawRoundRect(const RoundRect& roundRect) override;
|
||||
void DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner) override;
|
||||
void DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle) override;
|
||||
void DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle) override;
|
||||
void DrawOval(const Rect& oval) override;
|
||||
void DrawCircle(const Point& centerPt, scalar radius) override;
|
||||
void DrawPath(const Path& path) override;
|
||||
void DrawPoint(const Point& point, const Paint& paint) override;
|
||||
void DrawPoints(PointMode mode, size_t count, const Point pts[], const Paint& paint) override;
|
||||
void DrawLine(const Point& startPt, const Point& endPt, const Paint& paint) override;
|
||||
void DrawRect(const Rect& rect, const Paint& paint) override;
|
||||
void DrawRoundRect(const RoundRect& roundRect, const Paint& paint) override;
|
||||
void DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner, const Paint& paint) override;
|
||||
void DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle, const Paint& paint) override;
|
||||
void DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle, const Paint& paint) override;
|
||||
void DrawOval(const Rect& oval, const Paint& paint) override;
|
||||
void DrawCircle(const Point& centerPt, scalar radius, const Paint& paint) override;
|
||||
void DrawPath(const Path& path, const Paint& paint) override;
|
||||
void DrawBackground(const Brush& brush) override;
|
||||
void DrawShadow(const Path& path, const Point3& planeParams, const Point3& devLightPos, scalar lightRadius,
|
||||
Color ambientColor, Color spotColor, ShadowFlags flag) override;
|
||||
void DrawShadowStyle(const Path& path, const Point3& planeParams, const Point3& devLightPos, scalar lightRadius,
|
||||
Color ambientColor, Color spotColor, ShadowFlags flag, bool isLimitElevation) override;
|
||||
void DrawRegion(const Region& region) override;
|
||||
void DrawRegion(const Region& region, const Paint& paint) override;
|
||||
void DrawPatch(const Point cubics[12], const ColorQuad colors[4],
|
||||
const Point texCoords[4], BlendMode mode) override;
|
||||
void DrawVertices(const Vertices& vertices, BlendMode mode) override;
|
||||
const Point texCoords[4], BlendMode mode, const Paint& paint) override;
|
||||
void DrawVertices(const Vertices& vertices, BlendMode mode, const Paint& paint) override;
|
||||
|
||||
void DrawImageNine(const Image* image, const RectI& center, const Rect& dst,
|
||||
FilterMode filter, const Brush* brush = nullptr) override;
|
||||
void DrawImageLattice(const Image* image, const Lattice& lattice, const Rect& dst,
|
||||
FilterMode filter) override;
|
||||
FilterMode filter, const Paint& paint) override;
|
||||
|
||||
// color
|
||||
void DrawColor(ColorQuad color, BlendMode mode) override;
|
||||
@ -109,21 +109,23 @@ public:
|
||||
|
||||
// image
|
||||
void DrawAtlas(const Image* atlas, const RSXform xform[], const Rect tex[], const ColorQuad colors[], int count,
|
||||
BlendMode mode, const SamplingOptions& sampling, const Rect* cullRect) override;
|
||||
void DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py) override;
|
||||
void DrawImage(const Image& image, const scalar px, const scalar py, const SamplingOptions& sampling) override;
|
||||
BlendMode mode, const SamplingOptions& sampling, const Rect* cullRect, const Paint& paint) override;
|
||||
void DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py, const Paint& paint) override;
|
||||
void DrawImage(const Image& image, const scalar px, const scalar py, const SamplingOptions& sampling,
|
||||
const Paint& paint) override;
|
||||
void DrawImageRect(const Image& image, const Rect& src, const Rect& dst, const SamplingOptions& sampling,
|
||||
SrcRectConstraint constraint) override;
|
||||
void DrawImageRect(const Image& image, const Rect& dst, const SamplingOptions& sampling) override;
|
||||
SrcRectConstraint constraint, const Paint& paint) override;
|
||||
void DrawImageRect(const Image& image, const Rect& dst, const SamplingOptions& sampling,
|
||||
const Paint& paint) override;
|
||||
void DrawPicture(const Picture& picture) override;
|
||||
|
||||
void DrawSVGDOM(const sk_sp<SkSVGDOM>& svgDom) override;
|
||||
|
||||
// text
|
||||
void DrawTextBlob(const TextBlob* blob, const scalar x, const scalar y) override;
|
||||
void DrawTextBlob(const TextBlob* blob, const scalar x, const scalar y, const Paint& paint) override;
|
||||
|
||||
// symbol
|
||||
void DrawSymbol(const DrawingHMSymbolData& symbol, Point locate) override;
|
||||
void DrawSymbol(const DrawingHMSymbolData& symbol, Point locate, const Paint& paint) override;
|
||||
|
||||
// clip
|
||||
void ClipRect(const Rect& rect, ClipOp op, bool doAntiAlias) override;
|
||||
@ -154,9 +156,6 @@ public:
|
||||
uint32_t GetSaveCount() const override;
|
||||
void Discard() override;
|
||||
|
||||
// paint
|
||||
void AttachPaint(const Paint& paint) override;
|
||||
|
||||
SkCanvas* ExportSkCanvas() const;
|
||||
void ImportSkCanvas(SkCanvas* skCanvas);
|
||||
|
||||
@ -177,7 +176,8 @@ private:
|
||||
SkCanvas* skCanvas_;
|
||||
SkCanvas* skCanvasBackup_ = nullptr;
|
||||
std::shared_ptr<SkiaCanvasOp> skiaCanvasOp_ = nullptr;
|
||||
SkiaPaint skiaPaint_;
|
||||
SkPaint defaultPaint_;
|
||||
SkPaint skPaint_;
|
||||
};
|
||||
} // namespace Drawing
|
||||
} // namespace Rosen
|
||||
|
@ -170,27 +170,6 @@ SkiaPaint::SkiaPaint() noexcept {}
|
||||
|
||||
SkiaPaint::~SkiaPaint() {}
|
||||
|
||||
void SkiaPaint::ApplyPaint(const Paint& paint)
|
||||
{
|
||||
if (paintInUse_ >= MAX_PAINTS_NUMBER || !paint.IsValid()) {
|
||||
return;
|
||||
}
|
||||
SkPaint& skPaint = paints_[paintInUse_];
|
||||
skPaint = defaultPaint_;
|
||||
PaintToSkPaint(paint, skPaint);
|
||||
paintInUse_++;
|
||||
}
|
||||
|
||||
SortedPaints& SkiaPaint::GetSortedPaints()
|
||||
{
|
||||
sortedPaints_.count_ = paintInUse_;
|
||||
for (int i = 0; i < paintInUse_; i++) {
|
||||
sortedPaints_.paints_[i] = &paints_[i];
|
||||
}
|
||||
paintInUse_ = 0;
|
||||
return sortedPaints_;
|
||||
}
|
||||
|
||||
void SkiaPaint::ApplyFilter(SkPaint& paint, const Filter& filter)
|
||||
{
|
||||
if (const ColorFilter* cs = filter.GetColorFilterPtr()) {
|
||||
@ -262,11 +241,6 @@ bool SkiaPaint::AsBlendMode(const Brush& brush)
|
||||
BrushToSkPaint(brush, skPaint);
|
||||
return skPaint.asBlendMode().has_value();
|
||||
}
|
||||
|
||||
void SkiaPaint::Reset()
|
||||
{
|
||||
paintInUse_ = 0;
|
||||
}
|
||||
} // namespace Drawing
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
@ -34,10 +34,6 @@ namespace OHOS {
|
||||
namespace Rosen {
|
||||
namespace Drawing {
|
||||
const int MAX_PAINTS_NUMBER = 2;
|
||||
struct SortedPaints {
|
||||
SkPaint* paints_[MAX_PAINTS_NUMBER] = { 0 };
|
||||
int count_ = 0;
|
||||
};
|
||||
|
||||
class SkiaPaint {
|
||||
public:
|
||||
@ -48,10 +44,6 @@ public:
|
||||
static void PenToSkPaint(const Pen& pen, SkPaint& paint);
|
||||
static void PaintToSkPaint(const Paint& paint, SkPaint& skPaint);
|
||||
|
||||
void ApplyPaint(const Paint& paint);
|
||||
SortedPaints& GetSortedPaints();
|
||||
void Reset();
|
||||
|
||||
static bool GetFillPath(const Pen& pen, const Path& src, Path& dst, const Rect* rect, const Matrix& matrix);
|
||||
static bool CanComputeFastBounds(const Brush& brush);
|
||||
static const Rect& ComputeFastBounds(const Brush& brush, const Rect& orig, Rect* storage);
|
||||
@ -61,12 +53,6 @@ public:
|
||||
private:
|
||||
static void ApplyFilter(SkPaint& paint, const Filter& filter);
|
||||
static void ApplyStrokeParam(const Paint& paint, SkPaint& skPaint);
|
||||
|
||||
int paintInUse_ = 0;
|
||||
SkPaint paints_[MAX_PAINTS_NUMBER];
|
||||
SkPaint defaultPaint_;
|
||||
|
||||
SortedPaints sortedPaints_;
|
||||
};
|
||||
} // namespace Drawing
|
||||
} // namespace Rosen
|
||||
|
@ -467,23 +467,6 @@ bool SkiaPath::GetMatrix(bool forceClosed, float distance, Matrix* matrix, PathM
|
||||
&matrix->GetImpl<SkiaMatrix>()->ExportMatrix(), skFlag);
|
||||
}
|
||||
|
||||
int SkiaPath::GetVerbsCount() const
|
||||
{
|
||||
return path_.countVerbs();
|
||||
}
|
||||
|
||||
std::vector<PathVerb> SkiaPath::GetVerbs() const
|
||||
{
|
||||
int cnt = GetVerbsCount();
|
||||
uint8_t verbs[cnt];
|
||||
path_.getVerbs(verbs, cnt);
|
||||
std::vector<PathVerb> result;
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
result.push_back(static_cast<PathVerb>(verbs[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::shared_ptr<Data> SkiaPath::Serialize() const
|
||||
{
|
||||
SkBinaryWriteBuffer writer;
|
||||
|
@ -108,9 +108,6 @@ public:
|
||||
bool IsClosed(bool forceClosed) override;
|
||||
bool GetMatrix(bool forceClosed, float distance, Matrix* matrix, PathMeasureMatrixFlags flag) override;
|
||||
|
||||
int GetVerbsCount() const override;
|
||||
std::vector<PathVerb> GetVerbs() const override;
|
||||
|
||||
std::shared_ptr<Data> Serialize() const override;
|
||||
bool Deserialize(std::shared_ptr<Data> data) override;
|
||||
private:
|
||||
|
@ -39,6 +39,11 @@ std::shared_ptr<TextBlob> StaticFactory::MakeFromText(const void* text, size_t b
|
||||
std::shared_ptr<TextBlob> StaticFactory::MakeFromPosText(const void* text, size_t byteLength,
|
||||
const Point pos[], const Font& font, TextEncoding encoding)
|
||||
{
|
||||
#ifdef ENABLE_DDGR_OPTIMIZE
|
||||
if (SystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
|
||||
return DDGRStaticFactory::MakeFromPosText(text, byteLength, pos, font, encoding);
|
||||
}
|
||||
#endif
|
||||
return EngineStaticFactory::MakeFromPosText(text, byteLength, pos, font, encoding);
|
||||
}
|
||||
|
||||
@ -138,6 +143,11 @@ std::shared_ptr<Surface> StaticFactory::MakeRenderTarget(GPUContext* gpuContext,
|
||||
|
||||
std::shared_ptr<Image> StaticFactory::MakeFromYUVAPixmaps(GPUContext& gpuContext, const YUVInfo& info, void* memory)
|
||||
{
|
||||
#ifdef ENABLE_DDGR_OPTIMIZE
|
||||
if (SystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
|
||||
return DDGRStaticFactory::MakeFromYUVAPixmaps(gpuContext, info, memory);
|
||||
}
|
||||
#endif
|
||||
return EngineStaticFactory::MakeFromYUVAPixmaps(gpuContext, info, memory);
|
||||
}
|
||||
#endif
|
||||
@ -208,8 +218,7 @@ std::shared_ptr<Typeface> StaticFactory::DeserializeTypeface(const void* data, s
|
||||
{
|
||||
#ifdef ENABLE_DDGR_OPTIMIZE
|
||||
if (SystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
|
||||
// DDGR need to be adapted
|
||||
return nullptr;
|
||||
return DDGRStaticFactory::DeserializeTypeface(data, size);
|
||||
}
|
||||
#endif
|
||||
return EngineStaticFactory::DeserializeTypeface(data, size);
|
||||
@ -218,7 +227,9 @@ std::shared_ptr<Typeface> StaticFactory::DeserializeTypeface(const void* data, s
|
||||
bool StaticFactory::GetFillPath(const Pen& pen, const Path& src, Path& dst, const Rect* rect, const Matrix& matrix)
|
||||
{
|
||||
#ifdef ENABLE_DDGR_OPTIMIZE
|
||||
// DDGR need to be adapted
|
||||
if (SystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
|
||||
return DDGRStaticFactory::GetFillPath(pen, src, dst, rect, matrix);
|
||||
}
|
||||
#endif
|
||||
return EngineStaticFactory::GetFillPath(pen, src, dst, rect, matrix);
|
||||
}
|
||||
@ -306,6 +317,11 @@ Path StaticFactory::GetDrawingPathforTextBlob(uint16_t glyphId, const TextBlob*
|
||||
|
||||
void StaticFactory::GetDrawingPointsForTextBlob(const TextBlob* blob, std::vector<Point>& points)
|
||||
{
|
||||
#ifdef ENABLE_DDGR_OPTIMIZE
|
||||
if (SystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
|
||||
return DDGRStaticFactory::GetDrawingPointsForTextBlob(blob, points);
|
||||
}
|
||||
#endif
|
||||
return EngineStaticFactory::GetDrawingPointsForTextBlob(blob, points);
|
||||
}
|
||||
|
||||
@ -322,6 +338,11 @@ DrawingSymbolLayersGroups StaticFactory::GetSymbolLayersGroups(uint32_t glyphId)
|
||||
std::vector<std::vector<DrawingPiecewiseParameter>> StaticFactory::GetGroupParameters(
|
||||
DrawingAnimationType type, uint16_t groupSum, uint16_t animationMode, DrawingCommonSubType commonSubType)
|
||||
{
|
||||
#ifdef ENABLE_DDGR_OPTIMIZE
|
||||
if (SystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
|
||||
return DDGRStaticFactory::GetGroupParameters(type, groupSum, animationMode, commonSubType);
|
||||
}
|
||||
#endif
|
||||
return EngineStaticFactory::GetGroupParameters(type, groupSum, animationMode, commonSubType);
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ bool UnmarshallingPlayer::RegisterUnmarshallingFunc(uint32_t type, Unmarshalling
|
||||
static std::unordered_map<uint32_t, UnmarshallingPlayer::UnmarshallingFunc> opUnmarshallingFuncLUT = {};
|
||||
opUnmarshallingFuncLUT_ = &opUnmarshallingFuncLUT;
|
||||
}
|
||||
std::unique_lock<std::shared_timed_mutex> lock(UnmarshallingFuncMapMutex_);
|
||||
std::unique_lock<std::mutex> lock(UnmarshallingFuncMapMutex_);
|
||||
return opUnmarshallingFuncLUT_->emplace(type, func).second;
|
||||
}
|
||||
|
||||
@ -571,54 +571,6 @@ void DrawPathOpItem::Playback(Canvas* canvas, const Rect* rect)
|
||||
canvas->DrawPath(*path_);
|
||||
}
|
||||
|
||||
std::shared_ptr<DrawImageRectOpItem> DrawPathOpItem::GenerateQuadCachedOpItem(Canvas* canvas)
|
||||
{
|
||||
if (!path_ || paint_.GetWidth() > 1.f) { // only cache when stroke width is too small
|
||||
return nullptr;
|
||||
}
|
||||
auto verbs = path_->GetVerbs();
|
||||
if (std::find(verbs.begin(), verbs.end(), PathVerb::Quad) == verbs.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto bounds = path_->GetBounds();
|
||||
if (!bounds.IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<Surface> offscreenSurface = nullptr;
|
||||
|
||||
if (auto surface = canvas != nullptr ? canvas->GetSurface() : nullptr) {
|
||||
// create GPU accelerated surface if possible
|
||||
offscreenSurface = surface->MakeSurface(bounds.GetWidth(), bounds.GetHeight());
|
||||
} else {
|
||||
// create CPU raster surface
|
||||
Drawing::ImageInfo offscreenInfo { bounds.GetWidth(), bounds.GetHeight(), Drawing::COLORTYPE_RGBA_8888,
|
||||
Drawing::ALPHATYPE_PREMUL, nullptr };
|
||||
offscreenSurface = Surface::MakeRaster(offscreenInfo);
|
||||
}
|
||||
if (offscreenSurface == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Canvas* offscreenCanvas = offscreenSurface->GetCanvas().get();
|
||||
|
||||
// align draw op to [0, 0]
|
||||
if (bounds.GetLeft() != 0 || bounds.GetTop() != 0) {
|
||||
offscreenCanvas->Translate(-bounds.GetLeft(), -bounds.GetTop());
|
||||
}
|
||||
Playback(offscreenCanvas, nullptr);
|
||||
std::shared_ptr<Image> image = offscreenSurface->GetImageSnapshot();
|
||||
Drawing::Rect src(0, 0, image->GetWidth(), image->GetHeight());
|
||||
Drawing::Rect dst(bounds.GetLeft(), bounds.GetTop(), bounds.GetRight(), bounds.GetBottom());
|
||||
Paint fakePaint;
|
||||
fakePaint.SetStyle(Paint::PaintStyle::PAINT_FILL);
|
||||
fakePaint.SetAntiAlias(true);
|
||||
return std::make_shared<DrawImageRectOpItem>(*image, src, dst,
|
||||
Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::LINEAR),
|
||||
SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT, fakePaint);
|
||||
}
|
||||
|
||||
/* DrawBackgroundOpItem */
|
||||
REGISTER_UNMARSHALLING_FUNC(DrawBackground, DrawOpItem::BACKGROUND_OPITEM, DrawBackgroundOpItem::Unmarshalling);
|
||||
|
||||
|
@ -440,27 +440,6 @@ void DrawCmdList::GenerateCacheByBuffer(Canvas* canvas, const Rect* rect)
|
||||
#endif
|
||||
}
|
||||
|
||||
void DrawCmdList::CacheQuadPath()
|
||||
{
|
||||
#ifdef ROSEN_OHOS
|
||||
if (drawOpItems_.size() == 0) {
|
||||
return;
|
||||
}
|
||||
uint32_t opSize = drawOpItems_.size();
|
||||
for (auto index = 0u; index < opSize; ++index) {
|
||||
std::shared_ptr<DrawOpItem> op = drawOpItems_[index];
|
||||
if (!op || op->GetType() != DrawOpItem::PATH_OPITEM) {
|
||||
continue;
|
||||
}
|
||||
DrawPathOpItem* pathOp = static_cast<DrawPathOpItem*>(op.get());
|
||||
auto replaceCache = pathOp->GenerateQuadCachedOpItem(nullptr);
|
||||
if (replaceCache) {
|
||||
drawOpItems_[index] = replaceCache;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DrawCmdList::PlaybackToDrawCmdList(std::shared_ptr<DrawCmdList> drawCmdList)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
||||
|
@ -89,7 +89,7 @@ public:
|
||||
const std::vector<GraphicHDRMetaData> &graphicMetaData) = 0;
|
||||
virtual int32_t SetLayerMetaDataSet(uint32_t screenId, uint32_t layerId, GraphicHDRMetadataKey gkey,
|
||||
const std::vector<uint8_t> &metaData) = 0;
|
||||
virtual int32_t GetSupportedLayerPerFrameParameterKey(std::vector<std::string>& keys) = 0;
|
||||
virtual std::vector<std::string>& GetSupportedLayerPerFrameParameterKey() = 0;
|
||||
virtual int32_t SetLayerPerFrameParameter(uint32_t devId, uint32_t layerId, const std::string& key,
|
||||
const std::vector<int8_t>& value) = 0;
|
||||
virtual int32_t SetLayerTunnelHandle(uint32_t screenId, uint32_t layerId, GraphicExtDataHandle *handle) = 0;
|
||||
|
@ -88,7 +88,7 @@ public:
|
||||
const std::vector<GraphicHDRMetaData> &metaData) override;
|
||||
int32_t SetLayerMetaDataSet(uint32_t screenId, uint32_t layerId, GraphicHDRMetadataKey key,
|
||||
const std::vector<uint8_t> &metaData) override;
|
||||
int32_t GetSupportedLayerPerFrameParameterKey(std::vector<std::string>& keys) override;
|
||||
std::vector<std::string>& GetSupportedLayerPerFrameParameterKey() override;
|
||||
int32_t SetLayerPerFrameParameter(uint32_t devId, uint32_t layerId, const std::string& key,
|
||||
const std::vector<int8_t>& value) override;
|
||||
int32_t SetLayerTunnelHandle(uint32_t screenId, uint32_t layerId, GraphicExtDataHandle *handle) override;
|
||||
@ -108,6 +108,9 @@ private:
|
||||
HdiDeviceImpl& operator=(const HdiDeviceImpl& rhs) = delete;
|
||||
HdiDeviceImpl(HdiDeviceImpl&& rhs) = delete;
|
||||
HdiDeviceImpl& operator=(HdiDeviceImpl&& rhs) = delete;
|
||||
|
||||
std::once_flag layerPerFrameParameterKeyCreateFlag_;
|
||||
std::vector<std::string> layerPerFrameParameterKeys_ = {};
|
||||
};
|
||||
|
||||
} // namespace Rosen
|
||||
|
@ -93,7 +93,7 @@ private:
|
||||
HdiDevice *device_ = nullptr;
|
||||
bool doLayerInfoCompare_ = false;
|
||||
|
||||
std::vector<sptr<SurfaceBuffer> > bufferCache_;
|
||||
std::vector<uint32_t> bufferCache_;
|
||||
uint32_t bufferCacheCountMax_ = 0;
|
||||
|
||||
int32_t CreateLayer(const LayerInfoPtr &layerInfo);
|
||||
@ -122,8 +122,12 @@ private:
|
||||
bool IsSameLayerMetaDataSet();
|
||||
inline void CheckRet(int32_t ret, const char* func);
|
||||
int32_t SetLayerMaskInfo();
|
||||
bool CheckAndUpdateLayerBufferCahce(sptr<SurfaceBuffer> buffer, uint32_t& index,
|
||||
bool CheckAndUpdateLayerBufferCahce(uint32_t sequence, uint32_t& index,
|
||||
std::vector<uint32_t>& deletingList);
|
||||
|
||||
int32_t SetPerFrameParameters();
|
||||
int32_t SetPerFrameParameterDisplayNit();
|
||||
int32_t SetPerFrameParameterBrightnessRatio();
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -382,6 +382,26 @@ public:
|
||||
presentTimestamp_ = timestamp;
|
||||
}
|
||||
|
||||
int32_t GetDisplayNit() const
|
||||
{
|
||||
return displayNit_;
|
||||
}
|
||||
|
||||
float GetBrightnessRatio() const
|
||||
{
|
||||
return brightnessRatio_;
|
||||
}
|
||||
|
||||
int32_t SetDisplayNit(int32_t displayNit)
|
||||
{
|
||||
return displayNit_ = displayNit;
|
||||
}
|
||||
|
||||
int32_t SetBrightnessRatio(float brightnessRatio)
|
||||
{
|
||||
return brightnessRatio_ = brightnessRatio;
|
||||
}
|
||||
|
||||
void CopyLayerInfo(const std::shared_ptr<HdiLayerInfo> &layerInfo)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
@ -408,6 +428,8 @@ public:
|
||||
pbuffer_= layerInfo->GetPreBuffer();
|
||||
acquireFence_ = layerInfo->GetAcquireFence();
|
||||
preMulti_ = layerInfo->IsPreMulti();
|
||||
displayNit_ = layerInfo->GetDisplayNit();
|
||||
brightnessRatio_ = layerInfo->GetBrightnessRatio();
|
||||
}
|
||||
|
||||
void Dump(std::string &result) const
|
||||
@ -452,6 +474,8 @@ public:
|
||||
if (cSurface_ != nullptr) {
|
||||
cSurface_->Dump(result);
|
||||
}
|
||||
result += " displayNit = " + std::to_string(displayNit_) +
|
||||
", brightnessRatio = " + std::to_string(brightnessRatio_) + ", ";
|
||||
}
|
||||
|
||||
RosenError SetLayerMaskInfo(LayerMask mask)
|
||||
@ -508,6 +532,8 @@ private:
|
||||
bool preMulti_ = false;
|
||||
LayerMask layerMask_ = LayerMask::LAYER_MASK_NORMAL;
|
||||
mutable std::mutex mutex_;
|
||||
int32_t displayNit_ = 500; // default luminance for sdr
|
||||
float brightnessRatio_ = 1.0f; // default ratio for sdr
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -624,10 +624,18 @@ int32_t HdiDeviceImpl::SetLayerMetaDataSet(uint32_t screenId, uint32_t layerId,
|
||||
return g_composer->SetLayerMetaDataSet(screenId, layerId, hdiKey, metaData);
|
||||
}
|
||||
|
||||
int32_t HdiDeviceImpl::GetSupportedLayerPerFrameParameterKey(std::vector<std::string>& keys)
|
||||
std::vector<std::string>& HdiDeviceImpl::GetSupportedLayerPerFrameParameterKey()
|
||||
{
|
||||
CHECK_FUNC(g_composer);
|
||||
return g_composer->GetSupportedLayerPerFrameParameterKey(keys);
|
||||
std::call_once(layerPerFrameParameterKeyCreateFlag_, [this]() {
|
||||
CHECK_FUNC(g_composer);
|
||||
if (g_composer->GetSupportedLayerPerFrameParameterKey(layerPerFrameParameterKeys_) != 0) {
|
||||
HLOGW("get supported layer perframe parameter key failed!");
|
||||
}
|
||||
|
||||
return GRAPHIC_DISPLAY_SUCCESS;
|
||||
});
|
||||
|
||||
return layerPerFrameParameterKeys_;
|
||||
}
|
||||
|
||||
int32_t HdiDeviceImpl::SetLayerPerFrameParameter(uint32_t devId, uint32_t layerId, const std::string& key,
|
||||
|
@ -22,6 +22,8 @@ constexpr float SIXTY_SIX_INTERVAL_IN_MS = 66.f;
|
||||
constexpr float THIRTY_THREE_INTERVAL_IN_MS = 33.f;
|
||||
constexpr float SIXTEEN_INTERVAL_IN_MS = 16.67f;
|
||||
constexpr float FPS_TO_MS = 1000000.f;
|
||||
const std::string GENERIC_METADATA_KEY_SDR_RATIO = "SDRBrightnessRatio";
|
||||
const std::string GENERIC_METADATA_KEY_BRIGHTNESS_NIT = "BrightnessNit";
|
||||
|
||||
template<typename T>
|
||||
bool Compare(const T& lhs, const T& rhs)
|
||||
@ -244,12 +246,12 @@ int32_t HdiLayer::SetLayerDirtyRegion()
|
||||
return GRAPHIC_DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
bool HdiLayer::CheckAndUpdateLayerBufferCahce(sptr<SurfaceBuffer> buffer, uint32_t& index,
|
||||
bool HdiLayer::CheckAndUpdateLayerBufferCahce(uint32_t sequence, uint32_t& index,
|
||||
std::vector<uint32_t>& deletingList)
|
||||
{
|
||||
uint32_t bufferCacheSize = (uint32_t)bufferCache_.size();
|
||||
for (uint32_t i = 0; i < bufferCacheSize; i++) {
|
||||
if (bufferCache_[i] == buffer) {
|
||||
if (bufferCache_[i] == sequence) {
|
||||
index = i;
|
||||
return true;
|
||||
}
|
||||
@ -262,7 +264,7 @@ bool HdiLayer::CheckAndUpdateLayerBufferCahce(sptr<SurfaceBuffer> buffer, uint32
|
||||
bufferCache_.clear();
|
||||
}
|
||||
index = (uint32_t)bufferCache_.size();
|
||||
bufferCache_.push_back(buffer);
|
||||
bufferCache_.push_back(sequence);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -288,7 +290,7 @@ int32_t HdiLayer::SetLayerBuffer()
|
||||
bufferCache_.clear();
|
||||
HLOGE("The count of this layer buffer cache is 0.");
|
||||
} else {
|
||||
bufferCached = CheckAndUpdateLayerBufferCahce(currBuffer, index, deletingList);
|
||||
bufferCached = CheckAndUpdateLayerBufferCahce(currBuffer->GetSeqNum(), index, deletingList);
|
||||
}
|
||||
|
||||
GraphicLayerBuffer layerBuffer;
|
||||
@ -556,6 +558,8 @@ int32_t HdiLayer::SetHdiLayerInfo()
|
||||
CheckRet(ret, "SetLayerPresentTimestamp");
|
||||
ret = SetLayerMaskInfo();
|
||||
CheckRet(ret, "SetLayerMask");
|
||||
ret = SetPerFrameParameters();
|
||||
CheckRet(ret, "SetPerFrameParameters");
|
||||
|
||||
return GRAPHIC_DISPLAY_SUCCESS;
|
||||
}
|
||||
@ -740,5 +744,47 @@ void HdiLayer::ClearDump()
|
||||
mergedPresentTimeRecords.fill(0);
|
||||
}
|
||||
|
||||
int32_t HdiLayer::SetPerFrameParameters()
|
||||
{
|
||||
const auto& supportedKeys = device_->GetSupportedLayerPerFrameParameterKey();
|
||||
int32_t ret = GRAPHIC_DISPLAY_SUCCESS;
|
||||
for (const auto& key : supportedKeys) {
|
||||
if (key == GENERIC_METADATA_KEY_BRIGHTNESS_NIT) {
|
||||
ret = SetPerFrameParameterDisplayNit();
|
||||
CheckRet(ret, "SetPerFrameParameterDisplayNit");
|
||||
} else if (key == GENERIC_METADATA_KEY_SDR_RATIO) {
|
||||
ret = SetPerFrameParameterBrightnessRatio();
|
||||
CheckRet(ret, "SetPerFrameParameterBrightnessRatio");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HdiLayer::SetPerFrameParameterDisplayNit()
|
||||
{
|
||||
if (doLayerInfoCompare_) {
|
||||
if (layerInfo_->GetDisplayNit() == prevLayerInfo_->GetDisplayNit()) {
|
||||
return GRAPHIC_DISPLAY_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int8_t> valueBlob(sizeof(int32_t));
|
||||
*reinterpret_cast<int32_t*>(valueBlob.data()) = layerInfo_->GetDisplayNit();
|
||||
return device_->SetLayerPerFrameParameter(screenId_, layerId_, GENERIC_METADATA_KEY_BRIGHTNESS_NIT, valueBlob);
|
||||
}
|
||||
|
||||
int32_t HdiLayer::SetPerFrameParameterBrightnessRatio()
|
||||
{
|
||||
if (doLayerInfoCompare_) {
|
||||
if (layerInfo_->GetBrightnessRatio() == prevLayerInfo_->GetBrightnessRatio()) {
|
||||
return GRAPHIC_DISPLAY_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int8_t> valueBlob(sizeof(float));
|
||||
*reinterpret_cast<float*>(valueBlob.data()) = layerInfo_->GetBrightnessRatio();
|
||||
return device_->SetLayerPerFrameParameter(screenId_, layerId_, GENERIC_METADATA_KEY_SDR_RATIO, valueBlob);
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -191,26 +191,24 @@ int32_t HdiOutput::CreateLayer(uint64_t surfaceId, const LayerInfoPtr &layerInfo
|
||||
}
|
||||
surfaceIdMap_[surfaceId] = layer;
|
||||
|
||||
if (device_ == nullptr) {
|
||||
HLOGE("[%{public}s]HdiDevice is nullptr.", __func__);
|
||||
return GRAPHIC_DISPLAY_SUCCESS;
|
||||
}
|
||||
// DISPLAY ENGINE
|
||||
if (!arsrPreEnabled_) {
|
||||
return GRAPHIC_DISPLAY_SUCCESS;
|
||||
}
|
||||
int32_t ret = 0;
|
||||
std::vector<std::string> validKeys{};
|
||||
ret = device_->GetSupportedLayerPerFrameParameterKey(validKeys);
|
||||
if (ret != 0) {
|
||||
HLOGD("GetSupportedLayerPreFrameParameter Fail! ret = %{public}d", ret);
|
||||
return GRAPHIC_DISPLAY_SUCCESS;
|
||||
}
|
||||
|
||||
const auto& validKeys = device_->GetSupportedLayerPerFrameParameterKey();
|
||||
const std::string GENERIC_METADATA_KEY_ARSR_PRE_NEEDED = "ArsrDoEnhance";
|
||||
if (std::find(validKeys.begin(), validKeys.end(), GENERIC_METADATA_KEY_ARSR_PRE_NEEDED) != validKeys.end()) {
|
||||
if (CheckIfDoArsrPre(layerInfo)) {
|
||||
const std::vector<int8_t> valueBlob{static_cast<int8_t>(1)};
|
||||
ret = device_->SetLayerPerFrameParameter(screenId_, layerId,
|
||||
GENERIC_METADATA_KEY_ARSR_PRE_NEEDED, valueBlob);
|
||||
}
|
||||
if (ret != 0) {
|
||||
HLOGD("SetLayerPerFrameParameter Fail! ret = %{public}d", ret);
|
||||
if (device_->SetLayerPerFrameParameter(screenId_,
|
||||
layerId, GENERIC_METADATA_KEY_ARSR_PRE_NEEDED, valueBlob) != 0) {
|
||||
HLOGE("SetLayerPerFrameParameter Fail!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,7 @@ namespace OHOS {
|
||||
device->SetLayerMaskInfo(screenId, layerId, maskInfo);
|
||||
|
||||
// DISPLAY ENGINE
|
||||
std::vector<std::string> keys{};
|
||||
device->GetSupportedLayerPerFrameParameterKey(keys);
|
||||
std::vector<std::string> keys = device->GetSupportedLayerPerFrameParameterKey();
|
||||
std::vector<int8_t> valueBlob{static_cast<int8_t>(1)};
|
||||
std::string validKey = "ArsrDoEnhance";
|
||||
device->SetLayerPerFrameParameter(screenId, layerId, validKey, valueBlob);
|
||||
@ -104,7 +103,7 @@ namespace OHOS {
|
||||
float matrixElement = GetData<float>();
|
||||
std::vector<float> matrix = { matrixElement };
|
||||
GraphicColorDataSpace colorSpace = GetData<GraphicColorDataSpace>();
|
||||
|
||||
|
||||
uint32_t deletingIndex = GetData<uint32_t>();
|
||||
std::vector<uint32_t> deletingList = { deletingIndex };
|
||||
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
MOCK_METHOD3(GetLayerColorDataSpace, int32_t(uint32_t, uint32_t, GraphicColorDataSpace&));
|
||||
MOCK_METHOD3(SetLayerMetaData, int32_t(uint32_t, uint32_t, const std::vector<GraphicHDRMetaData>&));
|
||||
MOCK_METHOD4(SetLayerMetaDataSet, int32_t(uint32_t, uint32_t, GraphicHDRMetadataKey, const std::vector<uint8_t>&));
|
||||
MOCK_METHOD1(GetSupportedLayerPerFrameParameterKey, int32_t(std::vector<std::string>&));
|
||||
MOCK_METHOD0(GetSupportedLayerPerFrameParameterKey, std::vector<std::string>&());
|
||||
MOCK_METHOD4(SetLayerPerFrameParameter,
|
||||
int32_t(uint32_t, uint32_t, const std::string&, const std::vector<int8_t>&));
|
||||
MOCK_METHOD3(SetLayerTunnelHandle, int32_t(uint32_t, uint32_t, GraphicExtDataHandle *));
|
||||
|
@ -62,6 +62,7 @@ void HdiLayerTest::SetUpTestCase()
|
||||
layerInfo_->SetBuffer(buffer, fence);
|
||||
|
||||
hdiDeviceMock_ = Mock::HdiDeviceMock::GetInstance();
|
||||
std::vector<std::string> paramKey;
|
||||
EXPECT_CALL(*hdiDeviceMock_, SetLayerAlpha(_, _, _)).WillRepeatedly(testing::Return(0));
|
||||
EXPECT_CALL(*hdiDeviceMock_, SetLayerSize(_, _, _)).WillRepeatedly(testing::Return(0));
|
||||
EXPECT_CALL(*hdiDeviceMock_, SetTransformMode(_, _, _)).WillRepeatedly(testing::Return(0));
|
||||
@ -78,7 +79,7 @@ void HdiLayerTest::SetUpTestCase()
|
||||
EXPECT_CALL(*hdiDeviceMock_, GetLayerColorDataSpace(_, _, _)).WillRepeatedly(testing::Return(0));
|
||||
EXPECT_CALL(*hdiDeviceMock_, SetLayerMetaData(_, _, _)).WillRepeatedly(testing::Return(0));
|
||||
EXPECT_CALL(*hdiDeviceMock_, SetLayerMetaDataSet(_, _, _, _)).WillRepeatedly(testing::Return(0));
|
||||
EXPECT_CALL(*hdiDeviceMock_, GetSupportedLayerPerFrameParameterKey(_)).WillRepeatedly(testing::Return(0));
|
||||
EXPECT_CALL(*hdiDeviceMock_, GetSupportedLayerPerFrameParameterKey()).WillRepeatedly(testing::ReturnRef(paramKey));
|
||||
EXPECT_CALL(*hdiDeviceMock_, SetLayerPerFrameParameter(_, _, _, _)).WillRepeatedly(testing::Return(0));
|
||||
EXPECT_CALL(*hdiDeviceMock_, SetLayerTunnelHandle(_, _, _)).WillRepeatedly(testing::Return(0));
|
||||
EXPECT_CALL(*hdiDeviceMock_, GetSupportedPresentTimestampType(_, _, _)).WillRepeatedly(testing::Return(0));
|
||||
|
@ -252,7 +252,7 @@ HWTEST_F(HdiOutputTest, Commit002, Function | MediumTest| Level1)
|
||||
*/
|
||||
HWTEST_F(HdiOutputTest, ClearFrameBuffer002, Function | MediumTest | Level1)
|
||||
{
|
||||
ASSERT_EQ(HdiOutputTest::hdiOutput_->ClearFrameBuffer(), GSERROR_INVALID_OPERATING);
|
||||
ASSERT_EQ(HdiOutputTest::hdiOutput_->ClearFrameBuffer(), GSERROR_CONSUMER_DISCONNECTED);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
MOCK_METHOD3(GetLayerColorDataSpace, int32_t(uint32_t, uint32_t, GraphicColorDataSpace&));
|
||||
MOCK_METHOD3(SetLayerMetaData, int32_t(uint32_t, uint32_t, const std::vector<GraphicHDRMetaData>&));
|
||||
MOCK_METHOD4(SetLayerMetaDataSet, int32_t(uint32_t, uint32_t, GraphicHDRMetadataKey, const std::vector<uint8_t>&));
|
||||
MOCK_METHOD1(GetSupportedLayerPerFrameParameterKey, int32_t(std::vector<std::string>&));
|
||||
MOCK_METHOD0(GetSupportedLayerPerFrameParameterKey, std::vector<std::string>&());
|
||||
MOCK_METHOD4(SetLayerPerFrameParameter,
|
||||
int32_t(uint32_t, uint32_t, const std::string&, const std::vector<int8_t>&));
|
||||
MOCK_METHOD3(SetLayerTunnelHandle, int32_t(uint32_t, uint32_t, GraphicExtDataHandle *));
|
||||
|
@ -137,7 +137,7 @@ private:
|
||||
int64_t vsyncCount; // used for LTPS
|
||||
int64_t period;
|
||||
int64_t vsyncPulseCount; // used for LTPO
|
||||
int32_t refreshRate;
|
||||
uint32_t refreshRate;
|
||||
};
|
||||
void ThreadMain();
|
||||
void EnableVSync();
|
||||
@ -187,6 +187,7 @@ private:
|
||||
sptr<DVsync> dvsync_ = nullptr;
|
||||
bool pendingRNVInVsync_ = false; // for vsync switch to dvsync
|
||||
std::atomic<int64_t> lastDVsyncTS_ = 0; // for dvsync switch to vsync
|
||||
void UpdateVsyncPeriodAndRefreshRate();
|
||||
#endif
|
||||
bool isRs_ = false;
|
||||
};
|
||||
|
@ -93,7 +93,7 @@ private:
|
||||
int64_t period_;
|
||||
int64_t phase_;
|
||||
int64_t referenceTime_;
|
||||
int64_t error_;
|
||||
double error_;
|
||||
int64_t samples_[MAX_SAMPLES] = {0};
|
||||
int64_t presentFenceTime_[NUM_PRESENT] = {-1};
|
||||
uint32_t firstSampleIndex_;
|
||||
|
@ -55,9 +55,14 @@ VsyncError VSyncConnectionProxy::GetReceiveFd(int32_t &fd)
|
||||
arg.WriteInterfaceToken(GetDescriptor());
|
||||
int res = Remote()->SendRequest(IVSYNC_CONNECTION_GET_RECEIVE_FD, arg, ret, opt);
|
||||
if (res != NO_ERROR) {
|
||||
VLOGE("GetReceiveFd Failed, res = %{public}d", res);
|
||||
return VSYNC_ERROR_BINDER_ERROR;
|
||||
}
|
||||
fd = ret.ReadFileDescriptor();
|
||||
if (fd <= 0) {
|
||||
VLOGE("GetReceiveFd Invalid fd:%{public}d", fd);
|
||||
return VSYNC_ERROR_API_FAILED;
|
||||
}
|
||||
return VSYNC_ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -140,6 +140,10 @@ VsyncError VSyncConnection::GetReceiveFd(int32_t &fd)
|
||||
return VSYNC_ERROR_API_FAILED;
|
||||
}
|
||||
fd = socketPair_->GetReceiveDataFd();
|
||||
if (fd <= 0) {
|
||||
VLOGE("%{public}s socketPair invalid fd:%{public}d.", __func__, fd);
|
||||
return VSYNC_ERROR_API_FAILED;
|
||||
}
|
||||
return VSYNC_ERROR_OK;
|
||||
}
|
||||
|
||||
@ -457,16 +461,12 @@ bool VSyncDistributor::PostVSyncEventPreProcess(int64_t ×tamp, std::vector<
|
||||
#if defined(RS_ENABLE_DVSYNC)
|
||||
// ensure the preexecution only gets ahead for at most one period(i.e., 3 buffer rotation)
|
||||
if (IsDVsyncOn()) {
|
||||
int64_t periodBeforeDelay = 0L;
|
||||
int64_t periodAfterDelay = 0L;
|
||||
{
|
||||
std::unique_lock<std::mutex> locker(mutex_);
|
||||
periodBeforeDelay = event_.period;
|
||||
dvsync_->MarkDistributorSleep(true);
|
||||
dvsync_->RNVNotify();
|
||||
dvsync_->DelayBeforePostEvent(timestamp, locker);
|
||||
dvsync_->MarkDistributorSleep(false);
|
||||
periodAfterDelay = event_.period;
|
||||
}
|
||||
// if getting switched into vsync mode after sleep
|
||||
if (!IsDVsyncOn()) {
|
||||
@ -476,9 +476,6 @@ bool VSyncDistributor::PostVSyncEventPreProcess(int64_t ×tamp, std::vector<
|
||||
RequestNextVSync(conn);
|
||||
} // resend RNV for vsync
|
||||
return false; // do not accumulate frame;
|
||||
} else if (!IsUiDvsyncOn() && std::abs(periodAfterDelay - periodBeforeDelay) > MAX_PERIOD_BIAS) {
|
||||
timestamp = timestamp + periodAfterDelay - periodBeforeDelay;
|
||||
dvsync_->SetLastVirtualVSyncTS(timestamp);
|
||||
}
|
||||
}
|
||||
{
|
||||
@ -512,13 +509,17 @@ void VSyncDistributor::OnDVSyncTrigger(int64_t now, int64_t period, uint32_t ref
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(mutex_);
|
||||
vsyncMode_ = vsyncMode;
|
||||
event_.period = period;
|
||||
dvsync_->RuntimeSwitch();
|
||||
if (IsDVsyncOn()) {
|
||||
if (isRs_ && event_.period != 0 && event_.refreshRate != 0) {
|
||||
period = event_.period;
|
||||
refreshRate = event_.refreshRate;
|
||||
}
|
||||
ScopedBytrace func("VSyncD onVSyncEvent, now:" + std::to_string(now));
|
||||
} else {
|
||||
ScopedBytrace func("VSync onVSyncEvent, now:" + std::to_string(now));
|
||||
}
|
||||
event_.period = period;
|
||||
|
||||
dvsync_->RecordVSync(now, period, refreshRate);
|
||||
dvsync_->NotifyPreexecuteWait();
|
||||
@ -745,6 +746,16 @@ void VSyncDistributor::CollectConnectionsLTPO(bool &waitForVSync, int64_t timest
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(RS_ENABLE_DVSYNC)
|
||||
void VSyncDistributor::UpdateVsyncPeriodAndRefreshRate()
|
||||
{
|
||||
std::unique_lock<std::mutex> locker(mutex_);
|
||||
event_.refreshRate = dvsync_->GetImmediateRefreshRate();
|
||||
event_.period = dvsync_->GetImmediatePeriod();
|
||||
dvsync_->UpdateVsyncPeriodAndRefreshRate(event_.period, event_.refreshRate);
|
||||
}
|
||||
#endif
|
||||
|
||||
void VSyncDistributor::PostVSyncEvent(const std::vector<sptr<VSyncConnection>> &conns, int64_t timestamp)
|
||||
{
|
||||
#if defined(RS_ENABLE_DVSYNC)
|
||||
@ -762,6 +773,11 @@ void VSyncDistributor::PostVSyncEvent(const std::vector<sptr<VSyncConnection>> &
|
||||
(generatorRefreshRate_ % conns[i]->refreshRate_ == 0)) {
|
||||
period = event_.period * static_cast<int64_t>(generatorRefreshRate_ / conns[i]->refreshRate_);
|
||||
}
|
||||
#if defined(RS_ENABLE_DVSYNC)
|
||||
if (isRs_) {
|
||||
UpdateVsyncPeriodAndRefreshRate();
|
||||
}
|
||||
#endif
|
||||
int32_t ret = conns[i]->PostEvent(timestamp, period, event_.vsyncCount);
|
||||
VLOGD("Distributor name:%{public}s, connection name:%{public}s, ret:%{public}d",
|
||||
name_.c_str(), conns[i]->info_.name_.c_str(), ret);
|
||||
|
@ -30,12 +30,12 @@ sptr<OHOS::Rosen::VSyncSampler> VSyncSampler::instance_ = nullptr;
|
||||
|
||||
namespace {
|
||||
constexpr double PI = 3.1415926;
|
||||
constexpr int64_t ERROR_THRESHOLD = 160000000000; // 400 usec squared
|
||||
constexpr double ERROR_THRESHOLD = 160000000000.0; // 400 usec squared
|
||||
constexpr int32_t INVALID_TIMESTAMP = -1;
|
||||
constexpr uint32_t MINES_SAMPLE_NUMS = 3;
|
||||
constexpr uint32_t SAMPLES_INTERVAL_DIFF_NUMS = 2;
|
||||
constexpr int64_t MAX_IDLE_TIME_THRESHOLD = 900000000; // 900000000ns == 900ms
|
||||
constexpr int64_t SAMPLE_VARIANCE_THRESHOLD = 250000000000; // 500 usec squared
|
||||
constexpr double SAMPLE_VARIANCE_THRESHOLD = 250000000000.0; // 500 usec squared
|
||||
}
|
||||
sptr<OHOS::Rosen::VSyncSampler> VSyncSampler::GetInstance() noexcept
|
||||
{
|
||||
@ -176,7 +176,7 @@ void VSyncSampler::UpdateModeLocked()
|
||||
int64_t max = 0;
|
||||
int64_t diffPrev = 0;
|
||||
int64_t diff = 0;
|
||||
int64_t variance = 0;
|
||||
double variance = 0;
|
||||
for (uint32_t i = 1; i < numSamples_; i++) {
|
||||
int64_t prevSample = samples_[(firstSampleIndex_ + i - 1 + MAX_SAMPLES) % MAX_SAMPLES];
|
||||
int64_t currentSample = samples_[(firstSampleIndex_ + i) % MAX_SAMPLES];
|
||||
@ -184,13 +184,13 @@ void VSyncSampler::UpdateModeLocked()
|
||||
diff = currentSample - prevSample;
|
||||
if (diffPrev != 0) {
|
||||
int64_t delta = diff - diffPrev;
|
||||
variance += delta * delta;
|
||||
variance += pow(static_cast<double>(delta), 2); // the 2nd power of delta
|
||||
}
|
||||
min = min < diff ? min : diff;
|
||||
max = max > diff ? max : diff;
|
||||
sum += diff;
|
||||
}
|
||||
variance /= (int64_t)(numSamples_ - SAMPLES_INTERVAL_DIFF_NUMS);
|
||||
variance /= (numSamples_ - SAMPLES_INTERVAL_DIFF_NUMS);
|
||||
if (variance > SAMPLE_VARIANCE_THRESHOLD) {
|
||||
// keep only the latest 5 samples, and sample the next timestamp.
|
||||
firstSampleIndex_ = (firstSampleIndex_ + numSamples_ - MIN_SAMPLES_FOR_UPDATE + 1) % MAX_SAMPLES;
|
||||
@ -236,7 +236,7 @@ void VSyncSampler::UpdateErrorLocked()
|
||||
}
|
||||
|
||||
int numErrSamples = 0;
|
||||
int64_t sqErrSum = 0;
|
||||
double sqErrSum = 0;
|
||||
|
||||
for (uint32_t i = 0; i < NUM_PRESENT; i++) {
|
||||
int64_t t = presentFenceTime_[i];
|
||||
@ -254,7 +254,7 @@ void VSyncSampler::UpdateErrorLocked()
|
||||
if (sampleErr > period_ / 2) {
|
||||
sampleErr -= period_;
|
||||
}
|
||||
sqErrSum += sampleErr * sampleErr;
|
||||
sqErrSum += pow(static_cast<double>(sampleErr), 2); // the 2nd power of sampleErr
|
||||
numErrSamples++;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
*/
|
||||
|
||||
#include "vsync_generator.h"
|
||||
#include "vsync_controller.h"
|
||||
#include "vsync_distributor.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
@ -36,11 +38,21 @@ public:
|
||||
|
||||
static inline sptr<VSyncGenerator> vsyncGenerator_;
|
||||
static constexpr const int32_t WAIT_SYSTEM_ABILITY_REPORT_DATA_SECONDS = 5;
|
||||
static inline sptr<VSyncController> appController;
|
||||
static inline sptr<VSyncController> rsController;
|
||||
static inline sptr<VSyncDistributor> appDistributor;
|
||||
static inline sptr<VSyncDistributor> rsDistributor;
|
||||
};
|
||||
|
||||
void VSyncGeneratorTest::SetUpTestCase()
|
||||
{
|
||||
vsyncGenerator_ = CreateVSyncGenerator();
|
||||
appController = new VSyncController(vsyncGenerator_, 0);
|
||||
rsController = new VSyncController(vsyncGenerator_, 0);
|
||||
appDistributor = new VSyncDistributor(appController, "app");
|
||||
rsDistributor = new VSyncDistributor(rsController, "app");
|
||||
vsyncGenerator_->SetRSDistributor(rsDistributor);
|
||||
vsyncGenerator_->SetAppDistributor(appDistributor);
|
||||
}
|
||||
|
||||
void VSyncGeneratorTest::TearDownTestCase()
|
||||
|
@ -44,7 +44,6 @@ ohos_source_set("create_pixelmap_surface_src") {
|
||||
"$graphic_2d_root/frameworks/opengl_wrapper:GLESv3",
|
||||
"$graphic_2d_root/rosen/modules/2d_graphics:2d_graphics",
|
||||
"$graphic_2d_root/rosen/modules/render_service_base:librender_service_base",
|
||||
"$graphic_2d_root/rosen/modules/render_service_base/src/platform:platform",
|
||||
"$graphic_2d_root/utils:scoped_bytrace",
|
||||
]
|
||||
|
||||
|
@ -9,10 +9,13 @@
|
||||
# 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.
|
||||
# limitations under the License.
|
||||
|
||||
group("test") {
|
||||
testonly = true
|
||||
|
||||
deps = [ "fuzztest:fuzztest" ]
|
||||
deps = [
|
||||
"fuzztest:fuzztest",
|
||||
"unittest:unittest",
|
||||
]
|
||||
}
|
||||
|
78
rosen/modules/create_pixelmap_surface/test/unittest/BUILD.gn
Normal file
78
rosen/modules/create_pixelmap_surface/test/unittest/BUILD.gn
Normal file
@ -0,0 +1,78 @@
|
||||
# Copyright (c) 2024 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.
|
||||
|
||||
import("//build/test.gni")
|
||||
import("//foundation/graphic/graphic_2d/graphic_config.gni")
|
||||
|
||||
module_out_path = "graphic_2d/create_pixelmap_surface"
|
||||
|
||||
group("unittest") {
|
||||
testonly = true
|
||||
|
||||
deps = [ ":pixel_map_from_surface_test" ]
|
||||
}
|
||||
|
||||
## UnitTest pixel_map_from_surface_test {{{
|
||||
ohos_unittest("pixel_map_from_surface_test") {
|
||||
module_out_path = module_out_path
|
||||
|
||||
sources = [ "pixel_map_from_surface_test.cpp" ]
|
||||
|
||||
deps = [ ":pixel_map_test_common" ]
|
||||
}
|
||||
|
||||
## UnitTest pixel_map_from_surface_test }}}
|
||||
|
||||
## Build pixel_map_test_common.a {{{
|
||||
config("pixel_map_test_common_public_config") {
|
||||
include_dirs = [
|
||||
"$graphic_2d_root/interfaces/inner_api/common",
|
||||
"$graphic_2d_root/rosen/modules/create_pixelmap_surface/include",
|
||||
]
|
||||
|
||||
cflags = [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-g3",
|
||||
"-Dprivate=public",
|
||||
"-Dprotected=public",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_static_library("pixel_map_test_common") {
|
||||
visibility = [ ":*" ]
|
||||
testonly = true
|
||||
sanitize = {
|
||||
cfi = true
|
||||
cfi_cross_dso = true
|
||||
cfi_no_nvcall = true
|
||||
debug = false
|
||||
}
|
||||
public_configs = [ ":pixel_map_test_common_public_config" ]
|
||||
|
||||
public_deps = [
|
||||
"$graphic_2d_root/rosen/modules/create_pixelmap_surface:create_pixelmap_surface",
|
||||
"//third_party/googletest:gmock_main",
|
||||
"//third_party/googletest:gtest_main",
|
||||
]
|
||||
|
||||
public_external_deps = [
|
||||
"c_utils:utils",
|
||||
"graphic_surface:surface",
|
||||
"image_framework:image_native",
|
||||
]
|
||||
|
||||
subsystem_name = "graphic"
|
||||
part_name = "graphic_2d"
|
||||
}
|
||||
## Build pixel_map_test_common.a }}}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.
|
||||
*/
|
||||
|
||||
#include "pixel_map_from_surface.h"
|
||||
#include "iconsumer_surface.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace testing;
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
class PixelMapFromSurfaceTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase();
|
||||
static void TearDownTestCase();
|
||||
};
|
||||
|
||||
void PixelMapFromSurfaceTest::SetUpTestCase() {}
|
||||
|
||||
void PixelMapFromSurfaceTest::TearDownTestCase() {}
|
||||
|
||||
namespace {
|
||||
/*
|
||||
* Function: CreatePixelMapFromSurface001
|
||||
* Type: Function
|
||||
* Rank: Important(2)
|
||||
* EnvConditions: N/A
|
||||
* CaseDescription:
|
||||
1. call CreatePixelMapFromSurface with nullptr suface and should return nullptr
|
||||
2. call CreatePixelMapFromSurface with incorrect rect.left and should return nullptr
|
||||
3. call CreatePixelMapFromSurface with incorrect rect.top and should return nullptr
|
||||
4. call CreatePixelMapFromSurface with incorrect rect.width and should return nullptr
|
||||
5. call CreatePixelMapFromSurface with incorrect rect.height and should return nullptr
|
||||
*/
|
||||
HWTEST_F(PixelMapFromSurfaceTest, CreatePixelMapFromSurface001, Function | MediumTest| Level3)
|
||||
{
|
||||
OHOS::Media::Rect srcRect = {0, 0, 100, 100};
|
||||
ASSERT_EQ(OHOS::Rosen::CreatePixelMapFromSurface(nullptr, srcRect), nullptr);
|
||||
auto cSurface = IConsumerSurface::Create();
|
||||
ASSERT_NE(cSurface, nullptr);
|
||||
auto producer = cSurface->GetProducer();
|
||||
auto pSurface = Surface::CreateSurfaceAsProducer(producer);
|
||||
ASSERT_NE(pSurface, nullptr);
|
||||
srcRect = {-1, 0, 100, 100};
|
||||
ASSERT_EQ(OHOS::Rosen::CreatePixelMapFromSurface(pSurface, srcRect), nullptr);
|
||||
srcRect = {0, -1, 100, 100};
|
||||
ASSERT_EQ(OHOS::Rosen::CreatePixelMapFromSurface(pSurface, srcRect), nullptr);
|
||||
srcRect = {0, 0, 0, 100};
|
||||
ASSERT_EQ(OHOS::Rosen::CreatePixelMapFromSurface(pSurface, srcRect), nullptr);
|
||||
srcRect = {0, 0, 100, 0};
|
||||
ASSERT_EQ(OHOS::Rosen::CreatePixelMapFromSurface(pSurface, srcRect), nullptr);
|
||||
}
|
||||
} // namespace
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
@ -40,6 +40,7 @@ public:
|
||||
~EglManager() {}
|
||||
EGLConfig GetConfig(int version, EGLDisplay eglDisplay);
|
||||
void Init();
|
||||
EGLBoolean IsEGLContextInCurrentThread(EGLDisplay display, EGLContext context);
|
||||
|
||||
private:
|
||||
EglManager() : EGLDisplay_(EGL_NO_DISPLAY), EGLConfig_(nullptr), EGLContext_(EGL_NO_CONTEXT),
|
||||
|
@ -46,6 +46,10 @@ EGLConfig EglManager::GetConfig(int version, EGLDisplay eglDisplay)
|
||||
void EglManager::Init()
|
||||
{
|
||||
if (initialized_) {
|
||||
if (!IsEGLContextInCurrentThread(EGLDisplay_, EGLContext_)) {
|
||||
LOGW("retry eglMakeCurrent.");
|
||||
eglMakeCurrent(EGLDisplay_, currentSurface_, currentSurface_, EGLContext_);
|
||||
}
|
||||
return;
|
||||
}
|
||||
initialized_ = true;
|
||||
@ -115,6 +119,20 @@ void EglManager::Init()
|
||||
}
|
||||
eglMakeCurrent(EGLDisplay_, currentSurface_, currentSurface_, EGLContext_);
|
||||
}
|
||||
|
||||
EGLBoolean EglManager::IsEGLContextInCurrentThread(EGLDisplay display, EGLContext context)
|
||||
{
|
||||
EGLBoolean isContextInCurrent = EGL_FALSE;
|
||||
EGLint isContextLost = 0;
|
||||
|
||||
eglQueryContext(display, context, EGL_CONTEXT_LOST, &isContextLost);
|
||||
|
||||
if (!isContextLost && eglGetCurrentContext() == context) {
|
||||
isContextInCurrent = EGL_TRUE;
|
||||
}
|
||||
|
||||
return isContextInCurrent;
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
||||
|
@ -182,8 +182,6 @@ HWTEST_F(BrightnessFilterUnittest, GetFragmentShader001, TestSize.Level1)
|
||||
fragColor = vec4((textureColor.rgb + brightness), textureColor.a);
|
||||
}
|
||||
)SHADER";
|
||||
GTEST_LOG_(INFO) << "brightness->GetFragmentShader()" << brightness->GetFragmentShader();
|
||||
GTEST_LOG_(INFO) << "result:" << result;
|
||||
EXPECT_TRUE(brightness->GetFragmentShader() == result);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ namespace Rosen {
|
||||
#define LOGE(fmt, ...) HILOG_ERROR(LOG_CORE, fmt, ##__VA_ARGS__)
|
||||
namespace {
|
||||
#if (defined(__aarch64__) || defined(__x86_64__))
|
||||
const std::string FRAME_AWARE_SO_PATH = "/system/lib64/platformsdk/libframe_ui_intf.z.so";
|
||||
const std::string FRAME_AWARE_SO_PATH = "/system/lib64/libframe_ui_intf.z.so";
|
||||
#else
|
||||
const std::string FRAME_AWARE_SO_PATH = "/system/lib/platformsdk/libframe_ui_intf.z.so";
|
||||
#endif
|
||||
|
@ -56,11 +56,14 @@ ohos_source_set("graphics_effect_src") {
|
||||
"src/ge_hps_blur_shader_filter.cpp",
|
||||
"src/ge_kawase_blur_shader_filter.cpp",
|
||||
"src/ge_linear_gradient_blur_shader_filter.cpp",
|
||||
"src/ge_magnifier_shader_filter.cpp",
|
||||
"src/ge_render.cpp",
|
||||
"src/ge_shader.cpp",
|
||||
"src/ge_system_properties.cpp",
|
||||
"src/ge_visual_effect.cpp",
|
||||
"src/ge_visual_effect_container.cpp",
|
||||
"src/ge_visual_effect_impl.cpp",
|
||||
"src/ge_water_ripple_filter.cpp",
|
||||
]
|
||||
|
||||
deps = [ "$graphic_2d_root/rosen/modules/2d_graphics:2d_graphics" ]
|
||||
|
@ -42,8 +42,6 @@ private:
|
||||
float aiBarThreshold_;
|
||||
float aiBarOpacity_;
|
||||
float aiBarSaturation_;
|
||||
std::shared_ptr<Drawing::RuntimeShaderBuilder> MakeBinarizationShader(
|
||||
float imageWidth, float imageHeight, std::shared_ptr<Drawing::ShaderEffect> imageShader);
|
||||
};
|
||||
|
||||
} // namespace Rosen
|
||||
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 GRAPHICS_EFFECT_GE_MAGNIFIER_SHADER_FILTER_H
|
||||
#define GRAPHICS_EFFECT_GE_MAGNIFIER_SHADER_FILTER_H
|
||||
|
||||
#include "ge_shader_filter.h"
|
||||
#include "ge_visual_effect.h"
|
||||
|
||||
#include "draw/canvas.h"
|
||||
#include "effect/runtime_effect.h"
|
||||
#include "effect/runtime_shader_builder.h"
|
||||
#include "image/image.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
|
||||
class GEMagnifierParams {
|
||||
public:
|
||||
float factor_ = 0.f;
|
||||
float width_ = 0.f;
|
||||
float height_ = 0.f;
|
||||
float borderWidth_ = 0.f;
|
||||
float cornerRadius_ = 0.f;
|
||||
|
||||
float shadowOffsetX_ = 0.f;
|
||||
float shadowOffsetY_ = 0.f;
|
||||
float shadowSize_ = 0.f;
|
||||
float shadowStrength_ = 0.f;
|
||||
|
||||
// rgba
|
||||
uint32_t gradientMaskColor1_ = 0x00000000;
|
||||
uint32_t gradientMaskColor2_ = 0x00000000;
|
||||
uint32_t outerContourColor1_ = 0x00000000;
|
||||
uint32_t outerContourColor2_ = 0x00000000;
|
||||
|
||||
explicit GEMagnifierParams() {}
|
||||
|
||||
~GEMagnifierParams() = default;
|
||||
};
|
||||
|
||||
class GEMagnifierShaderFilter : public GEShaderFilter {
|
||||
public:
|
||||
GEMagnifierShaderFilter(const Drawing::GEMagnifierShaderFilterParams& params);
|
||||
GEMagnifierShaderFilter(const GEMagnifierShaderFilter&) = delete;
|
||||
GEMagnifierShaderFilter operator=(const GEMagnifierShaderFilter&) = delete;
|
||||
~GEMagnifierShaderFilter() override = default;
|
||||
|
||||
std::shared_ptr<Drawing::Image> ProcessImage(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image> image,
|
||||
const Drawing::Rect& src, const Drawing::Rect& dst) override;
|
||||
|
||||
const std::string GetDescription() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Drawing::RuntimeShaderBuilder> MakeMagnifierShader(
|
||||
std::shared_ptr<Drawing::ShaderEffect> imageShader, float imageWidth, float imageHeight);
|
||||
bool InitMagnifierEffect();
|
||||
void ConvertToRgba(uint32_t rgba, float* color);
|
||||
|
||||
std::shared_ptr<GEMagnifierParams> magnifierPara_ = nullptr;
|
||||
static std::shared_ptr<Drawing::RuntimeEffect> magnifierShaderEffect_;
|
||||
};
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // GRAPHICS_EFFECT_GE_MAGNIFIER_SHADER_FILTER_H
|
94
rosen/modules/graphics_effect/include/ge_shader.h
Normal file
94
rosen/modules/graphics_effect/include/ge_shader.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 GRAPHICS_EFFECT_GE_SHADER_H
|
||||
#define GRAPHICS_EFFECT_GE_SHADER_H
|
||||
#include "effect/runtime_effect.h"
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
typedef enum {
|
||||
SHADER_AIBAR,
|
||||
SHADER_GREY,
|
||||
SHADER_BLUR,
|
||||
SHADER_BLURAF,
|
||||
SHADER_MIX,
|
||||
SHADER_SIMPLE,
|
||||
SHADER_HORIBLUR,
|
||||
SHADER_VERTBLUR,
|
||||
SHADER_MASKBLUR
|
||||
} ShaderIndex;
|
||||
// Union Shader Feature
|
||||
typedef enum {
|
||||
TYPE_NO_REFERENCE,
|
||||
TYPE_REFERENCE_ROW,
|
||||
TYPE_REFERENCE_COLUME,
|
||||
TYPE_REFERENCE_AROUND
|
||||
} ShaderType;
|
||||
typedef enum {
|
||||
GE_ERROR_NONE = 0,
|
||||
GE_ERROR_NOT_ACCEPTED_CONNECT,
|
||||
GE_ERROR_SHADER_STRING_INVALID,
|
||||
GE_ERROR_SHADER_COMPILE_FAILED
|
||||
} GE_Error;
|
||||
|
||||
class GEShader {
|
||||
public:
|
||||
GEShader(const std::string& name, ShaderType type,
|
||||
const std::string& shaderStr, const Drawing::RuntimeEffectOptions* opt = nullptr);
|
||||
GEShader(const std::shared_ptr<GEShader> rth);
|
||||
~GEShader();
|
||||
std::string GetName() const;
|
||||
ShaderType GetType() const;
|
||||
GEShader& String(const std::string& shaderStr);
|
||||
GEShader& Type(ShaderType type);
|
||||
GEShader& Name(const std::string& name);
|
||||
Drawing::RuntimeEffectOptions* GetOptions() const;
|
||||
bool Combine(const GEShader& rth);
|
||||
std::shared_ptr<Drawing::RuntimeEffect> GetShader() const;
|
||||
GE_Error Compile(const Drawing::RuntimeEffectOptions* ops = nullptr);
|
||||
private:
|
||||
std::string GetString() const;
|
||||
GE_Error Connect(const GEShader& subShader) ;
|
||||
static GE_Error CombineShaderString(std::string& cbStr,
|
||||
const std::string& shaderStrFirst, const std::string& shaderStrSecond);
|
||||
|
||||
// Union Shader Feature
|
||||
ShaderType type_ = TYPE_NO_REFERENCE;
|
||||
std::string name_ = {};
|
||||
std::string shaderStr_ = {};
|
||||
std::shared_ptr<Drawing::RuntimeEffect> shader_ = nullptr;
|
||||
Drawing::RuntimeEffectOptions* opt_ = nullptr;
|
||||
};
|
||||
|
||||
class GEShaderStore {
|
||||
public:
|
||||
static std::shared_ptr<GEShaderStore> GetInstance();
|
||||
std::shared_ptr<GEShader> GetShader(ShaderIndex which);
|
||||
std::shared_ptr<GEShader> GetShader(const std::vector<ShaderIndex>& which);
|
||||
private:
|
||||
void Initialize();
|
||||
void RegisterShader(ShaderIndex key, const std::string& name, ShaderType type, const std::string& shader,
|
||||
const Drawing::RuntimeEffectOptions* opt);
|
||||
std::unordered_map<std::string, std::shared_ptr<GEShader>> shaderMap_ = {};
|
||||
std::unordered_map<ShaderIndex, std::shared_ptr<GEShader>> shaderObjMap_ = {};
|
||||
};
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // GRAPHICS_EFFECT_GE_SHADER_H
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "draw/canvas.h"
|
||||
#include "image/image.h"
|
||||
#include "ge_shader.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
|
@ -39,6 +39,18 @@ struct GEAIBarShaderFilterParams {
|
||||
float aiBarSaturation;
|
||||
};
|
||||
|
||||
constexpr char GE_FILTER_WATER_RIPPLE[] = "WATER_RIPPLE";
|
||||
constexpr char GE_FILTER_WATER_RIPPLE_PROGRESS[] = "PROGRESS";
|
||||
constexpr char GE_FILTER_WATER_RIPPLE_WAVE_NUM[] = "WAVE_NUM";
|
||||
constexpr char GE_FILTER_WATER_RIPPLE_RIPPLE_CENTER_X[] = "RIPPLE_CENTER_X";
|
||||
constexpr char GE_FILTER_WATER_RIPPLE_RIPPLE_CENTER_Y[] = "RIPPLE_CENTER_Y";
|
||||
struct GEWaterRippleFilterParams {
|
||||
float progress = 0.0f;
|
||||
float waveCount = 2.0f;
|
||||
float rippleCenterX = 0.5f;
|
||||
float rippleCenterY = 0.7f;
|
||||
};
|
||||
|
||||
constexpr char GE_FILTER_GREY[] = "GREY";
|
||||
constexpr char GE_FILTER_GREY_COEF_1[] = "GREY_COEF_1";
|
||||
constexpr char GE_FILTER_GREY_COEF_2[] = "GREY_COEF_2";
|
||||
@ -85,6 +97,39 @@ struct GELinearGradientBlurShaderFilterParams {
|
||||
bool isOffscreenCanvas;
|
||||
};
|
||||
|
||||
constexpr char GE_FILTER_MAGNIFIER[] = "MAGNIFIER";
|
||||
constexpr char GE_FILTER_MAGNIFIER_FACTOR[] = "FACTOR";
|
||||
constexpr char GE_FILTER_MAGNIFIER_WIDTH[] = "WIDTH";
|
||||
constexpr char GE_FILTER_MAGNIFIER_HEIGHT[] = "HEIGHT";
|
||||
constexpr char GE_FILTER_MAGNIFIER_BORDER_WIDTH[] = "BORDERWIDTH";
|
||||
constexpr char GE_FILTER_MAGNIFIER_CORNER_RADIUS[] = "CORNERRADIUS";
|
||||
constexpr char GE_FILTER_MAGNIFIER_SHADOW_OFFSET_X[] = "SHADOWOFFSETX";
|
||||
constexpr char GE_FILTER_MAGNIFIER_SHADOW_OFFSET_Y[] = "SHADOWOFFSETY";
|
||||
constexpr char GE_FILTER_MAGNIFIER_SHADOW_SIZE[] = "SHADOWSIZE";
|
||||
constexpr char GE_FILTER_MAGNIFIER_SHADOW_STRENGTH[] = "SHADOWSTRENGTH";
|
||||
constexpr char GE_FILTER_MAGNIFIER_GRADIENT_MASK_COLOR_1[] = "GRADIENTMASKCOLOR1";
|
||||
constexpr char GE_FILTER_MAGNIFIER_GRADIENT_MASK_COLOR_2[] = "GRADIENTMASKCOLOR2";
|
||||
constexpr char GE_FILTER_MAGNIFIER_OUTER_CONTOUR_COLOR_1[] = "OUTERCONTOURCOLOR1";
|
||||
constexpr char GE_FILTER_MAGNIFIER_OUTER_CONTOUR_COLOR_2[] = "OUTERCONTOURCOLOR2";
|
||||
struct GEMagnifierShaderFilterParams {
|
||||
float factor;
|
||||
float width;
|
||||
float height;
|
||||
float borderWidth;
|
||||
float cornerRadius;
|
||||
|
||||
float shadowOffsetX;
|
||||
float shadowOffsetY;
|
||||
float shadowSize;
|
||||
float shadowStrength;
|
||||
|
||||
// rgba
|
||||
uint32_t gradientMaskColor1;
|
||||
uint32_t gradientMaskColor2;
|
||||
uint32_t outerContourColor1;
|
||||
uint32_t outerContourColor2;
|
||||
};
|
||||
|
||||
} // namespace Drawing
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
241
rosen/modules/graphics_effect/include/ge_shader_string.h
Normal file
241
rosen/modules/graphics_effect/include/ge_shader_string.h
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 GRAPHICS_EFFECT_SHADER_STRING_H
|
||||
#define GRAPHICS_EFFECT_SHADER_STRING_H
|
||||
#include <string>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
|
||||
static std::string g_aibarString(R"(
|
||||
uniform half low;
|
||||
uniform half high;
|
||||
uniform half threshold;
|
||||
uniform half opacity;
|
||||
uniform half saturation;
|
||||
uniform shader imageShader;
|
||||
|
||||
const vec3 toLuminance = vec3(0.3086, 0.6094, 0.0820);
|
||||
|
||||
half4 main(float2 coord) {
|
||||
half3 c = imageShader.eval(coord).rgb;
|
||||
float gray = 0.299 * c.r + 0.587 * c.g + 0.114 * c.b;
|
||||
float bin = mix(high, low, step(threshold, gray));
|
||||
float luminance = dot(c, toLuminance);
|
||||
half3 satAdjust = mix(vec3(luminance), c, saturation);
|
||||
half3 res = satAdjust - (opacity + 1.0) * gray + bin;
|
||||
return half4(res, 1.0);
|
||||
}
|
||||
)");
|
||||
|
||||
static std::string g_greyGradationString(R"(
|
||||
uniform shader imageShader;
|
||||
uniform float coefficient1;
|
||||
uniform float coefficient2;
|
||||
|
||||
float poww(float x, float y) {
|
||||
return (x < 0) ? -pow(-x, y) : pow(x, y);
|
||||
}
|
||||
|
||||
float calculateT_y(float rgb) {
|
||||
if (rgb > 127.5) { rgb = 255 - rgb; }
|
||||
float b = 38.0;
|
||||
float c = 45.0;
|
||||
float d = 127.5;
|
||||
float A = 106.5; // 3 * b - 3 * c + d;
|
||||
float B = -93; // 3 * (c - 2 * b);
|
||||
float C = 114; // 3 * b;
|
||||
float p = 0.816240163988; // (3 * A * C - pow(B, 2)) / (3 * pow(A, 2));
|
||||
float q = -rgb / 106.5 + 0.262253485943; // -rgb/A - B*C/(3*pow(A,2)) + 2*pow(B,3)/(27*pow(A,3))
|
||||
float s1 = -(q / 2.0);
|
||||
float s2 = sqrt(pow(s1, 2) + pow(p / 3, 3));
|
||||
return poww((s1 + s2), 1.0 / 3) + poww((s1 - s2), 1.0 / 3) - (B / (3 * A));
|
||||
}
|
||||
|
||||
float calculateGreyAdjustY(float rgb) {
|
||||
float t_r = calculateT_y(rgb);
|
||||
return (rgb < 127.5) ? (rgb + coefficient1 * pow((1 - t_r), 3)) :
|
||||
(rgb - coefficient2 * pow((1 - t_r), 3));
|
||||
}
|
||||
|
||||
half4 main(float2 coord) {
|
||||
vec3 color = vec3(imageShader.eval(coord).r, imageShader.eval(coord).g, imageShader.eval(coord).b);
|
||||
float Y = (0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 255;
|
||||
float U = (-0.147 * color.r - 0.289 * color.g + 0.436 * color.b) * 255;
|
||||
float V = (0.615 * color.r - 0.515 * color.g - 0.100 * color.b) * 255;
|
||||
Y = calculateGreyAdjustY(Y);
|
||||
color.r = (Y + 1.14 * V) / 255.0;
|
||||
color.g = (Y - 0.39 * U - 0.58 * V) / 255.0;
|
||||
color.b = (Y + 2.03 * U) / 255.0;
|
||||
|
||||
return vec4(color, 1.0);
|
||||
}
|
||||
)");
|
||||
|
||||
static std::string g_blurStringAF(R"(
|
||||
uniform shader imageShader;
|
||||
uniform float2 in_blurOffset[5];
|
||||
|
||||
half4 main(float2 coord) {
|
||||
half4 c = half4(0, 0, 0, 0);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
c += imageShader.eval(float2(coord.x + in_blurOffset[i].x, coord.y + in_blurOffset[i].y));
|
||||
}
|
||||
return half4(c.rgb * 0.2, 1.0);
|
||||
}
|
||||
)");
|
||||
|
||||
static std::string g_mixString(R"(
|
||||
uniform shader blurredInput;
|
||||
uniform shader originalInput;
|
||||
uniform float mixFactor;
|
||||
uniform float inColorFactor;
|
||||
|
||||
highp float random(float2 xy) {
|
||||
float t = dot(xy, float2(78.233, 12.9898));
|
||||
return fract(sin(t) * 43758.5453);
|
||||
}
|
||||
half4 main(float2 coord) {
|
||||
highp float noiseGranularity = inColorFactor / 255.0;
|
||||
half4 finalColor = mix(originalInput.eval(coord), blurredInput.eval(coord), mixFactor);
|
||||
float noise = mix(-noiseGranularity, noiseGranularity, random(coord));
|
||||
finalColor.rgb += noise;
|
||||
return finalColor;
|
||||
}
|
||||
)");
|
||||
|
||||
static std::string g_blurString(R"(
|
||||
uniform shader imageShader;
|
||||
uniform float2 in_blurOffset;
|
||||
uniform float2 in_maxSizeXY;
|
||||
|
||||
half4 main(float2 coord) {
|
||||
half4 c = imageShader.eval(coord);
|
||||
c += imageShader.eval(float2(clamp(in_blurOffset.x + coord.x, 0, in_maxSizeXY.x),
|
||||
clamp(in_blurOffset.y + coord.y, 0, in_maxSizeXY.y)));
|
||||
c += imageShader.eval(float2(clamp(in_blurOffset.x + coord.x, 0, in_maxSizeXY.x),
|
||||
clamp(-in_blurOffset.y + coord.y, 0, in_maxSizeXY.y)));
|
||||
c += imageShader.eval(float2(clamp(-in_blurOffset.x + coord.x, 0, in_maxSizeXY.x),
|
||||
clamp(in_blurOffset.y + coord.y, 0, in_maxSizeXY.y)));
|
||||
c += imageShader.eval(float2(clamp(-in_blurOffset.x + coord.x, 0, in_maxSizeXY.x),
|
||||
clamp(-in_blurOffset.y + coord.y, 0, in_maxSizeXY.y)));
|
||||
return half4(c.rgb * 0.2, 1.0);
|
||||
}
|
||||
)");
|
||||
|
||||
static std::string g_simpleString(R"(
|
||||
uniform shader imageShader;
|
||||
half4 main(float2 coord) {
|
||||
return imageShader.eval(coord);
|
||||
}
|
||||
)");
|
||||
|
||||
static const std::string g_hBlurString(R"(
|
||||
uniform half r;
|
||||
uniform shader imageShader;
|
||||
uniform shader gradientShader;
|
||||
half4 meanFilter(float2 coord, half radius)
|
||||
{
|
||||
half4 sum = vec4(0.0);
|
||||
half div = 0;
|
||||
for (half x = -30.0; x < 30.0; x += 1.0) {
|
||||
if (x > radius) {
|
||||
break;
|
||||
}
|
||||
if (abs(x) < radius) {
|
||||
div += 1;
|
||||
sum += imageShader.eval(coord + float2(x, 0));
|
||||
}
|
||||
}
|
||||
return half4(sum.xyz / div, 1.0);
|
||||
}
|
||||
half4 main(float2 coord)
|
||||
{
|
||||
if (abs(gradientShader.eval(coord).a - 0) < 0.001) {
|
||||
return imageShader.eval(coord);
|
||||
}
|
||||
else {
|
||||
float val = clamp(r * gradientShader.eval(coord).a, 1.0, r);
|
||||
return meanFilter(coord, val);
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
static const std::string g_vBlurString(R"(
|
||||
uniform half r;
|
||||
uniform shader imageShader;
|
||||
uniform shader gradientShader;
|
||||
half4 meanFilter(float2 coord, half radius)
|
||||
{
|
||||
half4 sum = vec4(0.0);
|
||||
half div = 0;
|
||||
for (half y = -30.0; y < 30.0; y += 1.0) {
|
||||
if (y > radius) {
|
||||
break;
|
||||
}
|
||||
if (abs(y) < radius) {
|
||||
div += 1;
|
||||
sum += imageShader.eval(coord + float2(0, y));
|
||||
}
|
||||
}
|
||||
return half4(sum.xyz / div, 1.0);
|
||||
}
|
||||
half4 main(float2 coord)
|
||||
{
|
||||
if (abs(gradientShader.eval(coord).a - 0) < 0.001) {
|
||||
return imageShader.eval(coord);
|
||||
}
|
||||
else {
|
||||
float val = clamp(r * gradientShader.eval(coord).a, 1.0, r);
|
||||
return meanFilter(coord, val);
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
static const std::string g_maskBlurString(R"(
|
||||
uniform shader srcImageShader;
|
||||
uniform shader blurImageShader;
|
||||
uniform shader gradientShader;
|
||||
half4 meanFilter(float2 coord)
|
||||
{
|
||||
vec3 srcColor = vec3(srcImageShader.eval(coord).r,
|
||||
srcImageShader.eval(coord).g, srcImageShader.eval(coord).b);
|
||||
vec3 blurColor = vec3(blurImageShader.eval(coord).r,
|
||||
blurImageShader.eval(coord).g, blurImageShader.eval(coord).b);
|
||||
float gradient = gradientShader.eval(coord).a;
|
||||
|
||||
vec3 color = blurColor * gradient + srcColor * (1 - gradient);
|
||||
return vec4(color, 1.0);
|
||||
}
|
||||
half4 main(float2 coord)
|
||||
{
|
||||
if (abs(gradientShader.eval(coord).a) < 0.001) {
|
||||
return srcImageShader.eval(coord);
|
||||
}
|
||||
else {
|
||||
if (abs(gradientShader.eval(coord).a) > 0.999) {
|
||||
return blurImageShader.eval(coord);
|
||||
}
|
||||
else {
|
||||
return meanFilter(coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
)");
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
#endif // GRAPHICS_EFFECT_SHADER_STRING_H
|
@ -47,6 +47,7 @@ public:
|
||||
void SetParam(const std::string& tag, const Drawing::Matrix param);
|
||||
void SetParam(const std::string& tag, const std::vector<std::pair<float, float>>);
|
||||
void SetParam(const std::string& tag, bool param);
|
||||
void SetParam(const std::string& tag, uint32_t param);
|
||||
|
||||
const std::string& GetName() const
|
||||
{
|
||||
|
@ -30,7 +30,16 @@ namespace Drawing {
|
||||
|
||||
class GEVisualEffectImpl {
|
||||
public:
|
||||
enum class FilterType { NONE, KAWASE_BLUR, GREY, AIBAR, LINEAR_GRADIENT_BLUR, HPS_BLUR, MAX };
|
||||
enum class FilterType {
|
||||
NONE,
|
||||
KAWASE_BLUR,
|
||||
GREY, AIBAR,
|
||||
LINEAR_GRADIENT_BLUR,
|
||||
HPS_BLUR,
|
||||
WATER_RIPPLE,
|
||||
MAGNIFIER,
|
||||
MAX
|
||||
};
|
||||
|
||||
GEVisualEffectImpl(const std::string& name);
|
||||
|
||||
@ -47,6 +56,7 @@ public:
|
||||
void SetParam(const std::string& tag, const Drawing::Matrix param);
|
||||
void SetParam(const std::string& tag, const std::vector<std::pair<float, float>>);
|
||||
void SetParam(const std::string& tag, bool param);
|
||||
void SetParam(const std::string& tag, uint32_t param);
|
||||
|
||||
void SetFilterType(FilterType type)
|
||||
{
|
||||
@ -68,6 +78,16 @@ public:
|
||||
return kawaseParams_;
|
||||
}
|
||||
|
||||
void MakeWaterRippleParams()
|
||||
{
|
||||
waterRippleParams_ = std::make_shared<GEWaterRippleFilterParams>();
|
||||
}
|
||||
|
||||
const std::shared_ptr<GEWaterRippleFilterParams>& GetWaterRippleParams() const
|
||||
{
|
||||
return waterRippleParams_;
|
||||
}
|
||||
|
||||
void MakeAIBarParams()
|
||||
{
|
||||
aiBarParams_ = std::make_shared<GEAIBarShaderFilterParams>();
|
||||
@ -108,13 +128,26 @@ public:
|
||||
return hpsBlurParams_;
|
||||
}
|
||||
|
||||
void MakeMagnifierParams()
|
||||
{
|
||||
magnifierParams_ = std::make_shared<GEMagnifierShaderFilterParams>();
|
||||
}
|
||||
|
||||
const std::shared_ptr<GEMagnifierShaderFilterParams>& GetMagnifierParams() const
|
||||
{
|
||||
return magnifierParams_;
|
||||
}
|
||||
|
||||
private:
|
||||
static std::map<const std::string, std::function<void(GEVisualEffectImpl*)>> g_initialMap;
|
||||
|
||||
void SetAIBarParams(const std::string& tag, float param);
|
||||
void SetGreyParams(const std::string& tag, float param);
|
||||
void SetLinearGradientBlurParams(const std::string& tag, float param);
|
||||
void SetWaterRippleParams(const std::string& tag, float param);
|
||||
void SetHpsBlurParams(const std::string& tag, float param);
|
||||
void SetMagnifierParamsFloat(const std::string& tag, float param);
|
||||
void SetMagnifierParamsUint32(const std::string& tag, uint32_t param);
|
||||
|
||||
FilterType filterType_ = GEVisualEffectImpl::FilterType::NONE;
|
||||
|
||||
@ -122,7 +155,9 @@ private:
|
||||
std::shared_ptr<GEAIBarShaderFilterParams> aiBarParams_ = nullptr;
|
||||
std::shared_ptr<GEGreyShaderFilterParams> greyParams_ = nullptr;
|
||||
std::shared_ptr<GELinearGradientBlurShaderFilterParams> linearGradientBlurParams_ = nullptr;
|
||||
std::shared_ptr<GEWaterRippleFilterParams> waterRippleParams_ = nullptr;
|
||||
std::shared_ptr<HpsBlurFilterParams> hpsBlurParams_ = nullptr;
|
||||
std::shared_ptr<GEMagnifierShaderFilterParams> magnifierParams_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Drawing
|
||||
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 GRAPHICS_EFFECT_GE_WATER_RIPPLE_FILTER_H
|
||||
#define GRAPHICS_EFFECT_GE_WATER_RIPPLE_FILTER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ge_shader_filter.h"
|
||||
#include "ge_visual_effect.h"
|
||||
|
||||
#include "draw/canvas.h"
|
||||
#include "effect/color_filter.h"
|
||||
#include "effect/runtime_effect.h"
|
||||
#include "effect/runtime_shader_builder.h"
|
||||
#include "image/image.h"
|
||||
#include "utils/matrix.h"
|
||||
#include "utils/rect.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
class GEWaterRippleFilter : public GEShaderFilter {
|
||||
public:
|
||||
GEWaterRippleFilter(const Drawing::GEWaterRippleFilterParams& params);
|
||||
~GEWaterRippleFilter() override = default;
|
||||
|
||||
std::shared_ptr<Drawing::Image> ProcessImage(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image> image,
|
||||
const Drawing::Rect& src, const Drawing::Rect& dst) override;
|
||||
|
||||
private:
|
||||
bool InitWaterRippleEffect();
|
||||
float progress_ = 0.0f;
|
||||
float waveCount_ = 2.0f;
|
||||
float rippleCenterX_ = 0.5f;
|
||||
float rippleCenterY_ = 0.7f;
|
||||
};
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // GRAPHICS_EFFECT_GE_WATER_RIPPLE_FILTER_H
|
@ -42,12 +42,24 @@ std::shared_ptr<Drawing::Image> GEAIBarShaderFilter::ProcessImage(Drawing::Canva
|
||||
return image;
|
||||
}
|
||||
|
||||
auto shader = GEShaderStore::GetInstance()->GetShader(SHADER_AIBAR);
|
||||
if (shader == nullptr) {
|
||||
return image;
|
||||
}
|
||||
|
||||
auto builder = std::make_shared<Drawing::RuntimeShaderBuilder>(shader->GetShader());
|
||||
|
||||
Drawing::Matrix matrix;
|
||||
auto imageShader = Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP,
|
||||
Drawing::TileMode::CLAMP, Drawing::SamplingOptions(Drawing::FilterMode::LINEAR), matrix);
|
||||
float imageWidth = image->GetWidth();
|
||||
float imageHeight = image->GetHeight();
|
||||
auto builder = MakeBinarizationShader(imageWidth, imageHeight, imageShader);
|
||||
|
||||
builder->SetChild("imageShader", imageShader);
|
||||
builder->SetUniform("low", aiBarLow_); // aiInvertCoef[0] is low
|
||||
builder->SetUniform("high", aiBarHigh_); // aiInvertCoef[1] is high
|
||||
builder->SetUniform("threshold", aiBarThreshold_); // aiInvertCoef[2] is threshold
|
||||
builder->SetUniform("opacity", aiBarOpacity_); // aiInvertCoef[3] is opacity
|
||||
builder->SetUniform("saturation", aiBarSaturation_); // aiInvertCoef[4] is saturation
|
||||
|
||||
auto invertedImage = builder->MakeImage(canvas.GetGPUContext().get(), nullptr, image->GetImageInfo(), false);
|
||||
if (invertedImage == nullptr) {
|
||||
LOGE("GEAIBarShaderFilter::ProcessImage invertedImage is null");
|
||||
@ -57,52 +69,5 @@ std::shared_ptr<Drawing::Image> GEAIBarShaderFilter::ProcessImage(Drawing::Canva
|
||||
return invertedImage;
|
||||
}
|
||||
|
||||
std::shared_ptr<Drawing::RuntimeShaderBuilder> GEAIBarShaderFilter::MakeBinarizationShader(
|
||||
float imageWidth, float imageHeight, std::shared_ptr<Drawing::ShaderEffect> imageShader)
|
||||
{
|
||||
static std::shared_ptr<Drawing::RuntimeEffect> binarizationShaderEffect_;
|
||||
|
||||
// coefficient of saturation borrowed from
|
||||
// the saturate filter in RSProperties::GenerateColorFilter()
|
||||
static constexpr char prog[] = R"(
|
||||
uniform half low;
|
||||
uniform half high;
|
||||
uniform half threshold;
|
||||
uniform half opacity;
|
||||
uniform half saturation;
|
||||
uniform shader imageShader;
|
||||
|
||||
const vec3 toLuminance = vec3(0.3086, 0.6094, 0.0820);
|
||||
|
||||
half4 main(float2 coord) {
|
||||
half3 c = imageShader.eval(coord).rgb;
|
||||
float gray = 0.299 * c.r + 0.587 * c.g + 0.114 * c.b;
|
||||
float bin = mix(high, low, step(threshold, gray));
|
||||
float luminance = dot(c, toLuminance);
|
||||
half3 satAdjust = mix(vec3(luminance), c, saturation);
|
||||
half3 res = satAdjust - (opacity + 1.0) * gray + bin;
|
||||
return half4(res, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
if (binarizationShaderEffect_ == nullptr) {
|
||||
binarizationShaderEffect_ = Drawing::RuntimeEffect::CreateForShader(prog);
|
||||
if (binarizationShaderEffect_ == nullptr) {
|
||||
LOGE("MakeBinarizationShader::RuntimeShader effect error\n");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
std::shared_ptr<Drawing::RuntimeShaderBuilder> builder =
|
||||
std::make_shared<Drawing::RuntimeShaderBuilder>(binarizationShaderEffect_);
|
||||
builder->SetChild("imageShader", imageShader);
|
||||
builder->SetUniform("low", aiBarLow_); // aiInvertCoef[0] is low
|
||||
builder->SetUniform("high", aiBarHigh_); // aiInvertCoef[1] is high
|
||||
builder->SetUniform("threshold", aiBarThreshold_); // aiInvertCoef[2] is threshold
|
||||
builder->SetUniform("opacity", aiBarOpacity_); // aiInvertCoef[3] is opacity
|
||||
builder->SetUniform("saturation", aiBarSaturation_); // aiInvertCoef[4] is saturation
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -25,14 +25,8 @@ namespace Rosen {
|
||||
GEGreyShaderFilter::GEGreyShaderFilter(const Drawing::GEGreyShaderFilterParams& params)
|
||||
: greyCoef1_(params.greyCoef1), greyCoef2_(params.greyCoef2)
|
||||
{
|
||||
if (!InitGreyAdjustmentEffect()) {
|
||||
LOGE("GEGreyShaderFilter::GEGreyShaderFilter failed to construct when initializing GreyAdjustmentEffect.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static std::shared_ptr<Drawing::RuntimeEffect> g_greyAdjustEffect;
|
||||
|
||||
std::shared_ptr<Drawing::Image> GEGreyShaderFilter::ProcessImage(Drawing::Canvas& canvas,
|
||||
const std::shared_ptr<Drawing::Image> image, const Drawing::Rect& src, const Drawing::Rect& dst)
|
||||
{
|
||||
@ -41,11 +35,12 @@ std::shared_ptr<Drawing::Image> GEGreyShaderFilter::ProcessImage(Drawing::Canvas
|
||||
return image;
|
||||
}
|
||||
|
||||
if (!g_greyAdjustEffect) {
|
||||
LOGE("GEGreyShaderFilter::DrawGreyAdjustment greyAdjustEffect is null");
|
||||
return nullptr;
|
||||
auto shader = GEShaderStore::GetInstance()->GetShader(SHADER_GREY);
|
||||
if (shader == nullptr) {
|
||||
return image;
|
||||
}
|
||||
Drawing::RuntimeShaderBuilder builder(g_greyAdjustEffect);
|
||||
|
||||
Drawing::RuntimeShaderBuilder builder(shader->GetShader());
|
||||
Drawing::Matrix matrix;
|
||||
auto imageShader = Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP,
|
||||
Drawing::TileMode::CLAMP, Drawing::SamplingOptions(Drawing::FilterMode::LINEAR), matrix);
|
||||
@ -55,69 +50,11 @@ std::shared_ptr<Drawing::Image> GEGreyShaderFilter::ProcessImage(Drawing::Canvas
|
||||
builder.SetUniform("coefficient2", greyCoef2_);
|
||||
auto greyImage = builder.MakeImage(canvas.GetGPUContext().get(), nullptr, image->GetImageInfo(), false);
|
||||
if (greyImage == nullptr) {
|
||||
LOGE("DrawGreyAdjustment successful");
|
||||
LOGE("DrawGreyAdjustment failed");
|
||||
return image;
|
||||
}
|
||||
return greyImage;
|
||||
};
|
||||
|
||||
bool GEGreyShaderFilter::InitGreyAdjustmentEffect()
|
||||
{
|
||||
if (g_greyAdjustEffect != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string GreyGradationString(R"(
|
||||
uniform shader imageShader;
|
||||
uniform float coefficient1;
|
||||
uniform float coefficient2;
|
||||
|
||||
float poww(float x, float y) {
|
||||
return (x < 0) ? -pow(-x, y) : pow(x, y);
|
||||
}
|
||||
|
||||
float calculateT_y(float rgb) {
|
||||
if (rgb > 127.5) { rgb = 255 - rgb; }
|
||||
float b = 38.0;
|
||||
float c = 45.0;
|
||||
float d = 127.5;
|
||||
float A = 106.5; // 3 * b - 3 * c + d;
|
||||
float B = -93; // 3 * (c - 2 * b);
|
||||
float C = 114; // 3 * b;
|
||||
float p = 0.816240163988; // (3 * A * C - pow(B, 2)) / (3 * pow(A, 2));
|
||||
float q = -rgb / 106.5 + 0.262253485943; // -rgb/A - B*C/(3*pow(A,2)) + 2*pow(B,3)/(27*pow(A,3))
|
||||
float s1 = -(q / 2.0);
|
||||
float s2 = sqrt(pow(s1, 2) + pow(p / 3, 3));
|
||||
return poww((s1 + s2), 1.0 / 3) + poww((s1 - s2), 1.0 / 3) - (B / (3 * A));
|
||||
}
|
||||
|
||||
float calculateGreyAdjustY(float rgb) {
|
||||
float t_r = calculateT_y(rgb);
|
||||
return (rgb < 127.5) ? (rgb + coefficient1 * pow((1 - t_r), 3)) :
|
||||
(rgb - coefficient2 * pow((1 - t_r), 3));
|
||||
}
|
||||
|
||||
half4 main(float2 coord) {
|
||||
vec3 color = vec3(imageShader.eval(coord).r, imageShader.eval(coord).g, imageShader.eval(coord).b);
|
||||
float Y = (0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 255;
|
||||
float U = (-0.147 * color.r - 0.289 * color.g + 0.436 * color.b) * 255;
|
||||
float V = (0.615 * color.r - 0.515 * color.g - 0.100 * color.b) * 255;
|
||||
Y = calculateGreyAdjustY(Y);
|
||||
color.r = (Y + 1.14 * V) / 255.0;
|
||||
color.g = (Y - 0.39 * U - 0.58 * V) / 255.0;
|
||||
color.b = (Y + 2.03 * U) / 255.0;
|
||||
|
||||
return vec4(color, 1.0);
|
||||
}
|
||||
)");
|
||||
g_greyAdjustEffect = Drawing::RuntimeEffect::CreateForShader(GreyGradationString);
|
||||
if (g_greyAdjustEffect == nullptr) {
|
||||
LOGE("GEGreyShaderFilter::InitGreyAdjustmentEffect blurEffect create failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -35,11 +35,6 @@ constexpr int32_t MAX_PASSES_LARGE_RADIUS = 7; // Maximum number of render passe
|
||||
constexpr float DILATED_CONVOLUTION_LARGE_RADIUS = 4.6f;
|
||||
// To avoid downscaling artifacts, interpolate the blurred fbo with the full composited image, up to this radius
|
||||
constexpr float MAX_CROSS_FADE_RADIUS = 10.0f;
|
||||
static std::shared_ptr<Drawing::RuntimeEffect> g_blurEffect;
|
||||
static std::shared_ptr<Drawing::RuntimeEffect> g_mixEffect;
|
||||
static std::shared_ptr<Drawing::RuntimeEffect> g_blurEffectAf;
|
||||
static std::shared_ptr<Drawing::RuntimeEffect> g_simpleFilter;
|
||||
|
||||
} // namespace
|
||||
|
||||
// Advanced Filter: we can get normalized uv offset from width and height
|
||||
@ -96,23 +91,16 @@ static const bool IS_ADVANCED_FILTER_USABLE_CHECK_ONCE = IsAdvancedFilterUsable(
|
||||
GEKawaseBlurShaderFilter::GEKawaseBlurShaderFilter(const Drawing::GEKawaseBlurShaderFilterParams& params)
|
||||
: radius_(params.radius)
|
||||
{
|
||||
if (!InitBlurEffect()) {
|
||||
LOGE("GEKawaseBlurShaderFilter::GEKawaseBlurShaderFilter failed when initializing BlurEffect.");
|
||||
return;
|
||||
}
|
||||
GEShaderStore::GetInstance()->GetShader(SHADER_BLUR);
|
||||
// Advanced Filter
|
||||
if (IS_ADVANCED_FILTER_USABLE_CHECK_ONCE && !InitBlurEffectForAdvancedFilter()) {
|
||||
LOGE("GEKawaseBlurShaderFilter::GEKawaseBlurShaderFilter failed when initializing BlurEffectAF.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InitMixEffect()) {
|
||||
LOGE("GEKawaseBlurShaderFilter::GEKawaseBlurShaderFilter failed when initializing MixEffect.");
|
||||
return;
|
||||
if (IS_ADVANCED_FILTER_USABLE_CHECK_ONCE) {
|
||||
GEShaderStore::GetInstance()->GetShader(SHADER_BLURAF);
|
||||
}
|
||||
GEShaderStore::GetInstance()->GetShader(SHADER_MIX);
|
||||
|
||||
if (GetBlurExtraFilterEnabled()) {
|
||||
if (!InitSimpleFilter()) {
|
||||
auto shader = GEShaderStore::GetInstance()->GetShader(SHADER_SIMPLE);
|
||||
if (shader == nullptr) {
|
||||
LOGE("GEKawaseBlurShaderFilter::GEKawaseBlurShaderFilter failed to construct SimpleFilter");
|
||||
return;
|
||||
}
|
||||
@ -138,14 +126,31 @@ std::shared_ptr<Drawing::ShaderEffect> GEKawaseBlurShaderFilter::ApplySimpleFilt
|
||||
const std::shared_ptr<Drawing::Image>& input, const std::shared_ptr<Drawing::ShaderEffect>& prevShader,
|
||||
const Drawing::ImageInfo& scaledInfo, const Drawing::SamplingOptions& linear) const
|
||||
{
|
||||
Drawing::RuntimeShaderBuilder simpleBlurBuilder(g_simpleFilter);
|
||||
simpleBlurBuilder.SetChild("imageInput", prevShader);
|
||||
auto shader = GEShaderStore::GetInstance()->GetShader(SHADER_SIMPLE);
|
||||
if (shader == nullptr) {
|
||||
LOGW("Get simple shader failed");
|
||||
return prevShader;
|
||||
}
|
||||
Drawing::RuntimeShaderBuilder simpleBlurBuilder(shader->GetShader());
|
||||
simpleBlurBuilder.SetChild("imageShader", prevShader);
|
||||
std::shared_ptr<Drawing::Image> tmpSimpleBlur(simpleBlurBuilder.MakeImage(
|
||||
canvas.GetGPUContext().get(), nullptr, scaledInfo, false));
|
||||
return Drawing::ShaderEffect::CreateImageShader(*tmpSimpleBlur, Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP,
|
||||
linear, Drawing::Matrix());
|
||||
}
|
||||
static std::shared_ptr<GEShader> GetAvailableShader()
|
||||
{
|
||||
// Advanced Filter: check is AF usable only the first time
|
||||
std::shared_ptr<GEShader> shader = nullptr;
|
||||
if (IS_ADVANCED_FILTER_USABLE_CHECK_ONCE) {
|
||||
shader = GEShaderStore::GetInstance()->GetShader(SHADER_BLURAF);
|
||||
}
|
||||
if (shader == nullptr) {
|
||||
shader = GEShaderStore::GetInstance()->GetShader(SHADER_BLUR);
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
std::shared_ptr<Drawing::Image> GEKawaseBlurShaderFilter::ProcessImage(Drawing::Canvas& canvas,
|
||||
const std::shared_ptr<Drawing::Image> image, const Drawing::Rect& src, const Drawing::Rect& dst)
|
||||
{
|
||||
@ -173,15 +178,19 @@ std::shared_ptr<Drawing::Image> GEKawaseBlurShaderFilter::ProcessImage(Drawing::
|
||||
Drawing::Matrix blurMatrix = BuildMatrix(src, scaledInfo, input);
|
||||
Drawing::SamplingOptions linear(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
|
||||
|
||||
// Advanced Filter: check is AF usable only the first time
|
||||
bool isUsingAF = IS_ADVANCED_FILTER_USABLE_CHECK_ONCE && g_blurEffectAf != nullptr;
|
||||
auto shader = GetAvailableShader();
|
||||
if (shader == nullptr) {
|
||||
return image;
|
||||
}
|
||||
|
||||
auto tmpShader = Drawing::ShaderEffect::CreateImageShader(
|
||||
*input, Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP, linear, blurMatrix);
|
||||
Drawing::RuntimeShaderBuilder blurBuilder(isUsingAF ? g_blurEffectAf : g_blurEffect);
|
||||
if (GetBlurExtraFilterEnabled() && g_simpleFilter) {
|
||||
|
||||
Drawing::RuntimeShaderBuilder blurBuilder(shader->GetShader());
|
||||
if (GetBlurExtraFilterEnabled() && GEShaderStore::GetInstance()->GetShader(SHADER_SIMPLE) != nullptr) {
|
||||
tmpShader = ApplySimpleFilter(canvas, input, tmpShader, scaledInfo, linear);
|
||||
}
|
||||
blurBuilder.SetChild("imageInput", tmpShader);
|
||||
blurBuilder.SetChild("imageShader", tmpShader);
|
||||
|
||||
auto offsetXY = radiusByPasses * blurScale_;
|
||||
SetBlurBuilderParam(blurBuilder, offsetXY, scaledInfo, width, height);
|
||||
@ -193,7 +202,7 @@ std::shared_ptr<Drawing::Image> GEKawaseBlurShaderFilter::ProcessImage(Drawing::
|
||||
auto blurShader = Drawing::ShaderEffect::CreateImageShader(
|
||||
*tmpBlur, Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP, linear, Drawing::Matrix());
|
||||
const float stepScale = static_cast<float>(i) * blurScale_;
|
||||
blurBuilder.SetChild("imageInput", blurShader);
|
||||
blurBuilder.SetChild("imageShader", blurShader);
|
||||
|
||||
// Advanced Filter
|
||||
auto offsetXYFilter = radiusByPasses * stepScale;
|
||||
@ -208,7 +217,7 @@ std::shared_ptr<Drawing::Image> GEKawaseBlurShaderFilter::ProcessImage(Drawing::
|
||||
bool GEKawaseBlurShaderFilter::IsInputValid(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image>& image,
|
||||
const Drawing::Rect& src, const Drawing::Rect& dst)
|
||||
{
|
||||
if (!g_blurEffect || !g_mixEffect || !image) {
|
||||
if (!image) {
|
||||
LOGE("GEKawaseBlurShaderFilter::shader error");
|
||||
return false;
|
||||
}
|
||||
@ -224,7 +233,8 @@ void GEKawaseBlurShaderFilter::SetBlurBuilderParam(Drawing::RuntimeShaderBuilder
|
||||
const Drawing::ImageInfo& scaledInfo, const int width, const int height)
|
||||
{
|
||||
// Advanced Filter: check is AF usable only the first time
|
||||
bool isUsingAF = IS_ADVANCED_FILTER_USABLE_CHECK_ONCE && g_blurEffectAf != nullptr;
|
||||
auto shader = GEShaderStore::GetInstance()->GetShader(SHADER_BLURAF);
|
||||
bool isUsingAF = IS_ADVANCED_FILTER_USABLE_CHECK_ONCE && shader != nullptr;
|
||||
if (isUsingAF) {
|
||||
SkV2 offsets[BLUR_SAMPLE_COUNT];
|
||||
OffsetInfo offsetInfo = { offsetXY, offsetXY, scaledInfo.GetWidth(), scaledInfo.GetHeight() };
|
||||
@ -253,123 +263,6 @@ const OHOS::Rosen::Drawing::Matrix GEKawaseBlurShaderFilter::BuildMatrix(
|
||||
return blurMatrix;
|
||||
}
|
||||
|
||||
bool GEKawaseBlurShaderFilter::InitBlurEffect()
|
||||
{
|
||||
if (g_blurEffect != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string blurString(R"(
|
||||
uniform shader imageInput;
|
||||
uniform float2 in_blurOffset;
|
||||
uniform float2 in_maxSizeXY;
|
||||
|
||||
half4 main(float2 xy) {
|
||||
half4 c = imageInput.eval(xy);
|
||||
c += imageInput.eval(float2(clamp(in_blurOffset.x + xy.x, 0, in_maxSizeXY.x),
|
||||
clamp(in_blurOffset.y + xy.y, 0, in_maxSizeXY.y)));
|
||||
c += imageInput.eval(float2(clamp(in_blurOffset.x + xy.x, 0, in_maxSizeXY.x),
|
||||
clamp(-in_blurOffset.y + xy.y, 0, in_maxSizeXY.y)));
|
||||
c += imageInput.eval(float2(clamp(-in_blurOffset.x + xy.x, 0, in_maxSizeXY.x),
|
||||
clamp(in_blurOffset.y + xy.y, 0, in_maxSizeXY.y)));
|
||||
c += imageInput.eval(float2(clamp(-in_blurOffset.x + xy.x, 0, in_maxSizeXY.x),
|
||||
clamp(-in_blurOffset.y + xy.y, 0, in_maxSizeXY.y)));
|
||||
return half4(c.rgb * 0.2, 1.0);
|
||||
}
|
||||
)");
|
||||
g_blurEffect = Drawing::RuntimeEffect::CreateForShader(blurString);
|
||||
if (g_blurEffect == nullptr) {
|
||||
LOGE("GEKawaseBlurShaderFilter::RuntimeShader blurEffect create failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GEKawaseBlurShaderFilter::InitMixEffect()
|
||||
{
|
||||
if (g_mixEffect != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string mixString(R"(
|
||||
uniform shader blurredInput;
|
||||
uniform shader originalInput;
|
||||
uniform float mixFactor;
|
||||
uniform float inColorFactor;
|
||||
|
||||
highp float random(float2 xy) {
|
||||
float t = dot(xy, float2(78.233, 12.9898));
|
||||
return fract(sin(t) * 43758.5453);
|
||||
}
|
||||
half4 main(float2 xy) {
|
||||
highp float noiseGranularity = inColorFactor / 255.0;
|
||||
half4 finalColor = mix(originalInput.eval(xy), blurredInput.eval(xy), mixFactor);
|
||||
float noise = mix(-noiseGranularity, noiseGranularity, random(xy));
|
||||
finalColor.rgb += noise;
|
||||
return finalColor;
|
||||
}
|
||||
)");
|
||||
g_mixEffect = Drawing::RuntimeEffect::CreateForShader(mixString);
|
||||
if (g_mixEffect == nullptr) {
|
||||
LOGE("GEKawaseBlurShaderFilter::RuntimeShader mixEffect create failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GEKawaseBlurShaderFilter::InitSimpleFilter()
|
||||
{
|
||||
if (g_simpleFilter != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string simpleShader(R"(
|
||||
uniform shader imageInput;
|
||||
half4 main(float2 xy) {
|
||||
return imageInput.eval(xy);
|
||||
}
|
||||
)");
|
||||
g_simpleFilter = Drawing::RuntimeEffect::CreateForShader(simpleShader);
|
||||
if (g_simpleFilter == nullptr) {
|
||||
LOGE("GEKawaseBlurShaderFilter::RuntimeShader failed to create simple filter");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Advanced Filter
|
||||
bool GEKawaseBlurShaderFilter::InitBlurEffectForAdvancedFilter()
|
||||
{
|
||||
if (g_blurEffectAf != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Drawing::RuntimeEffectOptions ops;
|
||||
ops.useAF = true;
|
||||
static std::string blurStringAF(R"(
|
||||
uniform shader imageInput;
|
||||
uniform float2 in_blurOffset[5];
|
||||
|
||||
half4 main(float2 xy) {
|
||||
half4 c = half4(0, 0, 0, 0);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
c += imageInput.eval(float2(xy.x + in_blurOffset[i].x, xy.y + in_blurOffset[i].y));
|
||||
}
|
||||
return half4(c.rgb * 0.2, 1.0);
|
||||
}
|
||||
)");
|
||||
g_blurEffectAf = Drawing::RuntimeEffect::CreateForShader(blurStringAF, ops);
|
||||
if (g_blurEffectAf == nullptr) {
|
||||
LOGE("%s: RuntimeShader blurEffectAF create failed", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Drawing::Matrix GEKawaseBlurShaderFilter::GetShaderTransform(
|
||||
const Drawing::Canvas* canvas, const Drawing::Rect& blurRect, float scaleW, float scaleH)
|
||||
{
|
||||
@ -387,7 +280,12 @@ void GEKawaseBlurShaderFilter::CheckInputImage(Drawing::Canvas& canvas, const st
|
||||
auto srcRect = Drawing::RectI(src.GetLeft(), src.GetTop(), src.GetRight(), src.GetBottom());
|
||||
if (image->GetImageInfo().GetBound() != srcRect) {
|
||||
auto resizedImage = std::make_shared<Drawing::Image>();
|
||||
if (resizedImage->BuildSubset(image, srcRect, *canvas.GetGPUContext())) {
|
||||
auto gpu = canvas.GetGPUContext();
|
||||
if (resizedImage == nullptr || gpu == nullptr) {
|
||||
LOGE("GEKawaseBlurShaderFilter::resize image failed, input nullptr");
|
||||
return;
|
||||
}
|
||||
if (resizedImage->BuildSubset(image, srcRect, *gpu)) {
|
||||
checkedImage = resizedImage;
|
||||
LOGD("GEKawaseBlurShaderFilter::resize image success");
|
||||
} else {
|
||||
@ -434,8 +332,11 @@ std::shared_ptr<Drawing::Image> GEKawaseBlurShaderFilter::ScaleAndAddRandomColor
|
||||
}
|
||||
|
||||
Drawing::SamplingOptions linear(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
|
||||
|
||||
Drawing::RuntimeShaderBuilder mixBuilder(g_mixEffect);
|
||||
auto shader = GEShaderStore::GetInstance()->GetShader(SHADER_MIX);
|
||||
if (shader == nullptr) {
|
||||
return blurImage;
|
||||
}
|
||||
Drawing::RuntimeShaderBuilder mixBuilder(shader->GetShader());
|
||||
const auto scaleMatrix = GetShaderTransform(
|
||||
&canvas, dst, dst.GetWidth() / blurImage->GetWidth(), dst.GetHeight() / blurImage->GetHeight());
|
||||
auto tmpShader = Drawing::ShaderEffect::CreateImageShader(
|
||||
|
@ -38,10 +38,6 @@ static bool GetMaskLinearBlurEnabled()
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::shared_ptr<Drawing::RuntimeEffect> GELinearGradientBlurShaderFilter::horizontalMeanBlurShaderEffect_ = nullptr;
|
||||
std::shared_ptr<Drawing::RuntimeEffect> GELinearGradientBlurShaderFilter::verticalMeanBlurShaderEffect_ = nullptr;
|
||||
std::shared_ptr<Drawing::RuntimeEffect> GELinearGradientBlurShaderFilter::maskBlurShaderEffect_ = nullptr;
|
||||
|
||||
GELinearGradientBlurShaderFilter::GELinearGradientBlurShaderFilter(
|
||||
const Drawing::GELinearGradientBlurShaderFilterParams& params)
|
||||
{
|
||||
@ -123,8 +119,6 @@ std::shared_ptr<Drawing::Image> GELinearGradientBlurShaderFilter::ProcessImage(D
|
||||
float radius = para->blurRadius_ - GELinearGradientBlurPara::ORIGINAL_BASE;
|
||||
radius = std::clamp(radius, 0.0f, 60.0f); // 60.0 represents largest blur radius
|
||||
radius = radius / 2 * imageScale_; // 2 half blur radius
|
||||
MakeHorizontalMeanBlurEffect();
|
||||
MakeVerticalMeanBlurEffect();
|
||||
DrawMeanLinearGradientBlur(image, canvas, radius, alphaGradientShader, dst);
|
||||
return image;
|
||||
}
|
||||
@ -297,85 +291,14 @@ std::shared_ptr<Drawing::ShaderEffect> GELinearGradientBlurShaderFilter::MakeAlp
|
||||
return Drawing::ShaderEffect::CreateLinearGradient(pts[0], pts[1], c, p, Drawing::TileMode::CLAMP);
|
||||
}
|
||||
|
||||
void GELinearGradientBlurShaderFilter::MakeHorizontalMeanBlurEffect()
|
||||
{
|
||||
static const std::string HorizontalBlurString(
|
||||
R"(
|
||||
uniform half r;
|
||||
uniform shader imageShader;
|
||||
uniform shader gradientShader;
|
||||
half4 meanFilter(float2 coord, half radius)
|
||||
{
|
||||
half4 sum = vec4(0.0);
|
||||
half div = 0;
|
||||
for (half x = -30.0; x < 30.0; x += 1.0) {
|
||||
if (x > radius) {
|
||||
break;
|
||||
}
|
||||
if (abs(x) < radius) {
|
||||
div += 1;
|
||||
sum += imageShader.eval(coord + float2(x, 0));
|
||||
}
|
||||
}
|
||||
return half4(sum.xyz / div, 1.0);
|
||||
}
|
||||
half4 main(float2 coord)
|
||||
{
|
||||
if (abs(gradientShader.eval(coord).a - 0) < 0.001) {
|
||||
return imageShader.eval(coord);
|
||||
}
|
||||
float val = clamp(r * gradientShader.eval(coord).a, 1.0, r);
|
||||
return meanFilter(coord, val);
|
||||
}
|
||||
)");
|
||||
|
||||
if (horizontalMeanBlurShaderEffect_ == nullptr) {
|
||||
horizontalMeanBlurShaderEffect_ = Drawing::RuntimeEffect::CreateForShader(HorizontalBlurString);
|
||||
}
|
||||
}
|
||||
|
||||
void GELinearGradientBlurShaderFilter::MakeVerticalMeanBlurEffect()
|
||||
{
|
||||
static const std::string VerticalBlurString(
|
||||
R"(
|
||||
uniform half r;
|
||||
uniform shader imageShader;
|
||||
uniform shader gradientShader;
|
||||
half4 meanFilter(float2 coord, half radius)
|
||||
{
|
||||
half4 sum = vec4(0.0);
|
||||
half div = 0;
|
||||
for (half y = -30.0; y < 30.0; y += 1.0) {
|
||||
if (y > radius) {
|
||||
break;
|
||||
}
|
||||
if (abs(y) < radius) {
|
||||
div += 1;
|
||||
sum += imageShader.eval(coord + float2(0, y));
|
||||
}
|
||||
}
|
||||
return half4(sum.xyz / div, 1.0);
|
||||
}
|
||||
half4 main(float2 coord)
|
||||
{
|
||||
if (abs(gradientShader.eval(coord).a - 0) < 0.001) {
|
||||
return imageShader.eval(coord);
|
||||
}
|
||||
float val = clamp(r * gradientShader.eval(coord).a, 1.0, r);
|
||||
return meanFilter(coord, val);
|
||||
}
|
||||
)");
|
||||
|
||||
if (verticalMeanBlurShaderEffect_ == nullptr) {
|
||||
verticalMeanBlurShaderEffect_ = Drawing::RuntimeEffect::CreateForShader(VerticalBlurString);
|
||||
}
|
||||
}
|
||||
|
||||
void GELinearGradientBlurShaderFilter::DrawMeanLinearGradientBlur(const std::shared_ptr<Drawing::Image>& image,
|
||||
Drawing::Canvas& canvas, float radius, std::shared_ptr<Drawing::ShaderEffect> alphaGradientShader,
|
||||
const Drawing::Rect& dst)
|
||||
{
|
||||
if (!horizontalMeanBlurShaderEffect_ || !verticalMeanBlurShaderEffect_ || !image) {
|
||||
auto shaderHorizontalBlur = GEShaderStore::GetInstance()->GetShader(SHADER_HORIBLUR);
|
||||
auto shaderVerticalBlur = GEShaderStore::GetInstance()->GetShader(SHADER_VERTBLUR);
|
||||
if (!shaderHorizontalBlur || !shaderVerticalBlur || !image) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -416,7 +339,11 @@ std::shared_ptr<Drawing::Image> GELinearGradientBlurShaderFilter::BuildMeanLinea
|
||||
originImageInfo.GetColorType(), originImageInfo.GetAlphaType(), originImageInfo.GetColorSpace());
|
||||
Drawing::Matrix m;
|
||||
Drawing::SamplingOptions linear(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
|
||||
Drawing::RuntimeShaderBuilder hBlurBuilder(horizontalMeanBlurShaderEffect_);
|
||||
auto shaderHBlur = GEShaderStore::GetInstance()->GetShader(SHADER_HORIBLUR);
|
||||
if (shaderHBlur == nullptr) {
|
||||
return image;
|
||||
}
|
||||
Drawing::RuntimeShaderBuilder hBlurBuilder(shaderHBlur->GetShader());
|
||||
hBlurBuilder.SetUniform("r", radius);
|
||||
auto shader1 = Drawing::ShaderEffect::CreateImageShader(
|
||||
*image, Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP, linear, blurMatrix);
|
||||
@ -425,7 +352,11 @@ std::shared_ptr<Drawing::Image> GELinearGradientBlurShaderFilter::BuildMeanLinea
|
||||
std::shared_ptr<Drawing::Image> tmpBlur(
|
||||
hBlurBuilder.MakeImage(canvas.GetGPUContext().get(), nullptr, scaledInfo, false));
|
||||
|
||||
Drawing::RuntimeShaderBuilder vBlurBuilder(verticalMeanBlurShaderEffect_);
|
||||
auto shaderVBlur = GEShaderStore::GetInstance()->GetShader(SHADER_VERTBLUR);
|
||||
if (shaderVBlur == nullptr) {
|
||||
return image;
|
||||
}
|
||||
Drawing::RuntimeShaderBuilder vBlurBuilder(shaderVBlur->GetShader());
|
||||
vBlurBuilder.SetUniform("r", radius);
|
||||
auto tmpBlurShader = Drawing::ShaderEffect::CreateImageShader(
|
||||
*tmpBlur, Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP, linear, m);
|
||||
@ -485,42 +416,11 @@ std::shared_ptr<Drawing::RuntimeShaderBuilder> GELinearGradientBlurShaderFilter:
|
||||
std::shared_ptr<Drawing::ShaderEffect> srcImageShader, std::shared_ptr<Drawing::ShaderEffect> blurImageShader,
|
||||
std::shared_ptr<Drawing::ShaderEffect> gradientShader)
|
||||
{
|
||||
if (maskBlurShaderEffect_ == nullptr) {
|
||||
static const char* prog = R"(
|
||||
uniform shader srcImageShader;
|
||||
uniform shader blurImageShader;
|
||||
uniform shader gradientShader;
|
||||
half4 meanFilter(float2 coord)
|
||||
{
|
||||
vec3 srcColor = vec3(srcImageShader.eval(coord).r,
|
||||
srcImageShader.eval(coord).g, srcImageShader.eval(coord).b);
|
||||
vec3 blurColor = vec3(blurImageShader.eval(coord).r,
|
||||
blurImageShader.eval(coord).g, blurImageShader.eval(coord).b);
|
||||
float gradient = gradientShader.eval(coord).a;
|
||||
|
||||
vec3 color = blurColor * gradient + srcColor * (1 - gradient);
|
||||
return vec4(color, 1.0);
|
||||
}
|
||||
half4 main(float2 coord)
|
||||
{
|
||||
if (abs(gradientShader.eval(coord).a) < 0.001) {
|
||||
return srcImageShader.eval(coord);
|
||||
}
|
||||
|
||||
if (abs(gradientShader.eval(coord).a) > 0.999) {
|
||||
return blurImageShader.eval(coord);
|
||||
}
|
||||
|
||||
return meanFilter(coord);
|
||||
}
|
||||
)";
|
||||
maskBlurShaderEffect_ = Drawing::RuntimeEffect::CreateForShader(prog);
|
||||
if (maskBlurShaderEffect_ == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto shader = GEShaderStore::GetInstance()->GetShader(SHADER_MASKBLUR);
|
||||
if (shader == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto builder = std::make_shared<Drawing::RuntimeShaderBuilder>(maskBlurShaderEffect_);
|
||||
auto builder = std::make_shared<Drawing::RuntimeShaderBuilder>(shader->GetShader());
|
||||
builder->SetChild("srcImageShader", srcImageShader);
|
||||
builder->SetChild("blurImageShader", blurImageShader);
|
||||
builder->SetChild("gradientShader", gradientShader);
|
||||
|
102
rosen/modules/graphics_effect/src/ge_magnifier_shader_filter.cpp
Normal file
102
rosen/modules/graphics_effect/src/ge_magnifier_shader_filter.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.
|
||||
*/
|
||||
#include "ge_magnifier_shader_filter.h"
|
||||
|
||||
#include "ge_log.h"
|
||||
#include "ge_system_properties.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
|
||||
std::shared_ptr<Drawing::RuntimeEffect> GEMagnifierShaderFilter::magnifierShaderEffect_ = nullptr;
|
||||
|
||||
GEMagnifierShaderFilter::GEMagnifierShaderFilter(const Drawing::GEMagnifierShaderFilterParams& params)
|
||||
{
|
||||
if (!InitMagnifierEffect()) {
|
||||
LOGE("GEMagnifierShaderFilter::GEMagnifierShaderFilter failed when initializing MagnifierEffect.");
|
||||
return;
|
||||
}
|
||||
|
||||
magnifierPara_ = std::make_shared<GEMagnifierParams>();
|
||||
magnifierPara_->factor_ = params.factor;
|
||||
magnifierPara_->width_ = params.width;
|
||||
magnifierPara_->height_ = params.height;
|
||||
magnifierPara_->borderWidth_ = params.borderWidth;
|
||||
magnifierPara_->cornerRadius_ = params.cornerRadius;
|
||||
magnifierPara_->shadowOffsetX_ = params.shadowOffsetX;
|
||||
magnifierPara_->shadowOffsetY_ = params.shadowOffsetY;
|
||||
magnifierPara_->shadowSize_ = params.shadowSize;
|
||||
magnifierPara_->shadowStrength_ = params.shadowStrength;
|
||||
magnifierPara_->gradientMaskColor1_ = params.gradientMaskColor1;
|
||||
magnifierPara_->gradientMaskColor2_ = params.gradientMaskColor2;
|
||||
magnifierPara_->outerContourColor1_ = params.outerContourColor1;
|
||||
magnifierPara_->outerContourColor2_ = params.outerContourColor2;
|
||||
}
|
||||
|
||||
std::shared_ptr<Drawing::Image> GEMagnifierShaderFilter::ProcessImage(Drawing::Canvas& canvas,
|
||||
const std::shared_ptr<Drawing::Image> image, const Drawing::Rect& src, const Drawing::Rect& dst)
|
||||
{
|
||||
if (image == nullptr || magnifierPara_ == nullptr) {
|
||||
LOGE("GEMagnifierShaderFilter::ProcessImage image or para is null");
|
||||
return image;
|
||||
}
|
||||
|
||||
Drawing::Matrix matrix;
|
||||
auto imageShader = Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP,
|
||||
Drawing::TileMode::CLAMP, Drawing::SamplingOptions(Drawing::FilterMode::LINEAR), matrix);
|
||||
float imageWidth = image->GetWidth();
|
||||
float imageHeight = image->GetHeight();
|
||||
auto builder = MakeMagnifierShader(imageShader, imageWidth, imageHeight);
|
||||
|
||||
auto resultImage = builder->MakeImage(canvas.GetGPUContext().get(), nullptr, image->GetImageInfo(), false);
|
||||
if (resultImage == nullptr) {
|
||||
LOGE("GEMagnifierShaderFilter::ProcessImage resultImage is null");
|
||||
return image;
|
||||
}
|
||||
|
||||
return resultImage;
|
||||
}
|
||||
|
||||
std::shared_ptr<Drawing::RuntimeShaderBuilder> GEMagnifierShaderFilter::MakeMagnifierShader(
|
||||
std::shared_ptr<Drawing::ShaderEffect> imageShader, float imageWidth, float imageHeight)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool GEMagnifierShaderFilter::InitMagnifierEffect()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void GEMagnifierShaderFilter::ConvertToRgba(uint32_t rgba, float* color)
|
||||
{
|
||||
int16_t alpha = static_cast<int16_t>(rgba & 0xFF); // 0xff byte mask
|
||||
int16_t red = static_cast<int16_t>((rgba & 0xFF000000) >> 24); // 0xff000000 red mask, 24 red shift
|
||||
int16_t green = static_cast<int16_t>((rgba & 0x00FF0000) >> 16); // 0x00ff0000 green mask, 16 green shift
|
||||
int16_t blue = static_cast<int16_t>((rgba & 0x0000FF00) >> 8); // 0x0000ff00 blue mask, 8 blue shift
|
||||
|
||||
color[0] = red * 1.0f / 255.0f; // 255.0f is the max value, 0 red
|
||||
color[1] = green * 1.0f / 255.0f; // 255.0f is the max value, 1 green
|
||||
color[2] = blue * 1.0f / 255.0f; // 255.0f is the max value, 2 blue
|
||||
color[3] = alpha * 1.0f / 255.0f; // 255.0f is the max value, 3 alpha
|
||||
}
|
||||
|
||||
const std::string GEMagnifierShaderFilter::GetDescription() const
|
||||
{
|
||||
return "GEMagnifierShaderFilter";
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
@ -20,7 +20,9 @@
|
||||
#include "ge_kawase_blur_shader_filter.h"
|
||||
#include "ge_linear_gradient_blur_shader_filter.h"
|
||||
#include "ge_log.h"
|
||||
#include "ge_magnifier_shader_filter.h"
|
||||
#include "ge_visual_effect_impl.h"
|
||||
#include "ge_water_ripple_filter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace GraphicsEffectEngine {
|
||||
@ -75,10 +77,10 @@ std::vector<std::shared_ptr<GEShaderFilter>> GERender::GenerateShaderFilter(
|
||||
for (auto vef : veContainer.GetFilters()) {
|
||||
auto ve = vef->GetImpl();
|
||||
std::shared_ptr<GEShaderFilter> shaderFilter;
|
||||
LOGD("GERender::shaderFilters %{public}d", (int)ve->GetFilterType());
|
||||
switch (ve->GetFilterType()) {
|
||||
case Drawing::GEVisualEffectImpl::FilterType::KAWASE_BLUR: {
|
||||
const auto& kawaseParams = ve->GetKawaseParams();
|
||||
LOGD("GERender::KAWASE_BLUR %{public}d", kawaseParams->radius);
|
||||
shaderFilter = std::make_shared<GEKawaseBlurShaderFilter>(*kawaseParams);
|
||||
break;
|
||||
}
|
||||
@ -88,29 +90,34 @@ std::vector<std::shared_ptr<GEShaderFilter>> GERender::GenerateShaderFilter(
|
||||
LOGE("GERender::HPS_BLUR hpsParams is null.");
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGD("GERender::HPS_BLUR %{public}f", hpsParams->radius);
|
||||
shaderFilter = std::make_shared<GEHpsBlurShaderFilter>(*hpsParams);
|
||||
break;
|
||||
}
|
||||
case Drawing::GEVisualEffectImpl::FilterType::AIBAR: {
|
||||
const auto& aiBarParams = ve->GetAIBarParams();
|
||||
LOGD("GERender::AIBAR %{public}f,", aiBarParams->aiBarLow);
|
||||
shaderFilter = std::make_shared<GEAIBarShaderFilter>(*aiBarParams);
|
||||
break;
|
||||
}
|
||||
case Drawing::GEVisualEffectImpl::FilterType::GREY: {
|
||||
const auto& greyParams = ve->GetGreyParams();
|
||||
LOGD("GERender::GREY %{public}f,", greyParams->greyCoef1);
|
||||
shaderFilter = std::make_shared<GEGreyShaderFilter>(*greyParams);
|
||||
break;
|
||||
}
|
||||
case Drawing::GEVisualEffectImpl::FilterType::LINEAR_GRADIENT_BLUR: {
|
||||
const auto& linearGradientBlurParams = ve->GetLinearGradientBlurParams();
|
||||
LOGD("GERender::LINEAR_GRADIENT_BLUR %{public}f,", linearGradientBlurParams->blurRadius);
|
||||
shaderFilter = std::make_shared<GELinearGradientBlurShaderFilter>(*linearGradientBlurParams);
|
||||
break;
|
||||
}
|
||||
case Drawing::GEVisualEffectImpl::FilterType::WATER_RIPPLE: {
|
||||
const auto& waterRippleParams = ve->GetWaterRippleParams();
|
||||
shaderFilter = std::make_shared<GEWaterRippleFilter>(*waterRippleParams);
|
||||
break;
|
||||
}
|
||||
case Drawing::GEVisualEffectImpl::FilterType::MAGNIFIER: {
|
||||
const auto& magnifierParams = ve->GetMagnifierParams();
|
||||
shaderFilter = std::make_shared<GEMagnifierShaderFilter>(*magnifierParams);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
369
rosen/modules/graphics_effect/src/ge_shader.cpp
Normal file
369
rosen/modules/graphics_effect/src/ge_shader.cpp
Normal file
@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.
|
||||
*/
|
||||
|
||||
#include "ge_shader.h"
|
||||
#include "ge_shader_string.h"
|
||||
#include "ge_log.h"
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <random>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
|
||||
static std::shared_ptr<GEShaderStore> g_ShaderStoreInstance = nullptr;
|
||||
std::shared_ptr<GEShaderStore> GEShaderStore::GetInstance()
|
||||
{
|
||||
if (g_ShaderStoreInstance == nullptr) {
|
||||
g_ShaderStoreInstance = std::make_shared<GEShaderStore>();
|
||||
g_ShaderStoreInstance->Initialize();
|
||||
}
|
||||
return g_ShaderStoreInstance;
|
||||
}
|
||||
|
||||
void GEShaderStore::RegisterShader(ShaderIndex key, const std::string& name, ShaderType type, const std::string& shader,
|
||||
const Drawing::RuntimeEffectOptions* opt)
|
||||
{
|
||||
auto sh = std::make_shared<GEShader>(name, type, shader, opt);
|
||||
shaderObjMap_[key] = sh;
|
||||
}
|
||||
|
||||
void GEShaderStore::Initialize()
|
||||
{
|
||||
LOGD("GEShaderStore::Initialize");
|
||||
RegisterShader(SHADER_AIBAR, "AIBAR", TYPE_NO_REFERENCE, g_aibarString, nullptr);
|
||||
RegisterShader(SHADER_GREY, "Grey", TYPE_NO_REFERENCE, g_greyGradationString, nullptr);
|
||||
RegisterShader(SHADER_BLUR, "blur", TYPE_REFERENCE_AROUND, g_blurString, nullptr);
|
||||
Drawing::RuntimeEffectOptions opt;
|
||||
opt.useAF = true;
|
||||
RegisterShader(SHADER_BLURAF, "blurAf", TYPE_REFERENCE_AROUND, g_blurStringAF, &opt);
|
||||
RegisterShader(SHADER_MIX, "mix", TYPE_REFERENCE_AROUND, g_mixString, nullptr);
|
||||
RegisterShader(SHADER_HORIBLUR, "horizontal", TYPE_REFERENCE_AROUND, g_hBlurString, nullptr);
|
||||
RegisterShader(SHADER_VERTBLUR, "vertical", TYPE_REFERENCE_AROUND, g_vBlurString, nullptr);
|
||||
RegisterShader(SHADER_MASKBLUR, "maskblur", TYPE_REFERENCE_AROUND, g_maskBlurString, nullptr);
|
||||
RegisterShader(SHADER_SIMPLE, "Simple", TYPE_NO_REFERENCE, g_simpleString, nullptr);
|
||||
}
|
||||
|
||||
static std::string GetKey(const std::vector<ShaderIndex>& which)
|
||||
{
|
||||
std::string key = {};
|
||||
for (auto w : which) {
|
||||
key += std::to_string(w);
|
||||
key += "_";
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
std::shared_ptr<GEShader> GEShaderStore::GetShader(ShaderIndex which)
|
||||
{
|
||||
LOGD("GEShaderStore::GetShader %{public}d ", which);
|
||||
std::string key = std::to_string(which) + "_";
|
||||
if (shaderMap_.count(key)) {
|
||||
LOGD("GetShader %{public}d is exist, total %{public}zu", which, shaderMap_.size());
|
||||
return shaderMap_[key];
|
||||
}
|
||||
|
||||
if (!shaderObjMap_.count(which)) {
|
||||
LOGD("GetShader %{public}d is NOT registered", which);
|
||||
return nullptr;
|
||||
}
|
||||
// copy a new obj because if combine failed, we don't need to recover the obj in shaderobjmap_
|
||||
std::shared_ptr<GEShader> shaderObj = std::make_shared<GEShader>(shaderObjMap_[which]);
|
||||
|
||||
if (shaderObj->Compile(shaderObj->GetOptions()) != GE_ERROR_NONE) {
|
||||
// else if failed, can be combined but can not be compiled, not accepted
|
||||
LOGD("GetShader %{public}d, shader %{public}s compile failed", which, shaderObj->GetName().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shaderMap_[key] = shaderObj;
|
||||
return shaderObj;
|
||||
}
|
||||
|
||||
std::shared_ptr<GEShader> GEShaderStore::GetShader(const std::vector<ShaderIndex>& which)
|
||||
{
|
||||
if (which.empty()) {
|
||||
LOGD("GetShader but input is empty");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string key = GetKey(which);
|
||||
LOGD("GEShaderStore::GetShader %{public}s ", key.c_str());
|
||||
if (shaderMap_.count(key)) {
|
||||
LOGD("GetShader %{public}s is exist, total %{public}zu", key.c_str(), shaderMap_.size());
|
||||
return shaderMap_[key];
|
||||
}
|
||||
|
||||
for (auto w : which) {
|
||||
if (!shaderObjMap_.count(w)) {
|
||||
LOGD("GetShader %{public}d is NOT registered", w);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<GEShader> shaderObj = std::make_shared<GEShader>(shaderObjMap_[which[0]]);
|
||||
size_t curWhich = 1;
|
||||
for (; curWhich < which.size(); curWhich++) {
|
||||
auto rth = shaderObjMap_[which[curWhich]];
|
||||
if (!shaderObj->Combine(*rth)) {
|
||||
LOGD("GetShader %{public}s, %{public}s combine %{public}s failed",
|
||||
key.c_str(), shaderObj->GetName().c_str(), rth->GetName().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (shaderObj->Compile(shaderObj->GetOptions()) != GE_ERROR_NONE) {
|
||||
LOGD("GetShader %{public}s, shader %{public}s compile filed", key.c_str(), shaderObj->GetName().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shaderMap_[key] = shaderObj;
|
||||
return shaderObj;
|
||||
}
|
||||
|
||||
GEShader::GEShader(
|
||||
const std::string& name, ShaderType type, const std::string& shaderStr, const Drawing::RuntimeEffectOptions* opt)
|
||||
: type_(type), name_(name), shaderStr_(shaderStr)
|
||||
{
|
||||
if (opt != nullptr) {
|
||||
opt_ = new Drawing::RuntimeEffectOptions;
|
||||
opt_->forceNoInline = opt->forceNoInline;
|
||||
opt_->useAF = opt->useAF;
|
||||
}
|
||||
}
|
||||
|
||||
GEShader::GEShader(const std::shared_ptr<GEShader> rth)
|
||||
{
|
||||
if (rth != nullptr) {
|
||||
name_ = rth->GetName();
|
||||
type_ = rth->GetType();
|
||||
shaderStr_ = rth->GetString();
|
||||
auto opt = rth->GetOptions();
|
||||
if (opt != nullptr) {
|
||||
opt_ = new Drawing::RuntimeEffectOptions;
|
||||
opt_->forceNoInline = opt->forceNoInline;
|
||||
opt_->useAF = opt->useAF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GEShader::~GEShader()
|
||||
{
|
||||
if (opt_ != nullptr) {
|
||||
delete opt_;
|
||||
opt_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GEShader::GetName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
ShaderType GEShader::GetType() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
std::string GEShader::GetString() const
|
||||
{
|
||||
return shaderStr_;
|
||||
}
|
||||
|
||||
GEShader& GEShader::String(const std::string& shaderStr)
|
||||
{
|
||||
shaderStr_ = shaderStr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
GEShader& GEShader::Type(ShaderType type)
|
||||
{
|
||||
type_ = type;
|
||||
return *this;
|
||||
}
|
||||
|
||||
GEShader& GEShader::Name(const std::string& name)
|
||||
{
|
||||
name_ = name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Drawing::RuntimeEffectOptions* GEShader::GetOptions() const
|
||||
{
|
||||
return opt_;
|
||||
}
|
||||
|
||||
// if failed, nothing will be changed
|
||||
bool GEShader::Combine(const GEShader& rth)
|
||||
{
|
||||
auto ret = Connect(rth);
|
||||
if (ret != GE_ERROR_NONE) {
|
||||
LOGW("combine shader failed, cause = %{public}d", ret);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<Drawing::RuntimeEffect> GEShader::GetShader() const
|
||||
{
|
||||
return shader_;
|
||||
}
|
||||
|
||||
GE_Error GEShader::Compile(const Drawing::RuntimeEffectOptions* ops)
|
||||
{
|
||||
std::shared_ptr<Drawing::RuntimeEffect> shader;
|
||||
if (ops != nullptr) {
|
||||
shader = Drawing::RuntimeEffect::CreateForShader(shaderStr_, *ops);
|
||||
} else {
|
||||
shader = Drawing::RuntimeEffect::CreateForShader(shaderStr_);
|
||||
}
|
||||
|
||||
if (shader == nullptr) {
|
||||
LOGE("GEShader::Compile %{public}s failed", name_.c_str());
|
||||
return GE_ERROR_SHADER_COMPILE_FAILED;
|
||||
}
|
||||
shader_ = shader;
|
||||
return GE_ERROR_NONE;
|
||||
}
|
||||
|
||||
GE_Error GEShader::Connect(const GEShader& subShader)
|
||||
{
|
||||
std::string newName = name_ + "_" + subShader.GetName();
|
||||
if (subShader.GetType() != TYPE_NO_REFERENCE) {
|
||||
return GE_ERROR_NOT_ACCEPTED_CONNECT;
|
||||
}
|
||||
|
||||
std::string targetStr = {};
|
||||
if (CombineShaderString(targetStr, shaderStr_, subShader.GetString()) != GE_ERROR_NONE) {
|
||||
return GE_ERROR_SHADER_STRING_INVALID;
|
||||
}
|
||||
|
||||
name_ = newName;
|
||||
shaderStr_ = targetStr;
|
||||
|
||||
auto rthOpt = subShader.GetOptions();
|
||||
if (rthOpt != nullptr) {
|
||||
if (opt_ != nullptr) {
|
||||
opt_->useAF |= rthOpt->useAF;
|
||||
opt_->forceNoInline |= rthOpt->forceNoInline;
|
||||
} else {
|
||||
opt_ = new Drawing::RuntimeEffectOptions;
|
||||
opt_->forceNoInline = rthOpt->forceNoInline;
|
||||
opt_->useAF = rthOpt->useAF;
|
||||
}
|
||||
}
|
||||
return GE_ERROR_NONE;
|
||||
}
|
||||
|
||||
static std::string PrepareFirstString(
|
||||
const std::string& sourceStr, const std::string& oldStr, const std::string& newStr)
|
||||
{
|
||||
std::istringstream iss(sourceStr);
|
||||
std::ostringstream oss;
|
||||
std::string line;
|
||||
while (std::getline(iss, line)) {
|
||||
size_t pos = 0;
|
||||
while ((pos = line.find(oldStr, pos)) != std::string::npos) {
|
||||
// find "return ", maybe a sub path
|
||||
line.replace(pos, oldStr.length(), newStr);
|
||||
pos += newStr.length();
|
||||
}
|
||||
oss << line << '\n';
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
static std::string PrepareSecondString(
|
||||
const std::string& sourceStr, const std::string& oldStr, const std::string& newStr)
|
||||
{
|
||||
std::istringstream iss(sourceStr);
|
||||
std::ostringstream oss;
|
||||
std::string line;
|
||||
bool first = true;
|
||||
// Replace subStr with newStr in the line
|
||||
std::string reg(R"(\\.[\s\S]*[a-zA-Z0-9]*\\([a-zA-Z0-9]*\\))");
|
||||
std::regex from(oldStr + reg);
|
||||
std::string to = newStr;
|
||||
|
||||
while (std::getline(iss, line)) {
|
||||
if (first && line.find(oldStr) != std::string::npos) {
|
||||
// Skip the first line that contains subStr to remove duplicate imageShader
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
line = std::regex_replace(line, from, to);
|
||||
oss << line << '\n';
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
static std::string GenSimpleUUIDString()
|
||||
{
|
||||
const std::string characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
static constexpr int maxNumberRange = 99; // the max random number
|
||||
std::random_device randomDevice;
|
||||
std::mt19937 generator(randomDevice());
|
||||
std::uniform_int_distribution<> charDistribution(0, characters.size() - 1);
|
||||
std::uniform_int_distribution<> numDistribution(0, maxNumberRange);
|
||||
|
||||
std::string randomString = "";
|
||||
randomString += characters[charDistribution(generator)];
|
||||
randomString += std::to_string(numDistribution(generator));
|
||||
|
||||
return randomString;
|
||||
}
|
||||
/*
|
||||
the two shaders should follow the rules as below:
|
||||
1. import image param's name should be imageShader (casesentense)
|
||||
2. param of main function should be float2 type and the name should be "coord", and only one param
|
||||
*/
|
||||
GE_Error GEShader::CombineShaderString(std::string& cbStr, const std::string& shaderA, const std::string& shaderB)
|
||||
{
|
||||
// each valid shader string should be have 5 matches;
|
||||
static constexpr int validMatchCount = 5;
|
||||
static constexpr int sectionParam = 1; // 1 : the string before main
|
||||
static constexpr int sectionMainTitle = 2; // 2 : the string of main(...)
|
||||
static constexpr int sectionMainBody = 3; // 3 : the string in main
|
||||
static constexpr int sectionMainOthers = 4; // 4: the rest of shader string
|
||||
std::string var = GenSimpleUUIDString();
|
||||
auto strShaderB = PrepareSecondString(shaderB, "imageShader", var);
|
||||
|
||||
std::regex re(R"(([\s\S]*)(half4\s+main\s*\(\s*float2\s+coord\s*\)\s*\{)([\s\S]*)(\}))");
|
||||
|
||||
std::smatch matchA;
|
||||
std::regex_search(shaderA, matchA, re);
|
||||
if (matchA.size() < validMatchCount) {
|
||||
LOGW("GEShader::CombineShaderString, invalid first shader string");
|
||||
return GE_ERROR_SHADER_STRING_INVALID;
|
||||
}
|
||||
std::smatch matchB;
|
||||
std::regex_search(strShaderB, matchB, re);
|
||||
if (matchB.size() < validMatchCount) {
|
||||
LOGW("GEShader::CombineShaderString, invalid second shader string");
|
||||
return GE_ERROR_SHADER_STRING_INVALID;
|
||||
}
|
||||
// if have multi return , need to jump to next section
|
||||
std::string shaderABody = PrepareFirstString(matchA[sectionMainBody].str(), "return ", var +" = ");
|
||||
|
||||
std::string resultVar("vec4 " + var + "=vec4(1.0);\n");
|
||||
cbStr = matchA[sectionParam].str() + "\n" + matchB[sectionParam].str() + "\n" + resultVar +
|
||||
matchA[sectionMainTitle].str() + "\n{" + shaderABody + "}\n{" + matchB[sectionMainBody].str() + "}\n" +
|
||||
matchA[sectionMainOthers].str();
|
||||
|
||||
return GE_ERROR_NONE;
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
@ -69,6 +69,11 @@ void GEVisualEffect::SetParam(const std::string& tag, bool param)
|
||||
visualEffectImpl_->SetParam(tag, param);
|
||||
}
|
||||
|
||||
void GEVisualEffect::SetParam(const std::string& tag, uint32_t param)
|
||||
{
|
||||
visualEffectImpl_->SetParam(tag, param);
|
||||
}
|
||||
|
||||
} // namespace Drawing
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -53,6 +53,18 @@ std::map<const std::string, std::function<void(GEVisualEffectImpl*)>> GEVisualEf
|
||||
impl->SetFilterType(GEVisualEffectImpl::FilterType::HPS_BLUR);
|
||||
impl->MakeHpsBlurParams();
|
||||
}
|
||||
},
|
||||
{ GE_FILTER_WATER_RIPPLE,
|
||||
[](GEVisualEffectImpl* impl) {
|
||||
impl->SetFilterType(GEVisualEffectImpl::FilterType::WATER_RIPPLE);
|
||||
impl->MakeWaterRippleParams();
|
||||
}
|
||||
},
|
||||
{ GE_FILTER_MAGNIFIER,
|
||||
[](GEVisualEffectImpl* impl) {
|
||||
impl->SetFilterType(GEVisualEffectImpl::FilterType::MAGNIFIER);
|
||||
impl->MakeMagnifierParams();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -134,6 +146,14 @@ void GEVisualEffectImpl::SetParam(const std::string& tag, float param)
|
||||
SetHpsBlurParams(tag, param);
|
||||
break;
|
||||
}
|
||||
case FilterType::WATER_RIPPLE: {
|
||||
SetWaterRippleParams(tag, param);
|
||||
break;
|
||||
}
|
||||
case FilterType::MAGNIFIER: {
|
||||
SetMagnifierParamsFloat(tag, param);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -182,6 +202,18 @@ void GEVisualEffectImpl::SetParam(const std::string& tag, const std::vector<std:
|
||||
}
|
||||
}
|
||||
|
||||
void GEVisualEffectImpl::SetParam(const std::string& tag, const uint32_t param)
|
||||
{
|
||||
switch (filterType_) {
|
||||
case FilterType::MAGNIFIER: {
|
||||
SetMagnifierParamsUint32(tag, param);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GEVisualEffectImpl::SetAIBarParams(const std::string& tag, float param)
|
||||
{
|
||||
if (aiBarParams_ == nullptr) {
|
||||
@ -268,6 +300,86 @@ void GEVisualEffectImpl::SetHpsBlurParams(const std::string& tag, float param)
|
||||
}
|
||||
}
|
||||
|
||||
void GEVisualEffectImpl::SetWaterRippleParams(const std::string& tag, float param)
|
||||
{
|
||||
if (waterRippleParams_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
static std::unordered_map<std::string, std::function<void(GEVisualEffectImpl*, float)>> actions = {
|
||||
|
||||
{ GE_FILTER_WATER_RIPPLE_PROGRESS,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->waterRippleParams_->progress = p; } },
|
||||
{ GE_FILTER_WATER_RIPPLE_WAVE_NUM,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->waterRippleParams_->waveCount = p; } },
|
||||
{ GE_FILTER_WATER_RIPPLE_RIPPLE_CENTER_X,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->waterRippleParams_->rippleCenterX = p; } },
|
||||
{ GE_FILTER_WATER_RIPPLE_RIPPLE_CENTER_Y,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->waterRippleParams_->rippleCenterY = p; } },
|
||||
};
|
||||
|
||||
auto it = actions.find(tag);
|
||||
if (it != actions.end()) {
|
||||
it->second(this, param);
|
||||
}
|
||||
}
|
||||
|
||||
void GEVisualEffectImpl::SetMagnifierParamsFloat(const std::string& tag, float param)
|
||||
{
|
||||
if (magnifierParams_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
static std::unordered_map<std::string, std::function<void(GEVisualEffectImpl*, float)>> actions = {
|
||||
{ GE_FILTER_MAGNIFIER_FACTOR,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->magnifierParams_->factor = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_WIDTH,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->magnifierParams_->width = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_HEIGHT,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->magnifierParams_->height = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_BORDER_WIDTH,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->magnifierParams_->borderWidth = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_CORNER_RADIUS,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->magnifierParams_->cornerRadius = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_SHADOW_OFFSET_X,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->magnifierParams_->shadowOffsetX = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_SHADOW_OFFSET_Y,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->magnifierParams_->shadowOffsetY = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_SHADOW_SIZE,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->magnifierParams_->shadowSize = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_SHADOW_STRENGTH,
|
||||
[](GEVisualEffectImpl* obj, float p) { obj->magnifierParams_->shadowStrength = p; } }
|
||||
};
|
||||
|
||||
auto it = actions.find(tag);
|
||||
if (it != actions.end()) {
|
||||
it->second(this, param);
|
||||
}
|
||||
}
|
||||
|
||||
void GEVisualEffectImpl::SetMagnifierParamsUint32(const std::string& tag, uint32_t param)
|
||||
{
|
||||
if (magnifierParams_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
static std::unordered_map<std::string, std::function<void(GEVisualEffectImpl*, uint32_t)>> actions = {
|
||||
{ GE_FILTER_MAGNIFIER_GRADIENT_MASK_COLOR_1,
|
||||
[](GEVisualEffectImpl* obj, uint32_t p) { obj->magnifierParams_->gradientMaskColor1 = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_GRADIENT_MASK_COLOR_2,
|
||||
[](GEVisualEffectImpl* obj, uint32_t p) { obj->magnifierParams_->gradientMaskColor2 = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_OUTER_CONTOUR_COLOR_1,
|
||||
[](GEVisualEffectImpl* obj, uint32_t p) { obj->magnifierParams_->outerContourColor1 = p; } },
|
||||
{ GE_FILTER_MAGNIFIER_OUTER_CONTOUR_COLOR_2,
|
||||
[](GEVisualEffectImpl* obj, uint32_t p) { obj->magnifierParams_->outerContourColor2 = p; } }
|
||||
};
|
||||
|
||||
auto it = actions.find(tag);
|
||||
if (it != actions.end()) {
|
||||
it->second(this, param);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Drawing
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
154
rosen/modules/graphics_effect/src/ge_water_ripple_filter.cpp
Normal file
154
rosen/modules/graphics_effect/src/ge_water_ripple_filter.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.
|
||||
*/
|
||||
|
||||
#include "chrono"
|
||||
|
||||
#include "ge_log.h"
|
||||
#include "ge_water_ripple_filter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
// Advanced Filter
|
||||
#define PROPERTY_HIGPU_VERSION "const.gpu.vendor"
|
||||
#define PROPERTY_DEBUG_SUPPORT_AF "persist.sys.graphic.supports_af"
|
||||
namespace {
|
||||
|
||||
static std::shared_ptr<Drawing::RuntimeEffect> g_waterRippleEffect = nullptr;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
GEWaterRippleFilter::GEWaterRippleFilter(const Drawing::GEWaterRippleFilterParams& params)
|
||||
: progress_(params.progress), waveCount_(params.waveCount), rippleCenterX_(params.rippleCenterX),
|
||||
rippleCenterY_(params.rippleCenterY)
|
||||
{
|
||||
if (!InitWaterRippleEffect()) {
|
||||
LOGE("GEWaterRippleFilter::GEWaterRippleFilter failed when initializing WaterRippleEffect.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Drawing::Image> GEWaterRippleFilter::ProcessImage(Drawing::Canvas& canvas,
|
||||
const std::shared_ptr<Drawing::Image> image, const Drawing::Rect& src, const Drawing::Rect& dst)
|
||||
{
|
||||
if (image == nullptr) {
|
||||
LOGE("GEWaterRippleFilter::ProcessImage input is invalid");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Drawing::Matrix matrix;
|
||||
auto shader = Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP,
|
||||
Drawing::TileMode::CLAMP, Drawing::SamplingOptions(Drawing::FilterMode::LINEAR), matrix);
|
||||
if (shader == nullptr) {
|
||||
LOGI("GEWaterRippleFilter::ProcessImage shader create failed");
|
||||
return nullptr;
|
||||
}
|
||||
if (g_waterRippleEffect == nullptr) {
|
||||
if (InitWaterRippleEffect() == false) {
|
||||
LOGE("GEWaterRippleFilter::ProcessImage g_waterRippleEffect init failed");
|
||||
return nullptr;
|
||||
}
|
||||
LOGE("GEWaterRippleFilter::ProcessImage g_waterRippleEffect first time create");
|
||||
}
|
||||
auto imageInfo = image->GetImageInfo();
|
||||
float height = imageInfo.GetHeight();
|
||||
float width = imageInfo.GetWidth();
|
||||
LOGD("GEWaterRippleFilter::ProcessImage input image heigth = %{public}f, width = %{public}f", height, width);
|
||||
Drawing::RuntimeShaderBuilder builder(g_waterRippleEffect);
|
||||
|
||||
builder.SetChild("image", shader);
|
||||
builder.SetUniform("iResolution", width, height);
|
||||
builder.SetUniform("progress", progress_);
|
||||
builder.SetUniform("waveNum", waveCount_);
|
||||
builder.SetUniform("rippleCenter", rippleCenterX_, rippleCenterY_);
|
||||
|
||||
auto invertedImage = builder.MakeImage(canvas.GetGPUContext().get(), nullptr, imageInfo, false);
|
||||
if (invertedImage == nullptr) {
|
||||
LOGE("GEWaterRippleFilter::ProcessImage make image failed");
|
||||
return nullptr;
|
||||
}
|
||||
return invertedImage;
|
||||
}
|
||||
|
||||
bool GEWaterRippleFilter::InitWaterRippleEffect()
|
||||
{
|
||||
static std::string blurString(R"(
|
||||
uniform shader image;
|
||||
uniform half2 iResolution;
|
||||
uniform half progress;
|
||||
uniform half waveNum;
|
||||
uniform half2 rippleCenter;
|
||||
|
||||
const half basicSlope = 0.5;
|
||||
const half gAmplSupress = 0.01;
|
||||
const half waveFreq = 31.0;
|
||||
const half wavePropRatio = 2.0;
|
||||
const half ampSupArea = 0.5;
|
||||
const half intensity = 0.15;
|
||||
|
||||
half calcWave(half dis)
|
||||
{
|
||||
half preWave = (waveNum == 1.) ? 1. : smoothstep(0., -0.3, dis);
|
||||
half waveForm = (waveNum == 1.) ? smoothstep(-0.4, -0.2, dis) *
|
||||
smoothstep(0., -0.2, dis) : (waveNum == 2.) ?
|
||||
smoothstep(-0.6, -0.3, dis) * preWave : smoothstep(-0.9, -0.6, dis) *
|
||||
step(abs(dis + 0.45), 0.45) * preWave;
|
||||
return sin(waveFreq * dis) * waveForm;
|
||||
}
|
||||
|
||||
half waveGenerator(half propDis, half t)
|
||||
{
|
||||
half dis = propDis - wavePropRatio * t;
|
||||
half h = 1e-3;
|
||||
half d1 = dis - h;
|
||||
half d2 = dis + h;
|
||||
return (calcWave(d2) - calcWave(d1)) / (2. * h);
|
||||
}
|
||||
|
||||
half4 main(vec2 fragCoord)
|
||||
{
|
||||
half shortEdge = min(iResolution.x, iResolution.y);
|
||||
half2 uv = fragCoord.xy / iResolution.xy;
|
||||
half2 uvHomo = fragCoord.xy / shortEdge;
|
||||
half2 resRatio = iResolution.xy / shortEdge;
|
||||
|
||||
half progSlope = basicSlope + 0.1 * waveNum;
|
||||
half t = progSlope * progress;
|
||||
half ampDecayByT = pow((1. - t), 9.);
|
||||
|
||||
half2 waveCenter = rippleCenter * resRatio;
|
||||
half propDis = distance(uvHomo, waveCenter);
|
||||
half2 v = uvHomo - waveCenter;
|
||||
|
||||
half ampSupByDis = smoothstep(0., ampSupArea, propDis);
|
||||
half hIntense = waveGenerator(propDis, t) * ampDecayByT * ampSupByDis * gAmplSupress;
|
||||
half2 circles = normalize(v) * hIntense;
|
||||
|
||||
half3 norm = vec3(circles, hIntense);
|
||||
half2 expandUV = (uv - intensity * norm.xy) * iResolution.xy;
|
||||
half3 color = image.eval(expandUV).rgb;
|
||||
color += 5. * clamp(dot(norm, normalize(vec3(0., -4., 0.5))), 0., 1.);
|
||||
|
||||
return half4(color, 1.0);
|
||||
}
|
||||
)");
|
||||
if (g_waterRippleEffect == nullptr) {
|
||||
g_waterRippleEffect = Drawing::RuntimeEffect::CreateForShader(blurString);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
@ -158,29 +158,5 @@ HWTEST_F(GEKawaseBlurShaderFilterTest, ComputeRadiusAndScale001, TestSize.Level1
|
||||
std::string expect = "blur radius is " + std::to_string(float(36)); // 36 match result
|
||||
EXPECT_EQ(geKawaseBlurShaderFilter->GetDescription(), expect);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: InitSimpleFilter001
|
||||
* @tc.desc: Verify function InitSimpleFilter
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(GEKawaseBlurShaderFilterTest, InitSimpleFilter001, TestSize.Level1)
|
||||
{
|
||||
Drawing::GEKawaseBlurShaderFilterParams params { 1 }; // 1 blur radius
|
||||
auto geKawaseBlurShaderFilter = std::make_shared<GEKawaseBlurShaderFilter>(params);
|
||||
EXPECT_TRUE(geKawaseBlurShaderFilter->InitSimpleFilter());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: InitBlurEffectForAdvancedFilter001
|
||||
* @tc.desc: Verify function InitBlurEffectForAdvancedFilter
|
||||
* @tc.type:FUNC
|
||||
*/
|
||||
HWTEST_F(GEKawaseBlurShaderFilterTest, InitBlurEffectForAdvancedFilter001, TestSize.Level1)
|
||||
{
|
||||
Drawing::GEKawaseBlurShaderFilterParams params { 1 }; // 1 blur radius
|
||||
auto geKawaseBlurShaderFilter = std::make_shared<GEKawaseBlurShaderFilter>(params);
|
||||
EXPECT_TRUE(geKawaseBlurShaderFilter->InitBlurEffectForAdvancedFilter());
|
||||
}
|
||||
} // namespace GraphicsEffectEngine
|
||||
} // namespace OHOS
|
||||
|
@ -402,8 +402,6 @@ HWTEST_F(GELinearGradientBlurShaderFilterTest, DrawMeanLinearGradientBlur001, Te
|
||||
auto filter = std::make_shared<GELinearGradientBlurShaderFilter>(params);
|
||||
ASSERT_TRUE(filter != nullptr);
|
||||
|
||||
filter->MakeHorizontalMeanBlurEffect();
|
||||
filter->MakeVerticalMeanBlurEffect();
|
||||
EXPECT_NE(filter->ProcessImage(canvas_, image_, src_, dst_), image_);
|
||||
}
|
||||
|
||||
|
@ -296,9 +296,6 @@ void HgmFrameRateManager::UniProcessDataForLtpo(uint64_t timestamp,
|
||||
}
|
||||
FrameRateReport();
|
||||
}
|
||||
if (dvsyncInfo.isRsDvsyncOn) {
|
||||
pendingRefreshRate_ = std::make_shared<uint32_t>(currRefreshRate_);
|
||||
}
|
||||
ReportHiSysEvent(resultVoteInfo);
|
||||
lastVoteInfo_ = resultVoteInfo;
|
||||
}
|
||||
@ -675,13 +672,24 @@ void HgmFrameRateManager::HandlePackageEvent(pid_t pid, uint32_t listSize, const
|
||||
}
|
||||
HgmTaskHandleThread::Instance().PostTask([this, packageList] () {
|
||||
if (multiAppStrategy_.HandlePkgsEvent(packageList) == EXEC_SUCCESS) {
|
||||
std::lock_guard<std::mutex> locker(pkgSceneMutex_);
|
||||
sceneStack_.clear();
|
||||
ClearScene();
|
||||
}
|
||||
UpdateAppSupportStatus();
|
||||
});
|
||||
}
|
||||
|
||||
void HgmFrameRateManager::ClearScene()
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(pkgSceneMutex_);
|
||||
for (auto it = sceneStack_.begin(); it != sceneStack_.end();) {
|
||||
if (it->first.find("CAMERA") != std::string::npos) {
|
||||
it++;
|
||||
} else {
|
||||
it = sceneStack_.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HgmFrameRateManager::HandleRefreshRateEvent(pid_t pid, const EventInfo& eventInfo)
|
||||
{
|
||||
std::string eventName = eventInfo.eventName;
|
||||
@ -723,6 +731,14 @@ void HgmFrameRateManager::HandleTouchEvent(pid_t pid, int32_t touchStatus, int32
|
||||
touchManager_.HandleTouchEvent(TouchEvent::DOWN_EVENT, "");
|
||||
}
|
||||
} else if (touchStatus == TOUCH_UP || touchStatus == TOUCH_PULL_UP) {
|
||||
if (touchCnt != LAST_TOUCH_CNT) {
|
||||
return;
|
||||
}
|
||||
if (auto iter = voteRecord_.find("VOTER_GAMES"); iter != voteRecord_.end() && !iter->second.empty() &&
|
||||
gameScenes_.empty() && multiAppStrategy_.CheckPidValid(iter->second.front().pid)) {
|
||||
HGM_LOGI("[touch manager] keep down in games");
|
||||
return;
|
||||
}
|
||||
if (touchCnt == LAST_TOUCH_CNT) {
|
||||
HGM_LOGI("[touch manager] up");
|
||||
touchManager_.HandleTouchEvent(TouchEvent::UP_EVENT, "");
|
||||
|
@ -154,7 +154,7 @@ public:
|
||||
HgmMultiAppStrategy& GetMultiAppStrategy() { return multiAppStrategy_; }
|
||||
HgmTouchManager& GetTouchManager() { return touchManager_; }
|
||||
void UpdateSurfaceTime(const std::string& name, uint64_t timestamp);
|
||||
void SetSchedulerPreferredFps(int32_t schedulePreferredFps)
|
||||
void SetSchedulerPreferredFps(uint32_t schedulePreferredFps)
|
||||
{
|
||||
if (schedulePreferredFps_ != schedulePreferredFps) {
|
||||
schedulePreferredFps_ = schedulePreferredFps;
|
||||
@ -199,6 +199,7 @@ private:
|
||||
void UpdateVoteRule();
|
||||
void ReportHiSysEvent(const VoteInfo& frameRateVoteInfo);
|
||||
void SetResultVoteInfo(VoteInfo& voteInfo, uint32_t min, uint32_t max);
|
||||
void ClearScene();
|
||||
|
||||
uint32_t currRefreshRate_ = 0;
|
||||
uint32_t controllerRate_ = 0;
|
||||
@ -240,7 +241,7 @@ private:
|
||||
bool prepareCheck_ = false;
|
||||
HgmIdleDetector idleDetector_;
|
||||
bool isNeedUpdateAppOffset_ = false;
|
||||
int32_t schedulePreferredFps_ = 60;
|
||||
uint32_t schedulePreferredFps_ = 60;
|
||||
int32_t schedulePreferredFpsChange_ = false;
|
||||
};
|
||||
} // namespace Rosen
|
||||
|
@ -61,7 +61,8 @@ uint64_t HgmVSyncGeneratorController::CalcVSyncQuickTriggerTime(uint64_t lastVSy
|
||||
}
|
||||
uint32_t maxPluseNum = HgmCore::Instance().GetSupportedMaxTE() / lastRate;
|
||||
|
||||
uint32_t pulse = vsyncGenerator_->GetVSyncPulse() >= 0 ? vsyncGenerator_->GetVSyncPulse() : 0;
|
||||
uint64_t pulse = vsyncGenerator_->GetVSyncPulse() >= 0 ?
|
||||
static_cast<uint64_t>(vsyncGenerator_->GetVSyncPulse()) : 0;
|
||||
uint64_t targetTime = lastVSyncTime + pulse * TARGET_TIME_TRIGGER_PULSE_NUM;
|
||||
uint64_t currTime = static_cast<uint64_t>(
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
|
@ -19,7 +19,8 @@
|
||||
#include "transaction/rs_interfaces.h"
|
||||
#include "vsync_receiver.h"
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
using namespace OHOS::Rosen;
|
||||
|
||||
struct OH_DisplaySoloist {
|
||||
std::shared_ptr<SoloistId> soloistId_;
|
||||
};
|
||||
@ -117,4 +118,3 @@ int32_t OH_DisplaySoloist_SetExpectedFrameRateRange(OH_DisplaySoloist* displaySo
|
||||
soloistManager.InsertFrameRateRange(soloistId, frameRateRange);
|
||||
return EXEC_SUCCESS;
|
||||
}
|
||||
} // namespace OHOS::Rosen
|
||||
|
@ -134,6 +134,7 @@ ohos_shared_library("librender_service") {
|
||||
"core/drawable/rs_canvas_drawing_render_node_drawable.cpp",
|
||||
"core/drawable/rs_canvas_render_node_drawable.cpp",
|
||||
"core/drawable/rs_display_render_node_drawable.cpp",
|
||||
"core/drawable/rs_dma_buffer_surface_render_node_drawable.cpp",
|
||||
"core/drawable/rs_effect_render_node_drawable.cpp",
|
||||
"core/drawable/rs_render_node_drawable.cpp",
|
||||
"core/drawable/rs_render_node_drawable_autocache.cpp",
|
||||
@ -162,6 +163,7 @@ ohos_shared_library("librender_service") {
|
||||
"core/pipeline/parallel_render/rs_render_task.cpp",
|
||||
"core/pipeline/parallel_render/rs_sub_thread.cpp",
|
||||
"core/pipeline/parallel_render/rs_sub_thread_manager.cpp",
|
||||
"core/pipeline/parallel_render/rs_ui_first_render_listener.cpp",
|
||||
]
|
||||
}
|
||||
|
||||
@ -284,7 +286,6 @@ ohos_shared_library("librender_service") {
|
||||
public_external_deps += [ "libxml2:libxml2" ]
|
||||
|
||||
external_deps = [
|
||||
"battery_manager:batterysrv_client",
|
||||
"c_utils:utils",
|
||||
"drivers_interface_display:libdisplay_commontype_proxy_1.0",
|
||||
"eventhandler:libeventhandler",
|
||||
@ -295,7 +296,6 @@ ohos_shared_library("librender_service") {
|
||||
"hilog:libhilog",
|
||||
"hisysevent:libhisysevent",
|
||||
"hitrace:hitrace_meter",
|
||||
"hiview:libucollection_utility",
|
||||
"init:libbegetutil",
|
||||
"ipc:ipc_core",
|
||||
"libpng:libpng",
|
||||
@ -343,7 +343,7 @@ ohos_shared_library("librender_service") {
|
||||
}
|
||||
|
||||
if (use_memmgr_plugin) {
|
||||
external_deps += [ "memmgr_override:memmgrclient" ]
|
||||
external_deps += [ "memmgr:memmgrclient" ]
|
||||
} else if (use_memmgr) {
|
||||
external_deps += [ "memmgr:memmgrclient" ]
|
||||
}
|
||||
|
@ -301,9 +301,9 @@ bool RSDirtyRectsDfx::DrawDetailedTypesOfDirtyRegionForDFX(RSSurfaceRenderNode&
|
||||
return true;
|
||||
}
|
||||
|
||||
void RSDirtyRectsDfx::DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderNode& node) const
|
||||
void RSDirtyRectsDfx::DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderParams& surfaceParams) const
|
||||
{
|
||||
const auto& opaqueRegionRects = node.GetOpaqueRegion().GetRegionRects();
|
||||
const auto& opaqueRegionRects = surfaceParams.GetOpaqueRegion().GetRegionRects();
|
||||
for (const auto& subRect : opaqueRegionRects) {
|
||||
DrawDirtyRectForDFX(subRect.ToRectI(), Drawing::Color::COLOR_GREEN, RSPaintStyle::FILL, DFXFillAlpha, 0);
|
||||
}
|
||||
@ -325,12 +325,15 @@ void RSDirtyRectsDfx::DrawAllSurfaceDirtyRegionForDFX() const
|
||||
|
||||
void RSDirtyRectsDfx::DrawAllSurfaceOpaqueRegionForDFX() const
|
||||
{
|
||||
auto params = static_cast<RSDisplayRenderParams*>(targetNode_->GetRenderParams().get());
|
||||
auto& curAllSurfaces = params->GetAllMainAndLeashSurfaces();
|
||||
for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
|
||||
auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
|
||||
if (surfaceNode->IsMainWindowType()) {
|
||||
DrawSurfaceOpaqueRegionForDFX(*surfaceNode);
|
||||
if (!displayParams_) {
|
||||
RS_LOGE("RSDirtyRectsDfx: displayParams is null ptr.");
|
||||
return;
|
||||
}
|
||||
auto& curAllSurfacesDrawables = displayParams_->GetAllMainAndLeashSurfaceDrawables();
|
||||
for (auto it = curAllSurfacesDrawables.rbegin(); it != curAllSurfacesDrawables.rend(); ++it) {
|
||||
auto surfaceParams = static_cast<RSSurfaceRenderParams*>((*it)->GetRenderParams().get());
|
||||
if (surfaceParams && surfaceParams->IsMainWindowType()) {
|
||||
DrawSurfaceOpaqueRegionForDFX(*surfaceParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -367,15 +370,17 @@ void RSDirtyRectsDfx::DrawTargetSurfaceDirtyRegionForDFX() const
|
||||
|
||||
void RSDirtyRectsDfx::DrawTargetSurfaceVisibleRegionForDFX() const
|
||||
{
|
||||
auto params = static_cast<RSDisplayRenderParams*>(targetNode_->GetRenderParams().get());
|
||||
auto& curAllSurfaces = params->GetAllMainAndLeashSurfaces();
|
||||
for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
|
||||
auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
|
||||
if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
|
||||
if (!displayParams_) {
|
||||
RS_LOGE("RSDirtyRectsDfx: displayParams is null ptr.");
|
||||
return;
|
||||
}
|
||||
auto& curAllSurfacesDrawables = displayParams_->GetAllMainAndLeashSurfaceDrawables();
|
||||
for (auto it = curAllSurfacesDrawables.rbegin(); it != curAllSurfacesDrawables.rend(); ++it) {
|
||||
auto surfaceParams = static_cast<RSSurfaceRenderParams*>((*it)->GetRenderParams().get());
|
||||
if (surfaceParams == nullptr || !surfaceParams->IsAppWindow()) {
|
||||
continue;
|
||||
}
|
||||
if (CheckIfSurfaceTargetedForDFX(surfaceNode->GetName())) {
|
||||
auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNode->GetRenderParams().get());
|
||||
if (CheckIfSurfaceTargetedForDFX(surfaceParams->GetName())) {
|
||||
const auto& visibleRegions = surfaceParams->GetVisibleRegion().GetRegionRects();
|
||||
std::vector<RectI> rects;
|
||||
for (auto& rect : visibleRegions) {
|
||||
|
@ -21,7 +21,9 @@
|
||||
#include "system/rs_system_parameters.h"
|
||||
|
||||
#include "common/rs_occlusion_region.h"
|
||||
#include "params/rs_display_render_params.h"
|
||||
#include "params/rs_render_thread_params.h"
|
||||
#include "params/rs_surface_render_params.h"
|
||||
#include "pipeline/rs_display_render_node.h"
|
||||
#include "pipeline/rs_recording_canvas.h"
|
||||
#include "pipeline/rs_surface_render_node.h"
|
||||
@ -30,7 +32,8 @@ namespace OHOS::Rosen {
|
||||
|
||||
class RSDirtyRectsDfx {
|
||||
public:
|
||||
explicit RSDirtyRectsDfx(std::shared_ptr<RSDisplayRenderNode> targetNode) : targetNode_(targetNode) {}
|
||||
explicit RSDirtyRectsDfx(std::shared_ptr<RSDisplayRenderNode> targetNode, RSDisplayRenderParams* displayParams)
|
||||
: targetNode_(targetNode), displayParams_(displayParams) {}
|
||||
~RSDirtyRectsDfx() = default;
|
||||
|
||||
enum class RSPaintStyle { FILL, STROKE };
|
||||
@ -53,12 +56,13 @@ private:
|
||||
ScreenInfo screenInfo_;
|
||||
std::shared_ptr<RSDisplayRenderNode> targetNode_;
|
||||
std::shared_ptr<RSPaintFilterCanvas> canvas_;
|
||||
RSDisplayRenderParams* displayParams_ = nullptr;
|
||||
|
||||
void DrawCurrentRefreshRate();
|
||||
void DrawDirtyRectForDFX(const RectI& dirtyRect, const Drawing::Color color, const RSPaintStyle fillType,
|
||||
float alpha, int edgeWidth = 6) const;
|
||||
bool DrawDetailedTypesOfDirtyRegionForDFX(RSSurfaceRenderNode& node) const;
|
||||
void DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderNode& node) const;
|
||||
void DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderParams& surfaceParams) const;
|
||||
|
||||
void DrawDirtyRegionForDFX(const std::vector<RectI>& dirtyRects) const;
|
||||
void DrawAllSurfaceDirtyRegionForDFX() const;
|
||||
|
@ -68,7 +68,9 @@ void RSCanvasDrawingRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
}
|
||||
auto paintFilterCanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
|
||||
RSAutoCanvasRestore acr(paintFilterCanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
|
||||
params->ApplyAlphaAndMatrixToCanvas(*paintFilterCanvas);
|
||||
if (!canvas.GetRecordingState()) {
|
||||
params->ApplyAlphaAndMatrixToCanvas(*paintFilterCanvas);
|
||||
}
|
||||
|
||||
auto uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams().get();
|
||||
if ((!uniParam || uniParam->IsOpDropped()) && GetOpDropped() && QuickReject(canvas, params->GetLocalDrawRect())) {
|
||||
@ -320,23 +322,34 @@ void RSCanvasDrawingRenderNodeDrawable::ResetSurface()
|
||||
}
|
||||
|
||||
// use in IPC thread
|
||||
Drawing::Bitmap RSCanvasDrawingRenderNodeDrawable::GetBitmap(const uint64_t tid)
|
||||
Drawing::Bitmap RSCanvasDrawingRenderNodeDrawable::GetBitmap(Drawing::GPUContext* grContext)
|
||||
{
|
||||
Drawing::Bitmap bitmap;
|
||||
std::lock_guard<std::mutex> lock(drawingMutex);
|
||||
// Judge valid of backendTexture_ by checking the image_.
|
||||
if (!image_) {
|
||||
RS_LOGE("Failed to get bitmap, image is null!");
|
||||
return bitmap;
|
||||
}
|
||||
#if (defined RS_ENABLE_GL) || (defined RS_ENABLE_VK)
|
||||
if ((RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) && (GetTid() != tid)) {
|
||||
RS_LOGE("Failed to get bitmap, image is used by multi threads");
|
||||
if (!grContext) {
|
||||
RS_LOGE("Failed to get bitmap, grContext is null!");
|
||||
return bitmap;
|
||||
}
|
||||
#endif
|
||||
if (!image_->AsLegacyBitmap(bitmap)) {
|
||||
#if (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
|
||||
Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
|
||||
Drawing::BitmapFormat info = Drawing::BitmapFormat{ image_->GetColorType(), image_->GetAlphaType() };
|
||||
auto image = std::make_shared<Drawing::Image>();
|
||||
SharedTextureContext* sharedContext = new SharedTextureContext(image); // last image
|
||||
bool ret = image->BuildFromTexture(*grContext, backendTexture_.GetTextureInfo(), origin,
|
||||
info, nullptr, SKResourceManager::DeleteSharedTextureContext, sharedContext);
|
||||
if (!ret) {
|
||||
RS_LOGE("RSCanvasDrawingRenderNodeDrawable::GetBitmap image BuildFromTexture failed");
|
||||
return bitmap;
|
||||
}
|
||||
if (!image->AsLegacyBitmap(bitmap)) {
|
||||
RS_LOGE("Failed to get bitmap, asLegacyBitmap failed");
|
||||
}
|
||||
#endif
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
@ -451,9 +464,10 @@ void RSCanvasDrawingRenderNodeDrawable::DrawCaptureImage(RSPaintFilterCanvas& ca
|
||||
}
|
||||
Drawing::TextureOrigin origin = Drawing::TextureOrigin::BOTTOM_LEFT;
|
||||
Drawing::BitmapFormat info = Drawing::BitmapFormat{ image_->GetColorType(), image_->GetAlphaType() };
|
||||
SharedTextureContext* sharedContext = new SharedTextureContext(image_);
|
||||
captureImage_ = std::make_shared<Drawing::Image>();
|
||||
bool ret = captureImage_->BuildFromTexture(
|
||||
*canvas.GetGPUContext(), backendTexture_.GetTextureInfo(), origin, info, nullptr);
|
||||
bool ret = captureImage_->BuildFromTexture(*canvas.GetGPUContext(), backendTexture_.GetTextureInfo(), origin, info,
|
||||
nullptr, SKResourceManager::DeleteSharedTextureContext, sharedContext);
|
||||
if (!ret) {
|
||||
RS_LOGE("RSCanvasDrawingRenderNodeDrawable::DrawCaptureImage BuildFromTexture failed");
|
||||
return;
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
std::shared_ptr<RSPaintFilterCanvas> GetCanvas();
|
||||
void Flush(float width, float height, std::shared_ptr<RSContext> context,
|
||||
NodeId nodeId, RSPaintFilterCanvas& rscanvas);
|
||||
Drawing::Bitmap GetBitmap(const uint64_t tid = UINT32_MAX);
|
||||
Drawing::Bitmap GetBitmap(Drawing::GPUContext* grContext);
|
||||
bool GetPixelmap(const std::shared_ptr<Media::PixelMap> pixelmap, const Drawing::Rect* rect,
|
||||
const uint64_t tid = UINT32_MAX, std::shared_ptr<Drawing::DrawCmdList> drawCmdList = nullptr);
|
||||
void DrawCaptureImage(RSPaintFilterCanvas& canvas);
|
||||
|
@ -60,7 +60,6 @@ public:
|
||||
explicit RSOverDrawDfx(std::shared_ptr<RSPaintFilterCanvas> curCanvas)
|
||||
{
|
||||
enable_ = RSOverdrawController::GetInstance().IsEnabled() && curCanvas != nullptr;
|
||||
aceDebugBoundaryEnabled_ = RSSystemProperties::GetAceDebugBoundaryEnabled();
|
||||
curCanvas_ = curCanvas;
|
||||
StartOverDraw();
|
||||
}
|
||||
@ -84,11 +83,7 @@ private:
|
||||
auto height = curCanvas_->GetHeight();
|
||||
Drawing::ImageInfo info =
|
||||
Drawing::ImageInfo { width, height, Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL };
|
||||
if (!aceDebugBoundaryEnabled_) {
|
||||
overdrawSurface_ = Drawing::Surface::MakeRenderTarget(gpuContext.get(), false, info);
|
||||
} else {
|
||||
overdrawSurface_ = Drawing::Surface::MakeRaster(info);
|
||||
}
|
||||
overdrawSurface_ = Drawing::Surface::MakeRaster(info);
|
||||
if (!overdrawSurface_) {
|
||||
RS_LOGE("RSOverDrawDfx::StartOverDraw failed: surface is nullptr");
|
||||
return;
|
||||
@ -122,7 +117,6 @@ private:
|
||||
}
|
||||
|
||||
bool enable_;
|
||||
bool aceDebugBoundaryEnabled_ = false;
|
||||
mutable std::shared_ptr<RSPaintFilterCanvas> curCanvas_;
|
||||
std::shared_ptr<Drawing::Surface> overdrawSurface_ = nullptr;
|
||||
std::shared_ptr<Drawing::OverDrawCanvas> overdrawCanvas_ = nullptr;
|
||||
@ -172,6 +166,18 @@ static inline std::vector<RectI> MergeDirtyHistory(std::shared_ptr<RSDisplayRend
|
||||
RSUniRenderUtil::MergeDirtyHistory(displayNodeSp, bufferAge, false, true);
|
||||
Occlusion::Region dirtyRegion = RSUniRenderUtil::MergeVisibleDirtyRegion(
|
||||
curAllSurfaceDrawables, RSUniRenderThread::Instance().GetDrawStatusVec(), false);
|
||||
const auto clipRectThreshold = RSSystemProperties::GetClipRectThreshold();
|
||||
if (clipRectThreshold < 1.f) {
|
||||
Occlusion::Region allDirtyRegion{ Occlusion::Rect{ dirtyManager->GetDirtyRegion() } };
|
||||
allDirtyRegion.OrSelf(dirtyRegion);
|
||||
auto bound = allDirtyRegion.GetBound();
|
||||
if (allDirtyRegion.GetSize() > 1 && !bound.IsEmpty() &&
|
||||
allDirtyRegion.Area() > bound.Area() * clipRectThreshold) {
|
||||
dirtyManager->MergeDirtyRectAfterMergeHistory(bound.ToRectI());
|
||||
RS_OPTIONAL_TRACE_NAME_FMT("dirty expand: %s to %s",
|
||||
allDirtyRegion.GetRegionInfo().c_str(), bound.GetRectInfo().c_str());
|
||||
}
|
||||
}
|
||||
RSUniRenderUtil::SetAllSurfaceDrawableGlobalDityRegion(curAllSurfaceDrawables, dirtyManager->GetDirtyRegion());
|
||||
|
||||
// DFX START
|
||||
@ -325,7 +331,9 @@ bool RSDisplayRenderNodeDrawable::CheckDisplayNodeSkip(std::shared_ptr<RSDisplay
|
||||
#ifdef OHOS_PLATFORM
|
||||
RSUniRenderThread::Instance().SetSkipJankAnimatorFrame(true);
|
||||
#endif
|
||||
if (!RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetForceCommitLayer()) {
|
||||
auto pendingDrawables = RSUifirstManager::Instance().GetPendingPostDrawables();
|
||||
if (!RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetForceCommitLayer() &&
|
||||
pendingDrawables.size() == 0) {
|
||||
RS_TRACE_NAME("DisplayNodeSkip skip commit");
|
||||
return true;
|
||||
}
|
||||
@ -350,6 +358,9 @@ bool RSDisplayRenderNodeDrawable::CheckDisplayNodeSkip(std::shared_ptr<RSDisplay
|
||||
RS_LOGW("RSDisplayRenderNodeDrawable::CheckDisplayNodeSkip: hardwareThread task has too many to Execute");
|
||||
}
|
||||
processor->ProcessDisplaySurface(*displayNode);
|
||||
|
||||
CreateUIFirstLayer(processor);
|
||||
|
||||
// commit RCD layers
|
||||
auto rcdInfo = std::make_unique<RcdInfo>();
|
||||
auto screenInfo = params->GetScreenInfo();
|
||||
@ -358,6 +369,17 @@ bool RSDisplayRenderNodeDrawable::CheckDisplayNodeSkip(std::shared_ptr<RSDisplay
|
||||
return true;
|
||||
}
|
||||
|
||||
void RSDisplayRenderNodeDrawable::CreateUIFirstLayer(std::shared_ptr<RSProcessor>& processor)
|
||||
{
|
||||
auto pendingDrawables = RSUifirstManager::Instance().GetPendingPostDrawables();
|
||||
for (auto& drawable : pendingDrawables) {
|
||||
auto params = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
|
||||
if (params && params->GetHardwareEnabled()) {
|
||||
processor->CreateUIFirstLayer(*drawable, *params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RSDisplayRenderNodeDrawable::RemoveClearMemoryTask() const
|
||||
{
|
||||
auto& unirenderThread = RSUniRenderThread::Instance();
|
||||
@ -496,8 +518,16 @@ void RSDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
WiredScreenProjection(displayNodeSp, *params, processor);
|
||||
return;
|
||||
}
|
||||
virtualScreenBlackList_ = screenManager->GetVirtualScreenBlackList(paramScreenId);
|
||||
uniParam->SetBlackList(virtualScreenBlackList_);
|
||||
castScreenEnableSkipWindow_ = screenManager->GetCastScreenEnableSkipWindow(paramScreenId);
|
||||
if (castScreenEnableSkipWindow_) {
|
||||
RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw, Enable CastScreen SkipWindow.");
|
||||
screenManager->GetCastScreenBlackList(castScreenBlackList_);
|
||||
uniParam->SetBlackList(castScreenBlackList_);
|
||||
} else {
|
||||
RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw, Enable RecordScreen SkipWindow.");
|
||||
virtualScreenBlackList_ = screenManager->GetVirtualScreenBlackList(paramScreenId);
|
||||
uniParam->SetBlackList(virtualScreenBlackList_);
|
||||
}
|
||||
RS_LOGD("RSDisplayRenderNodeDrawable::OnDraw Mirror screen.");
|
||||
DrawMirrorScreen(displayNodeSp, *params, processor);
|
||||
} else {
|
||||
@ -508,7 +538,7 @@ void RSDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
RS_LOGE("RSDisplayRenderNodeDrawable::OnDraw expandProcessor is null!");
|
||||
return;
|
||||
}
|
||||
RSDirtyRectsDfx rsDirtyRectsDfx(displayNodeSp);
|
||||
RSDirtyRectsDfx rsDirtyRectsDfx(displayNodeSp, params);
|
||||
std::vector<RectI> damageRegionRects;
|
||||
// disable expand screen dirty when skipFrameInterval > 1, because the dirty history is incorrect
|
||||
if (uniParam->IsVirtualDirtyEnabled() && curScreenInfo.skipFrameInterval <= 1) {
|
||||
@ -530,13 +560,11 @@ void RSDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
|
||||
if (uniParam->IsOpDropped() && CheckDisplayNodeSkip(displayNodeSp, params, processor)) {
|
||||
RSMainThread::Instance()->SetFrameIsRender(false);
|
||||
RSUniRenderThread::Instance().DvsyncRequestNextVsync();
|
||||
SetDisplayNodeSkipFlag(*uniParam, true);
|
||||
return;
|
||||
}
|
||||
SetDisplayNodeSkipFlag(*uniParam, false);
|
||||
RSMainThread::Instance()->SetFrameIsRender(true);
|
||||
RSUniRenderThread::Instance().DvsyncRequestNextVsync();
|
||||
|
||||
bool isHdrOn = params->GetHDRPresent();
|
||||
RS_LOGD("SetHDRPresent: %{public}d OnDraw", isHdrOn);
|
||||
@ -551,7 +579,7 @@ void RSDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
return;
|
||||
}
|
||||
|
||||
RSDirtyRectsDfx rsDirtyRectsDfx(displayNodeSp);
|
||||
RSDirtyRectsDfx rsDirtyRectsDfx(displayNodeSp, params);
|
||||
std::vector<RectI> damageRegionrects;
|
||||
Drawing::Region clipRegion;
|
||||
if (uniParam->IsPartialRenderEnabled()) {
|
||||
@ -648,7 +676,6 @@ void RSDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
|
||||
RS_TRACE_BEGIN("RSDisplayRenderNodeDrawable CommitLayer");
|
||||
auto& hardwareNodes = RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeNodes();
|
||||
float globalZOrder = 0.f;
|
||||
for (const auto& surfaceNode : hardwareNodes) {
|
||||
if (surfaceNode == nullptr) {
|
||||
continue;
|
||||
@ -656,12 +683,11 @@ void RSDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
auto params = static_cast<RSSurfaceRenderParams*>(surfaceNode->GetRenderParams().get());
|
||||
if (params->GetHardwareEnabled()) {
|
||||
processor->CreateLayer(*surfaceNode, *params);
|
||||
globalZOrder++;
|
||||
}
|
||||
}
|
||||
displayNodeSp->SetGlobalZOrder(globalZOrder);
|
||||
displayNodeSp->SetDirtyRects(damageRegionrects);
|
||||
processor->ProcessDisplaySurface(*displayNodeSp);
|
||||
CreateUIFirstLayer(processor);
|
||||
processor->PostProcess();
|
||||
RS_TRACE_END();
|
||||
}
|
||||
@ -703,7 +729,7 @@ void RSDisplayRenderNodeDrawable::DrawMirrorScreen(std::shared_ptr<RSDisplayRend
|
||||
uniParam->SetOpDropped(false);
|
||||
mirroredNode->SetOriginScreenRotation(displayNodeSp->GetOriginScreenRotation());
|
||||
mirroredProcessor->CalculateTransform(*mirroredNode);
|
||||
RSDirtyRectsDfx rsDirtyRectsDfx(displayNodeSp);
|
||||
RSDirtyRectsDfx rsDirtyRectsDfx(displayNodeSp, ¶ms);
|
||||
if (uniParam->IsVirtualDirtyEnabled()) {
|
||||
auto dirtyRects = CalculateVirtualDirty(
|
||||
*displayNodeSp, processor, params, mirroredProcessor->GetCanvasMatrix());
|
||||
@ -724,7 +750,7 @@ bool RSDisplayRenderNodeDrawable::CheckIfHasSpecialLayer(RSDisplayRenderParams&
|
||||
if (params.HasSecurityLayer() || params.HasSkipLayer() || params.HasProtectedLayer() ||
|
||||
params.HasCaptureWindow() || RSUniRenderThread::Instance().IsCurtainScreenOn() ||
|
||||
params.GetHDRPresent() || !params.GetScreenInfo().filteredAppSet.empty() ||
|
||||
!virtualScreenBlackList_.empty()) {
|
||||
!virtualScreenBlackList_.empty() || !castScreenBlackList_.empty()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -825,7 +851,7 @@ void RSDisplayRenderNodeDrawable::DrawMirror(std::shared_ptr<RSDisplayRenderNode
|
||||
clipRegion.Clone(uniParam.GetClipRegion());
|
||||
ResetRotateIfNeed(*mirroredNode, *mirroredProcessor, clipRegion);
|
||||
|
||||
RSDirtyRectsDfx rsDirtyRectsDfx(displayNodeSp);
|
||||
RSDirtyRectsDfx rsDirtyRectsDfx(displayNodeSp, ¶ms);
|
||||
if (uniParam.IsVirtualDirtyEnabled()) {
|
||||
Drawing::Matrix matrix = canvasBackup_->GetTotalMatrix();
|
||||
matrix.PreConcat(curCanvas_->GetTotalMatrix());
|
||||
@ -1179,10 +1205,10 @@ void RSDisplayRenderNodeDrawable::OnCapture(Drawing::Canvas& canvas)
|
||||
!RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetBlackList().empty();
|
||||
}
|
||||
if (hasSpecialLayer_) {
|
||||
RS_LOGD("RSDisplayRenderNodeDrawable::OnCapture: params %{public}s \
|
||||
RS_LOGD("RSDisplayRenderNodeDrawable::OnCapture: \
|
||||
process RSDisplayRenderNode(id:[%{public}" PRIu64 "]) Not using UniRender buffer.",
|
||||
params->ToString().c_str(), params->GetId());
|
||||
RS_TRACE_NAME("RSDisplayRenderNodeDrawable::OnCapture: processRSDisplayRenderNodeDrawable[" +
|
||||
params->GetId());
|
||||
RS_TRACE_NAME("Process RSDisplayRenderNodeDrawable[" +
|
||||
std::to_string(params->GetScreenId()) + "] Not using UniRender buffer.");
|
||||
|
||||
// Adding matrix affine transformation logic
|
||||
@ -1226,13 +1252,17 @@ void RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes(Drawing::Canvas& canv
|
||||
return;
|
||||
}
|
||||
|
||||
RS_LOGD("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes: params %{public}s \
|
||||
process RSDisplayRenderNode(id:[%{public}" PRIu64 "]) using UniRender buffer.",
|
||||
params->ToString().c_str(), params->GetId());
|
||||
RS_TRACE_NAME("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes: processRSDisplayRenderNodeDrawable[" +
|
||||
std::to_string(params->GetScreenId()) + "] using UniRender buffer.");
|
||||
int hwcNodesNum = params->GetHardwareEnabledNodes().size();
|
||||
int hwcTopNodesNum = params->GetHardwareEnabledTopNodes().size();
|
||||
|
||||
if (params->GetHardwareEnabledNodes().size() != 0) {
|
||||
RS_LOGD("RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes: \
|
||||
process RSDisplayRenderNode(id:[%{public}" PRIu64 "]) \
|
||||
using UniRender buffer with hwcNodes(%{public}d, %{public}d)",
|
||||
params->GetId(), hwcNodesNum, hwcTopNodesNum);
|
||||
RS_TRACE_NAME_FMT("Process RSDisplayRenderNodeDrawable[%" PRIu64 "] using UniRender buffer with hwcNodes(%d, %d)",
|
||||
params->GetScreenId(), hwcNodesNum, hwcTopNodesNum);
|
||||
|
||||
if (hwcNodesNum > 0) {
|
||||
AdjustZOrderAndDrawSurfaceNode(params->GetHardwareEnabledNodes(), canvas, *params);
|
||||
}
|
||||
|
||||
@ -1253,7 +1283,7 @@ void RSDisplayRenderNodeDrawable::DrawHardwareEnabledNodes(Drawing::Canvas& canv
|
||||
RSBaseRenderUtil::WriteSurfaceBufferToPng(drawParams.buffer);
|
||||
renderEngine->DrawDisplayNodeWithParams(*rscanvas, *displayNodeSp, drawParams);
|
||||
|
||||
if (params->GetHardwareEnabledTopNodes().size() != 0) {
|
||||
if (hwcTopNodesNum > 0) {
|
||||
AdjustZOrderAndDrawSurfaceNode(params->GetHardwareEnabledTopNodes(), canvas, *params);
|
||||
}
|
||||
}
|
||||
@ -1405,9 +1435,12 @@ void RSDisplayRenderNodeDrawable::DrawWatermarkIfNeed(RSDisplayRenderParams& par
|
||||
auto screenInfo = screenManager->QueryScreenInfo(params.GetScreenId());
|
||||
auto mainWidth = static_cast<float>(screenInfo.width);
|
||||
auto mainHeight = static_cast<float>(screenInfo.height);
|
||||
if (RSSystemProperties::IsFoldScreenFlag() && params.GetScreenId() == 0) {
|
||||
auto rotation = params.GetScreenRotation();
|
||||
if (rotation == ScreenRotation::ROTATION_0 || rotation == ScreenRotation::ROTATION_180) {
|
||||
|
||||
// in certain cases (such as fold screen), the width and height must be swapped to fix the screen correction.
|
||||
auto screenCorrection = screenManager->GetScreenCorrection(params.GetScreenId());
|
||||
if (screenCorrection == ScreenRotation::ROTATION_90 || screenCorrection == ScreenRotation::ROTATION_270) {
|
||||
auto screenRotation = params.GetScreenRotation();
|
||||
if (screenRotation == ScreenRotation::ROTATION_0 || screenRotation == ScreenRotation::ROTATION_180) {
|
||||
std::swap(mainWidth, mainHeight);
|
||||
}
|
||||
}
|
||||
@ -1470,7 +1503,8 @@ void RSDisplayRenderNodeDrawable::PrepareOffscreenRender(const RSRenderNode& nod
|
||||
// use fixed surface size in order to reduce create texture
|
||||
if (RSSystemProperties::IsFoldScreenFlag() && params && params->IsRotationChanged()) {
|
||||
useFixedOffscreenSurfaceSize_ = true;
|
||||
auto maxRenderSize = std::max(params->GetScreenInfo().width, params->GetScreenInfo().height);
|
||||
int32_t maxRenderSize =
|
||||
static_cast<int32_t>(std::max(params->GetScreenInfo().width, params->GetScreenInfo().height));
|
||||
offscreenWidth = maxRenderSize;
|
||||
offscreenHeight = maxRenderSize;
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ private:
|
||||
bool SkipDisplayIfScreenOff() const;
|
||||
bool CheckIfHasSpecialLayer(RSDisplayRenderParams& params);
|
||||
void SetDisplayNodeSkipFlag(RSRenderThreadParams& uniParam, bool flag);
|
||||
void CreateUIFirstLayer(std::shared_ptr<RSProcessor>& processor);
|
||||
|
||||
using Registrar = RenderNodeDrawableRegistrar<RSRenderNodeType::DISPLAY_NODE, OnGenerate>;
|
||||
static Registrar instance_;
|
||||
@ -95,6 +96,8 @@ private:
|
||||
std::shared_ptr<RSPaintFilterCanvas> canvasBackup_; // backup current canvas before offscreen rende
|
||||
bool canvasRotation_ = false;
|
||||
std::unordered_set<NodeId> virtualScreenBlackList_ = {};
|
||||
std::unordered_set<NodeId> castScreenBlackList_ = {};
|
||||
bool castScreenEnableSkipWindow_ = false;
|
||||
bool hasSpecialLayer_ = false;
|
||||
bool exFoldScreen_ = false; // Expanded state of folding screen
|
||||
bool isLastFrameHasSecSurface_ = false;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "pipeline/rs_main_thread.h"
|
||||
#include "pipeline/rs_paint_filter_canvas.h"
|
||||
#include "pipeline/rs_surface_render_node.h"
|
||||
#include "pipeline/rs_uifirst_manager.h"
|
||||
#include "pipeline/rs_uni_render_thread.h"
|
||||
#include "pipeline/rs_uni_render_util.h"
|
||||
#include "platform/common/rs_log.h"
|
||||
@ -36,12 +37,13 @@
|
||||
namespace OHOS::Rosen::DrawableV2 {
|
||||
bool RSSurfaceRenderNodeDrawable::UseDmaBuffer()
|
||||
{
|
||||
bool enabled = RSSystemParameters::GetUIFirstDmaBufferEnabled();
|
||||
bool useDmaBuffer = (RSUifirstManager::Instance().GetUseDmaBuffer() &&
|
||||
RSUifirstManager::Instance().IsScreenshotAnimation()) || GetBuffer();
|
||||
auto surfaceParams = static_cast<RSSurfaceRenderParams*>(GetRenderParams().get());
|
||||
if (!surfaceParams) {
|
||||
return enabled;
|
||||
return useDmaBuffer;
|
||||
}
|
||||
return enabled && surfaceParams->GetUifirstNodeEnableParam() == MultiThreadCacheType::LEASH_WINDOW;
|
||||
return useDmaBuffer && surfaceParams->GetUifirstNodeEnableParam() == MultiThreadCacheType::LEASH_WINDOW;
|
||||
}
|
||||
|
||||
#ifndef ROSEN_CROSS_PLATFORM
|
||||
|
@ -118,8 +118,23 @@ void RSRenderNodeDrawable::GenerateCacheIfNeed(Drawing::Canvas& canvas, RSRender
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::scoped_lock<std::recursive_mutex> lock(cacheMutex_);
|
||||
if (cachedSurface_ == nullptr) {
|
||||
// Remove node id in update time map to avoid update time exceeds DRAWING_CACHE_MAX_UPDATE_TIME
|
||||
// (If cache disabled for node not on the tree, we clear cache in OnSync func, but we can't clear node
|
||||
// id in drawingCacheUpdateTimeMap_ [drawable will not be visited in RT].
|
||||
// If this node is marked node group by arkui again, we should first clear update time here, otherwise
|
||||
// update time will accumulate.)
|
||||
std::lock_guard<std::mutex> lock(drawingCacheMapMutex_);
|
||||
drawingCacheUpdateTimeMap_.erase(nodeId_);
|
||||
}
|
||||
}
|
||||
// generate(first time)/update cache(cache changed) [TARGET -> DISABLED if >= MAX UPDATE TIME]
|
||||
bool needUpdateCache = CheckIfNeedUpdateCache(params);
|
||||
// reset drawing cache changed false for render param if drawable is visited this frame
|
||||
// if this drawble is skipped due to occlusion skip of app surface node, this flag should be kept for next frame
|
||||
params.SetDrawingCacheChanged(false, true);
|
||||
bool hasFilter = params.ChildHasVisibleFilter() || params.ChildHasVisibleEffect();
|
||||
if ((params.GetDrawingCacheType() == RSDrawingCacheType::DISABLED_CACHE || (!needUpdateCache && !hasFilter))
|
||||
&& !params.OpincGetCachedMark() && !params.GetRSFreezeFlag()) {
|
||||
@ -506,7 +521,8 @@ bool RSRenderNodeDrawable::CheckIfNeedUpdateCache(RSRenderParams& params)
|
||||
}
|
||||
|
||||
if (params.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE &&
|
||||
updateTimes >= DRAWING_CACHE_MAX_UPDATE_TIME) {
|
||||
(updateTimes >= DRAWING_CACHE_MAX_UPDATE_TIME ||
|
||||
(params.NeedFilter() && params.GetDrawingCacheIncludeProperty()))) {
|
||||
params.SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
|
||||
ClearCachedSurface();
|
||||
return false;
|
||||
@ -518,7 +534,6 @@ bool RSRenderNodeDrawable::CheckIfNeedUpdateCache(RSRenderParams& params)
|
||||
}
|
||||
|
||||
if (updateTimes == 0 || params.GetDrawingCacheChanged()) {
|
||||
params.SetDrawingCacheChanged(false, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -45,6 +45,11 @@
|
||||
#include "platform/ohos/backend/rs_vulkan_context.h"
|
||||
#endif
|
||||
|
||||
#include "luminance/rs_luminance_control.h"
|
||||
#ifdef USE_VIDEO_PROCESSING_ENGINE
|
||||
#include "metadata_helper.h"
|
||||
#endif
|
||||
|
||||
namespace OHOS::Rosen::DrawableV2 {
|
||||
RSSurfaceRenderNodeDrawable::Registrar RSSurfaceRenderNodeDrawable::instance_;
|
||||
|
||||
@ -139,6 +144,67 @@ void RSSurfaceRenderNodeDrawable::CacheImgForCapture(RSPaintFilterCanvas& canvas
|
||||
}
|
||||
}
|
||||
|
||||
bool RSSurfaceRenderNodeDrawable::PrepareOffscreenRender()
|
||||
{
|
||||
// cleanup
|
||||
canvasBackup_ = nullptr;
|
||||
|
||||
// check offscreen size
|
||||
int offscreenWidth = curCanvas_->GetSurface()->Width();
|
||||
int offscreenHeight = curCanvas_->GetSurface()->Height();
|
||||
if (offscreenWidth <= 0 || offscreenHeight <= 0) {
|
||||
RS_LOGE("RSSurfaceRenderNodeDrawable::PrepareOffscreenRender, offscreenWidth or offscreenHeight is invalid");
|
||||
return false;
|
||||
}
|
||||
if (curCanvas_->GetSurface() == nullptr) {
|
||||
RS_LOGE("RSSurfaceRenderNodeDrawable::PrepareOffscreenRender, current surface is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
int maxRenderSize = std::max(offscreenWidth, offscreenHeight);
|
||||
// create offscreen surface and canvas
|
||||
if (offscreenSurface_ == nullptr || maxRenderSize_ != maxRenderSize) {
|
||||
RS_LOGD("PrepareOffscreenRender create offscreen surface offscreenSurface_,\
|
||||
new [%{public}d, %{public}d %{public}d]", offscreenWidth, offscreenHeight, maxRenderSize);
|
||||
RS_TRACE_NAME_FMT("PrepareOffscreenRender surface size: [%d, %d]", maxRenderSize, maxRenderSize);
|
||||
maxRenderSize_ = maxRenderSize;
|
||||
offscreenSurface_ = curCanvas_->GetSurface()->MakeSurface(maxRenderSize_, maxRenderSize_);
|
||||
}
|
||||
if (offscreenSurface_ == nullptr) {
|
||||
RS_LOGE("RSSurfaceRenderNodeDrawable::PrepareOffscreenRender, offscreenSurface is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
offscreenCanvas_ = std::make_shared<RSPaintFilterCanvas>(offscreenSurface_.get());
|
||||
|
||||
// copy current canvas properties into offscreen canvas
|
||||
offscreenCanvas_->CopyConfiguration(*curCanvas_);
|
||||
|
||||
// backup current canvas and replace with offscreen canvas
|
||||
canvasBackup_ = curCanvas_;
|
||||
curCanvas_ = offscreenCanvas_.get();
|
||||
curCanvas_->Save();
|
||||
curCanvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RSSurfaceRenderNodeDrawable::FinishOffscreenRender(const Drawing::SamplingOptions& sampling)
|
||||
{
|
||||
if (canvasBackup_ == nullptr) {
|
||||
RS_LOGE("RSSurfaceRenderNodeDrawable::FinishOffscreenRender, canvasBackup_ is nullptr");
|
||||
return;
|
||||
}
|
||||
// draw offscreen surface to current canvas
|
||||
Drawing::Brush paint;
|
||||
paint.SetAntiAlias(true);
|
||||
canvasBackup_->AttachBrush(paint);
|
||||
auto image = offscreenSurface_->GetImageSnapshot();
|
||||
canvasBackup_->DrawImage(*image, 0, 0, sampling);
|
||||
canvasBackup_->DetachBrush();
|
||||
curCanvas_->Restore();
|
||||
curCanvas_ = canvasBackup_;
|
||||
}
|
||||
|
||||
void RSSurfaceRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
{
|
||||
if (!ShouldPaint()) {
|
||||
@ -188,7 +254,12 @@ void RSSurfaceRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
}
|
||||
Drawing::Region curSurfaceDrawRegion = CalculateVisibleRegion(uniParam, surfaceParams, surfaceNode, isUiFirstNode);
|
||||
// when surfacenode named "CapsuleWindow", cache the current canvas as SkImage for screen recording
|
||||
auto curDisplayNode = surfaceParams->GetAncestorDisplayNode().lock()->ReinterpretCastTo<RSDisplayRenderNode>();
|
||||
auto ancestorNodeTmp = surfaceParams->GetAncestorDisplayNode().lock();
|
||||
if (ancestorNodeTmp == nullptr) {
|
||||
RS_LOGE("surfaceNode GetAncestorDisplayNode().lock() return nullptr");
|
||||
return;
|
||||
}
|
||||
auto curDisplayNode = ancestorNodeTmp->ReinterpretCastTo<RSDisplayRenderNode>();
|
||||
if (!curDisplayNode) {
|
||||
RS_LOGE("surfaceNode GetAncestorDisplayNode() return nullptr");
|
||||
return;
|
||||
@ -209,7 +280,8 @@ void RSSurfaceRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
return;
|
||||
}
|
||||
const auto &absDrawRect = surfaceParams->GetAbsDrawRect();
|
||||
RS_OPTIONAL_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw:[%s] (%d %d %d %d)Alpha: %f", name_.c_str(),
|
||||
// warning : don't delete this trace or change trace level to optional !!!
|
||||
RS_TRACE_NAME_FMT("RSSurfaceRenderNodeDrawable::OnDraw:[%s] (%d %d %d %d)Alpha: %f", name_.c_str(),
|
||||
absDrawRect.left_, absDrawRect.top_, absDrawRect.width_, absDrawRect.height_, surfaceNode->GetGlobalAlpha());
|
||||
|
||||
RS_LOGD("RSSurfaceRenderNodeDrawable::OnDraw node:%{public}" PRIu64 ",child size:%{public}u,"
|
||||
@ -227,57 +299,92 @@ void RSSurfaceRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas)
|
||||
|
||||
surfaceNode->UpdateFilterCacheStatusWithVisible(true);
|
||||
|
||||
RSAutoCanvasRestore acr(rscanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
|
||||
|
||||
// Draw base pipeline start
|
||||
surfaceParams->ApplyAlphaAndMatrixToCanvas(*rscanvas);
|
||||
RSAutoCanvasRestore acr(rscanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
|
||||
bool needOffscreen = surfaceParams->GetNeedOffscreen() && !rscanvas->GetTotalMatrix().IsIdentity() &&
|
||||
surfaceParams->IsAppWindow() && surfaceNode->GetName().substr(0, 3) != "SCB";
|
||||
curCanvas_ = rscanvas;
|
||||
if (needOffscreen) {
|
||||
releaseCount_ = 0;
|
||||
if (!PrepareOffscreenRender()) {
|
||||
needOffscreen = false;
|
||||
}
|
||||
} else {
|
||||
releaseCount_++;
|
||||
if (releaseCount_ == MAX_RELEASE_FRAME) {
|
||||
offscreenSurface_ = nullptr;
|
||||
releaseCount_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
surfaceParams->ApplyAlphaAndMatrixToCanvas(*curCanvas_, !needOffscreen);
|
||||
|
||||
bool isSelfDrawingSurface = surfaceParams->GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE;
|
||||
if (isSelfDrawingSurface && !surfaceParams->IsSpherizeValid()) {
|
||||
if (isSelfDrawingSurface && !surfaceParams->IsSpherizeValid() && !surfaceParams->IsAttractionValid()) {
|
||||
SetSkip(surfaceParams->GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE);
|
||||
rscanvas->Save();
|
||||
curCanvas_->Save();
|
||||
}
|
||||
|
||||
if (surfaceParams->IsMainWindowType()) {
|
||||
RSRenderNodeDrawable::ClearTotalProcessedNodeCount();
|
||||
rscanvas->PushDirtyRegion(curSurfaceDrawRegion);
|
||||
if (!surfaceParams->GetNeedOffscreen()) {
|
||||
curCanvas_->PushDirtyRegion(curSurfaceDrawRegion);
|
||||
}
|
||||
}
|
||||
|
||||
auto parentSurfaceMatrix = RSRenderParams::GetParentSurfaceMatrix();
|
||||
RSRenderParams::SetParentSurfaceMatrix(rscanvas->GetTotalMatrix());
|
||||
if (!needOffscreen) {
|
||||
RSRenderParams::SetParentSurfaceMatrix(curCanvas_->GetTotalMatrix());
|
||||
}
|
||||
|
||||
// add a blending disable rect op behind floating window, to enable overdraw buffer feature on special gpu.
|
||||
if (surfaceParams->IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()
|
||||
&& surfaceParams->IsGpuOverDrawBufferOptimizeNode()) {
|
||||
EnableGpuOverDrawDrawBufferOptimization(canvas, surfaceParams);
|
||||
EnableGpuOverDrawDrawBufferOptimization(*curCanvas_, surfaceParams);
|
||||
}
|
||||
|
||||
auto bounds = surfaceParams->GetFrameRect();
|
||||
|
||||
// 1. draw background
|
||||
DrawBackground(canvas, bounds);
|
||||
DrawBackground(*curCanvas_, bounds);
|
||||
|
||||
// 2. draw self drawing node
|
||||
if (surfaceParams->GetBuffer() != nullptr) {
|
||||
DealWithSelfDrawingNodeBuffer(*surfaceNode, *rscanvas, *surfaceParams);
|
||||
DealWithSelfDrawingNodeBuffer(*surfaceNode, *curCanvas_, *surfaceParams);
|
||||
}
|
||||
|
||||
if (isSelfDrawingSurface) {
|
||||
rscanvas->Restore();
|
||||
curCanvas_->Restore();
|
||||
}
|
||||
|
||||
// 3. Draw content of this node by the main canvas.
|
||||
DrawContent(canvas, bounds);
|
||||
DrawContent(*curCanvas_, bounds);
|
||||
|
||||
// 4. Draw children of this node by the main canvas.
|
||||
DrawChildren(canvas, bounds);
|
||||
DrawChildren(*curCanvas_, bounds);
|
||||
|
||||
// 5. Draw foreground of this node by the main canvas.
|
||||
DrawForeground(canvas, bounds);
|
||||
DrawForeground(*curCanvas_, bounds);
|
||||
|
||||
if (needOffscreen) {
|
||||
Drawing::AutoCanvasRestore acr(*canvasBackup_, true);
|
||||
if (surfaceParams->HasSandBox()) {
|
||||
canvasBackup_->SetMatrix(surfaceParams->GetParentSurfaceMatrix());
|
||||
canvasBackup_->ConcatMatrix(surfaceParams->GetMatrix());
|
||||
} else {
|
||||
canvasBackup_->ConcatMatrix(surfaceParams->GetMatrix());
|
||||
}
|
||||
FinishOffscreenRender(
|
||||
Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NEAREST));
|
||||
RS_LOGD("FinishOffscreenRender %{public}s node type %{public}d", surfaceParams->GetName().c_str(),
|
||||
int(surfaceParams->GetSurfaceNodeType()));
|
||||
}
|
||||
|
||||
// Draw base pipeline end
|
||||
if (surfaceParams->IsMainWindowType()) {
|
||||
rscanvas->PopDirtyRegion();
|
||||
if (!surfaceParams->GetNeedOffscreen()) {
|
||||
curCanvas_->PopDirtyRegion();
|
||||
}
|
||||
RS_TRACE_NAME_FMT("RSUniRenderThread::Render() the number of total ProcessedNodes: %d",
|
||||
RSRenderNodeDrawable::GetTotalProcessedNodeCount());
|
||||
const RSNodeStatsType nodeStats = CreateRSNodeStatsItem(
|
||||
@ -386,7 +493,7 @@ void RSSurfaceRenderNodeDrawable::OnCapture(Drawing::Canvas& canvas)
|
||||
surfaceParams->GetAbsDrawRect().ToString() + "Alpha: " +
|
||||
std::to_string(surfaceNode->GetGlobalAlpha()));
|
||||
RSAutoCanvasRestore acr(rscanvas, RSPaintFilterCanvas::SaveType::kCanvasAndAlpha);
|
||||
|
||||
|
||||
// First node don't need to concat matrix for application
|
||||
if (RSUniRenderThread::GetCaptureParam().isFirstNode_) {
|
||||
// Planning: If node is a sandbox.
|
||||
@ -426,6 +533,7 @@ void RSSurfaceRenderNodeDrawable::CaptureSurface(RSSurfaceRenderNode& surfaceNod
|
||||
RS_LOGD("RSSurfaceRenderNodeDrawable::CaptureSurface: \
|
||||
process RSSurfaceRenderNode(id:[%{public}" PRIu64 "] name:[%{public}s]) with security or skip layer.",
|
||||
surfaceParams.GetId(), name_.c_str());
|
||||
RS_TRACE_NAME("CaptureSurface with security or skip layer");
|
||||
if (RSUniRenderThread::GetCaptureParam().isSingleSurface_) {
|
||||
Drawing::Brush rectBrush;
|
||||
rectBrush.SetColor(Drawing::Color::COLOR_WHITE);
|
||||
@ -456,14 +564,18 @@ void RSSurfaceRenderNodeDrawable::CaptureSurface(RSSurfaceRenderNode& surfaceNod
|
||||
return;
|
||||
}
|
||||
|
||||
bool hwcEnable = surfaceParams.GetHardwareEnabled();
|
||||
surfaceParams.SetHardwareEnabled(false);
|
||||
if (!(surfaceParams.HasSecurityLayer() || surfaceParams.HasSkipLayer() || surfaceParams.HasProtectedLayer() ||
|
||||
hasHdrPresent_) && DealWithUIFirstCache(surfaceNode, canvas, surfaceParams, *uniParams)) {
|
||||
surfaceParams.SetHardwareEnabled(hwcEnable);
|
||||
return;
|
||||
}
|
||||
surfaceParams.SetHardwareEnabled(hwcEnable);
|
||||
|
||||
auto nodeType = surfaceParams.GetSurfaceNodeType();
|
||||
bool isSelfDrawingSurface = (nodeType == RSSurfaceNodeType::SELF_DRAWING_NODE);
|
||||
if (isSelfDrawingSurface && !surfaceParams.IsSpherizeValid()) {
|
||||
if (isSelfDrawingSurface && !surfaceParams.IsSpherizeValid() && !surfaceParams.IsAttractionValid()) {
|
||||
SetSkip(surfaceParams.GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE);
|
||||
canvas.Save();
|
||||
}
|
||||
@ -497,9 +609,45 @@ void RSSurfaceRenderNodeDrawable::CaptureSurface(RSSurfaceRenderNode& surfaceNod
|
||||
RSRenderParams::SetParentSurfaceMatrix(parentSurfaceMatrix);
|
||||
}
|
||||
|
||||
#ifdef USE_VIDEO_PROCESSING_ENGINE
|
||||
void RSSurfaceRenderNodeDrawable::DealWithHdr(RSSurfaceRenderNode& surfaceNode,
|
||||
const RSSurfaceRenderParams& surfaceParams)
|
||||
{
|
||||
std::shared_ptr<RSDisplayRenderNode> ancestor = nullptr;
|
||||
if (surfaceNode.GetAncestorDisplayNode().lock() != nullptr) {
|
||||
ancestor = surfaceNode.GetAncestorDisplayNode().lock()->ReinterpretCastTo<RSDisplayRenderNode>();
|
||||
}
|
||||
if (ancestor == nullptr) {
|
||||
RS_LOGE("RSSurfaceRenderNodeDrawable DealWithHdr GetAncestorDisplayNode() return nullptr");
|
||||
return;
|
||||
}
|
||||
auto screenId = ancestor->GetScreenId();
|
||||
if (!RSLuminanceControl::Get().IsHdrOn(screenId)) {
|
||||
return;
|
||||
}
|
||||
const sptr<SurfaceBuffer> buffer = surfaceParams.GetBuffer();
|
||||
if (buffer == nullptr) {
|
||||
return;
|
||||
}
|
||||
Media::VideoProcessingEngine::CM_ColorSpaceInfo colorSpaceInfo;
|
||||
if (MetadataHelper::GetColorSpaceInfo(buffer, colorSpaceInfo) != GSERROR_OK) {
|
||||
return;
|
||||
}
|
||||
bool isHdrBuffer = colorSpaceInfo.transfunc == HDI::Display::Graphic::Common::V1_0::TRANSFUNC_PQ ||
|
||||
colorSpaceInfo.transfunc == HDI::Display::Graphic::Common::V1_0::TRANSFUNC_HLG;
|
||||
|
||||
surfaceNode.SetDisplayNit(RSLuminanceControl::Get().GetHdrDisplayNits(screenId));
|
||||
surfaceNode.SetBrightnessRatio(
|
||||
isHdrBuffer ? 1.0f : RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
void RSSurfaceRenderNodeDrawable::DealWithSelfDrawingNodeBuffer(RSSurfaceRenderNode& surfaceNode,
|
||||
RSPaintFilterCanvas& canvas, const RSSurfaceRenderParams& surfaceParams)
|
||||
{
|
||||
#ifdef USE_VIDEO_PROCESSING_ENGINE
|
||||
DealWithHdr(surfaceNode, surfaceParams);
|
||||
#endif
|
||||
if (surfaceParams.GetHardwareEnabled() && !RSUniRenderThread::GetCaptureParam().isInCaptureFlag_) {
|
||||
if (!surfaceNode.IsHardwareEnabledTopSurface()) {
|
||||
RSAutoCanvasRestore arc(&canvas);
|
||||
@ -518,20 +666,7 @@ void RSSurfaceRenderNodeDrawable::DealWithSelfDrawingNodeBuffer(RSSurfaceRenderN
|
||||
auto params = RSUniRenderUtil::CreateBufferDrawParam(surfaceNode, false, threadId, useRenderParams);
|
||||
params.targetColorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
|
||||
#ifdef USE_VIDEO_PROCESSING_ENGINE
|
||||
auto screenManager = CreateOrGetScreenManager();
|
||||
auto ancestorDisplayNode = surfaceParams.GetAncestorDisplayNode().lock();
|
||||
if (!ancestorDisplayNode) {
|
||||
RS_LOGE("ancestorDisplayNode return nullptr");
|
||||
return;
|
||||
}
|
||||
auto ancestor = ancestorDisplayNode->ReinterpretCastTo<RSDisplayRenderNode>();
|
||||
if (!ancestor) {
|
||||
RS_LOGE("surfaceNode GetAncestorDisplayNode() return nullptr");
|
||||
return;
|
||||
}
|
||||
auto ancestorParam = static_cast<RSDisplayRenderParams*>(ancestor->GetRenderParams().get());
|
||||
params.screenBrightnessNits =
|
||||
screenManager->GetScreenBrightnessNits(ancestorParam ? ancestorParam->GetScreenId() : 0);
|
||||
params.screenBrightnessNits = surfaceNode.GetDisplayNit();
|
||||
#endif
|
||||
auto bgColor = surfaceParams.GetBackgroundColor();
|
||||
auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
|
||||
@ -569,16 +704,22 @@ bool RSSurfaceRenderNodeDrawable::DealWithUIFirstCache(RSSurfaceRenderNode& surf
|
||||
canvas.MultiplyAlpha(surfaceParams.GetAlpha());
|
||||
canvas.ConcatMatrix(surfaceParams.GetMatrix());
|
||||
}
|
||||
DrawBackground(canvas, bounds);
|
||||
bool drawCacheSuccess = true;
|
||||
bool useDmaBuffer = UseDmaBuffer();
|
||||
if (!useDmaBuffer) {
|
||||
DrawBackground(canvas, bounds);
|
||||
}
|
||||
bool canSkipFirstWait = (enableType == MultiThreadCacheType::ARKTS_CARD) &&
|
||||
(RSUifirstManager::Instance().GetCurrentFrameSkipFirstWait());
|
||||
if (!DrawUIFirstCache(canvas, canSkipFirstWait)) {
|
||||
|
||||
bool drawCacheSuccess = useDmaBuffer ?
|
||||
DrawUIFirstCacheWithDma(canvas, surfaceParams) : DrawUIFirstCache(canvas, canSkipFirstWait);
|
||||
if (!drawCacheSuccess) {
|
||||
RS_TRACE_NAME_FMT("[%s] reuse failed!", name_.c_str());
|
||||
RS_LOGE("DrawUIFirstCache failed!");
|
||||
drawCacheSuccess = false;
|
||||
}
|
||||
DrawForeground(canvas, bounds);
|
||||
if (!useDmaBuffer) {
|
||||
DrawForeground(canvas, bounds);
|
||||
}
|
||||
if (uniParams.GetUIFirstDebugEnabled()) {
|
||||
DrawUIFirstDfx(canvas, enableType, surfaceParams, drawCacheSuccess);
|
||||
}
|
||||
|
@ -16,9 +16,22 @@
|
||||
#ifndef RENDER_SERVICE_DRAWABLE_RS_SURFACE_RENDER_NODE_DRAWABLE_H
|
||||
#define RENDER_SERVICE_DRAWABLE_RS_SURFACE_RENDER_NODE_DRAWABLE_H
|
||||
|
||||
#ifndef ROSEN_CROSS_PLATFORM
|
||||
#include <ibuffer_consumer_listener.h>
|
||||
#include <iconsumer_surface.h>
|
||||
#include <surface.h>
|
||||
#endif
|
||||
#ifdef NEW_RENDER_CONTEXT
|
||||
#include "rs_render_surface.h"
|
||||
#else
|
||||
#include "platform/drawing/rs_surface.h"
|
||||
#endif
|
||||
|
||||
#include "common/rs_common_def.h"
|
||||
#include "drawable/rs_render_node_drawable.h"
|
||||
#include "params/rs_surface_render_params.h"
|
||||
#include "pipeline/rs_base_render_engine.h"
|
||||
#include "params/rs_display_render_params.h"
|
||||
#include "pipeline/rs_surface_render_node.h"
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
@ -51,6 +64,23 @@ public:
|
||||
return name_;
|
||||
}
|
||||
|
||||
// Dma Buffer
|
||||
bool UseDmaBuffer();
|
||||
|
||||
bool IsSurfaceCreated() const
|
||||
{
|
||||
return surfaceCreated_;
|
||||
}
|
||||
|
||||
void ClearBufferQueue();
|
||||
|
||||
#ifndef ROSEN_CROSS_PLATFORM
|
||||
bool CreateSurface();
|
||||
#endif
|
||||
BufferRequestConfig GetFrameBufferRequestConfig();
|
||||
std::unique_ptr<RSRenderFrame> RequestFrame(
|
||||
RenderContext* renderContext, std::shared_ptr<Drawing::GPUContext> grContext);
|
||||
|
||||
// UIFirst
|
||||
void SetSubmittedSubThreadIndex(uint32_t index)
|
||||
{
|
||||
@ -153,6 +183,16 @@ public:
|
||||
{
|
||||
return brightnessRatio_;
|
||||
}
|
||||
|
||||
void SetSubThreadSkip(bool isSubThreadSkip)
|
||||
{
|
||||
isSubThreadSkip_ = isSubThreadSkip;
|
||||
}
|
||||
|
||||
bool IsSubThreadSkip() const
|
||||
{
|
||||
return isSubThreadSkip_;
|
||||
}
|
||||
void SetTaskFrameCount(uint64_t frameCount);
|
||||
|
||||
uint64_t GetTaskFrameCount() const;
|
||||
@ -170,6 +210,8 @@ public:
|
||||
RSPaintFilterCanvas& canvas, const RSSurfaceRenderParams& surfaceParams);
|
||||
void ClearCacheSurfaceOnly();
|
||||
|
||||
bool PrepareOffscreenRender();
|
||||
void FinishOffscreenRender(const Drawing::SamplingOptions& sampling);
|
||||
private:
|
||||
explicit RSSurfaceRenderNodeDrawable(std::shared_ptr<const RSRenderNode>&& node);
|
||||
void CacheImgForCapture(RSPaintFilterCanvas& canvas, std::shared_ptr<RSDisplayRenderNode> curDisplayNode);
|
||||
@ -193,10 +235,27 @@ private:
|
||||
bool DrawUIFirstCache(RSPaintFilterCanvas& rscanvas, bool canSkipWait);
|
||||
bool CheckIfNeedResetRotate(RSPaintFilterCanvas& canvas);
|
||||
NodeId FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node);
|
||||
#ifdef USE_VIDEO_PROCESSING_ENGINE
|
||||
void DealWithHdr(RSSurfaceRenderNode& surfaceNode, const RSSurfaceRenderParams& surfaceParams);
|
||||
#endif
|
||||
|
||||
void DrawUIFirstDfx(RSPaintFilterCanvas& canvas, MultiThreadCacheType enableType,
|
||||
RSSurfaceRenderParams& surfaceParams, bool drawCacheSuccess);
|
||||
void EnableGpuOverDrawDrawBufferOptimization(Drawing::Canvas& canvas, RSSurfaceRenderParams* surfaceParams);
|
||||
|
||||
// DMA Buffer
|
||||
bool DrawUIFirstCacheWithDma(RSPaintFilterCanvas& canvas, RSSurfaceRenderParams& surfaceParams);
|
||||
void DrawDmaBufferWithGPU(RSPaintFilterCanvas& canvas);
|
||||
#ifndef ROSEN_CROSS_PLATFORM
|
||||
sptr<IBufferConsumerListener> consumerListener_ = nullptr;
|
||||
#endif
|
||||
#ifdef NEW_RENDER_CONTEXT
|
||||
std::shared_ptr<RSRenderSurface> surface_ = nullptr;
|
||||
#else
|
||||
std::shared_ptr<RSSurface> surface_ = nullptr;
|
||||
#endif
|
||||
bool surfaceCreated_ = false;
|
||||
|
||||
// UIFIRST
|
||||
UIFirstParams uiFirstParams;
|
||||
ClearCacheSurfaceFunc clearCacheSurfaceFunc_ = nullptr;
|
||||
@ -220,6 +279,15 @@ private:
|
||||
bool hasHdrPresent_ = false;
|
||||
float brightnessRatio_ = 1.0f; // 1.of means no discount.
|
||||
uint64_t frameCount_ = 0;
|
||||
bool isSubThreadSkip_ = false;
|
||||
|
||||
RSPaintFilterCanvas* curCanvas_ = nullptr;
|
||||
std::shared_ptr<Drawing::Surface> offscreenSurface_ = nullptr; // temporary holds offscreen surface
|
||||
int releaseCount_ = 0;
|
||||
static constexpr int MAX_RELEASE_FRAME = 10;
|
||||
RSPaintFilterCanvas* canvasBackup_ = nullptr; // backup current canvas before offscreen rende
|
||||
std::shared_ptr<RSPaintFilterCanvas> offscreenCanvas_ = nullptr;
|
||||
int maxRenderSize_ = 0;
|
||||
};
|
||||
} // namespace DrawableV2
|
||||
} // namespace OHOS::Rosen
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user