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