1 /*
2 * Copyright (C) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <atomic>
17 #include <cstddef>
18 #include <mutex>
19 #include <shared_mutex>
20 #include <unordered_map>
21
22 #include "ani_filter.h"
23 #include "ani_effect_kit_utils.h"
24 #include "effect_errors.h"
25 #include "effect_utils.h"
26 #include "pixel_map.h"
27 #include "sk_image_chain.h"
28 #include "sk_image_filter_factory.h"
29
30
31 namespace OHOS {
32 namespace Rosen {
33
34 static const std::string ANI_CLASS_FILTER = "L@ohos/effectKit/effectKit/FilterInternal;";
35
GetDstPixelMap()36 std::shared_ptr<Media::PixelMap> AniFilter::GetDstPixelMap()
37 {
38 return dstPixelMap_;
39 }
40
GetSrcPixelMap()41 std::shared_ptr<Media::PixelMap> AniFilter::GetSrcPixelMap()
42 {
43 return srcPixelMap_;
44 }
45
Render(bool forceCPU)46 DrawError AniFilter::Render(bool forceCPU)
47 {
48 Rosen::SKImageChain skImage(srcPixelMap_);
49 DrawError ret = skImage.Render(skFilters_, forceCPU, dstPixelMap_);
50
51 return ret;
52 }
53
AddNextFilter(sk_sp<SkImageFilter> filter)54 void AniFilter::AddNextFilter(sk_sp<SkImageFilter> filter)
55 {
56 skFilters_.emplace_back(filter);
57 }
58
Blur(ani_env * env,ani_object obj,ani_double param)59 ani_object AniFilter::Blur(ani_env* env, ani_object obj, ani_double param)
60 {
61 SkTileMode tileMode = SkTileMode::kDecal;
62 AniFilter* aniFilter = AniEffectKitUtils::GetFilterFromEnv(env, obj);
63 if (aniFilter == nullptr) {
64 EFFECT_LOG_E("GetFilterFromEnv failed");
65 return AniEffectKitUtils::CreateAniUndefined(env);
66 }
67 float radius = 0.0f;
68 if (param >= 0) {
69 radius = static_cast<float>(param);
70 }
71 auto blur = Rosen::SKImageFilterFactory::Blur(radius, tileMode);
72 aniFilter->AddNextFilter(blur);
73
74 static const char* className = ANI_CLASS_FILTER.c_str();
75 const char* methodSig = "J:V";
76 return AniEffectKitUtils::CreateAniObject(
77 env, className, methodSig, reinterpret_cast<ani_long>(aniFilter));
78 }
79
Grayscale(ani_env * env,ani_object obj)80 ani_object AniFilter::Grayscale(ani_env* env, ani_object obj)
81 {
82 AniFilter* aniFilter = AniEffectKitUtils::GetFilterFromEnv(env, obj);
83 if (aniFilter == nullptr) {
84 EFFECT_LOG_E("GetFilterFromEnv failed");
85 return AniEffectKitUtils::CreateAniUndefined(env);
86 }
87 auto grayscale = Rosen::SKImageFilterFactory::Grayscale();
88 aniFilter->AddNextFilter(grayscale);
89
90 static const char* className = ANI_CLASS_FILTER.c_str();
91 return AniEffectKitUtils::CreateAniObject(
92 env, className, nullptr, reinterpret_cast<ani_long>(aniFilter));
93 }
94
GetEffectPixelMap(ani_env * env,ani_object obj)95 ani_object AniFilter::GetEffectPixelMap(ani_env* env, ani_object obj)
96 {
97 AniFilter* thisFilter = AniEffectKitUtils::GetFilterFromEnv(env, obj);
98 bool forceCpu = false;
99 if (!thisFilter) {
100 EFFECT_LOG_E("thisFilter is null");
101 return AniEffectKitUtils::CreateAniUndefined(env);
102 }
103 if (thisFilter->Render(forceCpu) != DrawError::ERR_OK) {
104 EFFECT_LOG_E("Render error");
105 return AniEffectKitUtils::CreateAniUndefined(env);
106 }
107 return Media::PixelMapTaiheAni::CreateEtsPixelMap(env, thisFilter->GetDstPixelMap());
108 }
109
CreateEffect(ani_env * env,ani_object para)110 ani_object AniFilter::CreateEffect(ani_env* env, ani_object para)
111 {
112 auto aniFilter = std::make_unique<AniFilter>();
113 std::shared_ptr<Media::PixelMap> pixelMap(Media::PixelMapTaiheAni::GetNativePixelMap(env, para));
114 if (!pixelMap) {
115 EFFECT_LOG_E("pixelMap is null");
116 return AniEffectKitUtils::CreateAniUndefined(env);
117 }
118 aniFilter->srcPixelMap_ = pixelMap;
119
120 static const char* className = ANI_CLASS_FILTER.c_str();
121 const char* methodSig = "J:V";
122 return AniEffectKitUtils::CreateAniObject(
123 env, className, methodSig, reinterpret_cast<ani_long>(aniFilter.release()));
124 }
125
Init(ani_env * env)126 ani_status AniFilter::Init(ani_env* env)
127 {
128 static const char* className = ANI_CLASS_FILTER.c_str();
129 ani_class cls;
130 if (env->FindClass(className, &cls) != ANI_OK) {
131 EFFECT_LOG_E("Not found L@ohos/effectKit/effectKit/FilterInternal");
132 return ANI_NOT_FOUND;
133 }
134
135 std::array methods = {
136 ani_native_function { "blurNative", "D:L@ohos/effectKit/effectKit/Filter;",
137 reinterpret_cast<void*>(OHOS::Rosen::AniFilter::Blur) },
138 ani_native_function { "grayscaleNative", ":L@ohos/effectKit/effectKit/Filter;",
139 reinterpret_cast<void*>(OHOS::Rosen::AniFilter::Grayscale) },
140 ani_native_function { "getEffectPixelMapNative", ":L@ohos/multimedia/image/image/PixelMap;",
141 reinterpret_cast<void*>(OHOS::Rosen::AniFilter::GetEffectPixelMap) },
142 };
143 ani_status ret = env->Class_BindNativeMethods(cls, methods.data(), methods.size());
144 if (ret != ANI_OK) {
145 EFFECT_LOG_I("Class_BindNativeMethods failed: %{public}d", ret);
146 return ANI_ERROR;
147 }
148 return ANI_OK;
149 }
150 } // namespace Rosen
151 } // namespace OHOS
152