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:
sqwlly 2024-06-20 06:55:01 +00:00
commit 3daa68cc77
311 changed files with 12093 additions and 2445 deletions

14
.gitee/CODEOWNERS Normal file
View 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

View File

@ -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",

View File

@ -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

View File

@ -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" ]
}
}

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -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"

View File

@ -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);
}
}

View File

@ -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"

View File

@ -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,

View File

@ -29,6 +29,9 @@
"uid" : "graphics",
"gid" : ["system", "tp_host"],
"caps" : ["SYS_NICE"],
"bootevents": [
"bootevent.renderservice.ready"
],
"permission" : [
"ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT"
],

View File

@ -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 {

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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_;
};

View File

@ -183,9 +183,6 @@ public:
void UpdateNodeIdToPicture(NodeId nodeId);
size_t CountTextBlobNum();
void CacheQuadPath();
private:
void ClearCache();
void GenerateCacheByVector(Canvas* canvas, const Rect* rect);

View File

@ -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

View File

@ -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_;

View File

@ -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();

View File

@ -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;

View File

@ -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;
};

View File

@ -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());

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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);
}

View File

@ -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);

View File

@ -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_);

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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!");
}
}
}

View File

@ -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 };

View File

@ -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 *));

View File

@ -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));

View File

@ -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);
}
/*

View File

@ -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 *));

View File

@ -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;
};

View File

@ -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_;

View File

@ -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;
}

View File

@ -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 &timestamp, 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 &timestamp, 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);

View File

@ -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++;
}

View File

@ -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()

View File

@ -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",
]

View File

@ -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",
]
}

View 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 }}}

View File

@ -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

View File

@ -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),

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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" ]

View File

@ -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

View 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.
*/
#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

View 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

View File

@ -18,6 +18,7 @@
#include "draw/canvas.h"
#include "image/image.h"
#include "ge_shader.h"
namespace OHOS {
namespace Rosen {

View File

@ -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

View 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

View File

@ -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
{

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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(

View File

@ -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);

View 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

View File

@ -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;
}

View 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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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_);
}

View File

@ -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, "");

View File

@ -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

View File

@ -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>(

View File

@ -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

View File

@ -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" ]
}

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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, &params);
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, &params);
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;
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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