1 /*
2 * Copyright (c) 2021-2023 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 "core/components/video/rosen_render_texture.h"
17
18 #ifndef USE_ROSEN_DRAWING
19 #include "include/core/SkCanvas.h"
20 #include "include/core/SkColor.h"
21 #endif
22 #include "core/components/common/layout/constants.h"
23 #ifdef ENABLE_ROSEN_BACKEND
24 #include "render_service_client/core/ui/rs_surface_node.h"
25 #endif
26
27 #include "base/log/ace_trace.h"
28 #include "base/log/dump_log.h"
29 #include "base/log/log.h"
30 #include "base/utils/system_properties.h"
31 #include "core/components/display/render_display.h"
32 #include "core/pipeline/base/rosen_render_context.h"
33
34 namespace OHOS::Ace {
35
36 namespace {
37
38 constexpr int32_t GAUSSIAN_DURATION = 1000;
39 constexpr Color GAUSSIAN_COLOR = Color(0xffc7bcb9);
40
41 } // namespace
42
Update(const RefPtr<Component> & component)43 void RosenRenderTexture::Update(const RefPtr<Component>& component)
44 {
45 RenderTexture::Update(component);
46
47 if (imageFit_ != ImageFit::FILL && GetRSNode()) {
48 GetRSNode()->SetBackgroundColor(Color::BLACK.GetValue());
49 }
50 }
51
Paint(RenderContext & context,const Offset & offset)52 void RosenRenderTexture::Paint(RenderContext& context, const Offset& offset)
53 {
54 SyncGeometryProperties();
55 #ifdef OHOS_PLATFORM
56 const auto renderContext = static_cast<RosenRenderContext*>(&context);
57 auto rsNode = std::static_pointer_cast<OHOS::Rosen::RSSurfaceNode>(renderContext->GetRSNode());
58
59 if (IsAddGaussianFuzzy()) {
60 AddGaussianFuzzy(context, offset);
61 }
62 #endif
63 RenderNode::Paint(context, offset);
64 }
65
SyncGeometryProperties()66 void RosenRenderTexture::SyncGeometryProperties()
67 {
68 if (!IsTailRenderNode()) {
69 return;
70 }
71 auto rsNode = GetRSNode();
72 if (!rsNode) {
73 return;
74 }
75
76 auto offset = GetPaintOffset() + Offset(alignmentX_, alignmentY_);
77 rsNode->SetBounds(offset.GetX(), offset.GetY(), drawSize_.Width(), drawSize_.Height());
78 LOGI("SetBounds position: %{public}s, size: %{public}s", offset.ToString().c_str(), drawSize_.ToString().c_str());
79 }
80
InitGaussianFuzzyParas()81 void RosenRenderTexture::InitGaussianFuzzyParas()
82 {
83 gaussianFuzzySize_ = GetPaintRect();
84 colorValue_ = GAUSSIAN_COLOR;
85 }
86
SetIsAddGaussianFuzzy(bool isAddGaussianFuzzy)87 void RosenRenderTexture::SetIsAddGaussianFuzzy(bool isAddGaussianFuzzy)
88 {
89 RenderTexture::SetIsAddGaussianFuzzy(isAddGaussianFuzzy);
90 if (isAddGaussianFuzzy) {
91 if (!controller_) {
92 controller_ = CREATE_ANIMATOR(GetContext());
93 } else if (controller_->IsRunning()) {
94 controller_->Finish();
95 }
96 controller_->ClearInterpolators();
97 controller_->ClearAllListeners();
98
99 controller_->AddStartListener([weak = AceType::WeakClaim(this)]() {
100 auto texture = weak.Upgrade();
101 if (texture) {
102 texture->InitGaussianFuzzyParas();
103 }
104 });
105
106 controller_->AddStopListener([weak = AceType::WeakClaim(this)]() {
107 auto texture = weak.Upgrade();
108 if (texture) {
109 texture->SetIsAddGaussianFuzzy(false);
110 }
111 });
112
113 moveAnimation_ = AceType::MakeRefPtr<CurveAnimation<uint8_t>>(0, 1, Curves::LINEAR);
114 moveAnimation_->AddListener(Animation<uint8_t>::ValueCallback([weak = AceType::WeakClaim(this)](uint8_t value) {
115 auto texture = weak.Upgrade();
116 if (texture) {
117 texture->MarkNeedRender();
118 }
119 }));
120
121 controller_->SetDuration(GAUSSIAN_DURATION);
122 controller_->AddInterpolator(moveAnimation_);
123 controller_->Play();
124 } else {
125 if (controller_ && controller_->IsRunning()) {
126 controller_->Stop();
127 }
128 }
129 }
130
AddGaussianFuzzy(RenderContext & context,const Offset & offset)131 void RosenRenderTexture::AddGaussianFuzzy(RenderContext& context, const Offset& offset)
132 {
133 const auto rosenContext = static_cast<RosenRenderContext*>(&context);
134 auto rsNode = rosenContext->GetRSNode();
135 if (rsNode == nullptr) {
136 LOGE("Paint canvas is null.");
137 return;
138 }
139
140 #ifndef USE_ROSEN_DRAWING
141 SkPaint paint;
142 paint.setAntiAlias(true);
143 #else
144 RSBrush brush;
145 brush.SetAntiAlias(true);
146 #endif
147 }
148
UpdateOpacity(uint8_t opacity)149 void RosenRenderTexture::UpdateOpacity(uint8_t opacity)
150 {
151 RenderNode::UpdateOpacity(opacity);
152 }
153
DumpTree(int32_t depth)154 void RosenRenderTexture::DumpTree(int32_t depth)
155 {
156 auto children = GetChildren();
157
158 if (DumpLog::GetInstance().GetDumpFile() > 0) {
159 DumpLog::GetInstance().AddDesc("textureId:", textureId_);
160 DumpLog::GetInstance().AddDesc("drawSize:", "width = ", drawSize_.Width(), " height = ", drawSize_.Height());
161 DumpLog::GetInstance().AddDesc("sourceSize:", "width = ", drawSize_.Width(), " height = ", drawSize_.Height());
162 DumpLog::GetInstance().AddDesc("alignmentX:", alignmentX_);
163 DumpLog::GetInstance().AddDesc("alignmentY:", alignmentY_);
164 DumpLog::GetInstance().Print(depth, AceType::TypeName(this), children.size());
165 }
166
167 for (const auto& item : children) {
168 item->DumpTree(depth + 1);
169 }
170 }
171
CreateRSNode() const172 std::shared_ptr<RSNode> RosenRenderTexture::CreateRSNode() const
173 {
174 struct Rosen::RSSurfaceNodeConfig surfaceNodeConfig = {.SurfaceNodeName = "RosenRenderTexture"};
175 return OHOS::Rosen::RSSurfaceNode::Create(surfaceNodeConfig, false);
176 }
177
178 #ifdef OHOS_STANDARD_SYSTEM
GetSurface()179 OHOS::sptr<OHOS::Surface> RosenRenderTexture::GetSurface()
180 {
181 auto surfaceNode = OHOS::Rosen::RSBaseNode::ReinterpretCast<OHOS::Rosen::RSSurfaceNode>(GetRSNode());
182 if (surfaceNode) {
183 auto surface = surfaceNode->GetSurface();
184 return surface;
185 }
186 return nullptr;
187 }
188
SyncProperties(const Size & videoSize,ImageFit imageFit,ImageObjectPosition imagePosition)189 void RosenRenderTexture::SyncProperties(const Size& videoSize, ImageFit imageFit, ImageObjectPosition imagePosition)
190 {
191 sourceSize_ = videoSize;
192 imageFit_ = imageFit;
193 imagePosition_ = imagePosition;
194 RenderTexture::Measure();
195 SyncGeometryProperties();
196 }
197 #endif
198 } // namespace OHOS::Ace
199