1 /*
2  * Copyright (c) 2022 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_ng/pattern/model/model_pattern.h"
17 
18 #include "core/components_ng/event/event_hub.h"
19 #include "core/components_ng/render/adapter/rosen_render_context.h"
20 #include "core/pipeline_ng/pipeline_context.h"
21 
22 namespace OHOS::Ace::NG {
OnRebuildFrame()23 void ModelPattern::OnRebuildFrame()
24 {
25     auto host = GetHost();
26     CHECK_NULL_VOID(host);
27     auto context = host->GetRenderContext();
28     modelAdapter_->OnRebuildFrame(context);
29 }
30 
ModelPattern(uint32_t key,const ModelViewContext & context)31 ModelPattern::ModelPattern(uint32_t key, const ModelViewContext& context) : key_(key)
32 {
33     modelAdapter_ = MakeRefPtr<ModelAdapterWrapper>(key_, context);
34     modelAdapter_->SetPaintFinishCallback([weak = WeakClaim(this)]() {
35             auto model = weak.Upgrade();
36             if (model) {
37                 if (model->NeedsRepaint()) {
38                     model->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
39                 }
40                 model->GetPaintProperty<ModelPaintProperty>()->ResetFlagProperties();
41             }
42         });
43 }
44 
OnModifyDone()45 void ModelPattern::OnModifyDone()
46 {
47     Pattern::OnModifyDone();
48     auto host = GetHost();
49     CHECK_NULL_VOID(host);
50     auto hub = host->GetEventHub<EventHub>();
51     CHECK_NULL_VOID(hub);
52     auto gestureHub = hub->GetOrCreateGestureEventHub();
53     CHECK_NULL_VOID(gestureHub);
54 
55     if (touchListener_) {
56         return;
57     }
58     auto touchTask = [weak = WeakClaim(this)](const TouchEventInfo& info) {
59         auto pattern = weak.Upgrade();
60         if (pattern) {
61             pattern->HandleTouchEvent(info);
62         }
63     };
64 
65     if (touchListener_) {
66         gestureHub->RemoveTouchEvent(touchListener_);
67     }
68     touchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
69     gestureHub->AddTouchEvent(touchListener_);
70 }
71 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)72 bool ModelPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
73 {
74     if (config.skipMeasure && config.skipLayout) {
75         return false;
76     }
77     CHECK_NULL_RETURN(modelAdapter_, false);
78     auto host = GetHost();
79     CHECK_NULL_RETURN(dirty, false);
80     CHECK_NULL_RETURN(host, false);
81     auto geometryNode = dirty->GetGeometryNode();
82     CHECK_NULL_RETURN(geometryNode, false);
83 
84     auto mainProperty = DynamicCast<ModelPaintProperty>(host->GetPaintProperty<ModelPaintProperty>());
85     auto widthScale = mainProperty->GetRenderWidth().value_or(1.0);
86     auto heightScale = mainProperty->GetRenderHeight().value_or(1.0);
87 
88     auto contentSize = geometryNode->GetContentSize();
89     auto contentOffset = geometryNode->GetContentOffset();
90 
91     bool measure = (config.skipMeasure || dirty->SkipMeasureContent()) ? false : true;
92     float width = contentSize.Width();
93     float height = contentSize.Height();
94     float scale = PipelineContext::GetCurrentContext()->GetViewScale();
95     Render3D::WindowChangeInfo windowChangeInfo {
96         contentOffset.GetX(), contentOffset.GetY(),
97         width, height,
98         scale, widthScale, heightScale,
99         config.contentSizeChange, modelAdapter_->GetSurfaceType(), rotation_,
100     };
101     modelAdapter_->OnDirtyLayoutWrapperSwap(windowChangeInfo);
102     host->MarkNeedSyncRenderTree();
103 
104     return measure;
105 }
106 
OnAttachToFrameNode()107 void ModelPattern::OnAttachToFrameNode()
108 {
109     auto host = GetHost();
110     CHECK_NULL_VOID(host);
111     CHECK_NULL_VOID(modelAdapter_);
112     // hint
113     auto pipeline = host->GetContextRefPtr();
114     CHECK_NULL_VOID(pipeline);
115     pipeline->AddWindowStateChangedCallback(host->GetId());
116     uint32_t rotation = pipeline->GetTransformHint();
117     if (rotation_ != rotation) {
118         rotation_ = rotation;
119     }
120     auto callbackId = pipeline->RegisterTransformHintChangeCallback([weak = WeakClaim(this)](uint32_t rotation) {
121         auto pattern = weak.Upgrade();
122         if (pattern) {
123             pattern->rotation_ = rotation;
124         }
125     });
126     UpdateTransformHintChangedCallbackId(callbackId);
127     modelAdapter_->OnAttachToFrameNode(host->GetRenderContext());
128 }
129 
OnDetachFromFrameNode(FrameNode * node)130 void ModelPattern::OnDetachFromFrameNode(FrameNode* node)
131 {
132     CHECK_NULL_VOID(node);
133     auto id = node->GetId();
134     auto pipeline = node->GetContextRefPtr();
135     CHECK_NULL_VOID(pipeline);
136     pipeline->RemoveWindowStateChangedCallback(id);
137 
138     if (HasTransformHintChangedCallbackId()) {
139         pipeline->UnregisterTransformHintChangedCallback(transformHintChangedCallbackId_.value_or(-1));
140     }
141 }
142 
HandleTouchEvent(const TouchEventInfo & info)143 void ModelPattern::HandleTouchEvent(const TouchEventInfo& info)
144 {
145     CHECK_NULL_VOID(modelAdapter_);
146     auto mainProperty = DynamicCast<ModelPaintProperty>(GetHost()->GetPaintProperty<ModelPaintProperty>());
147     bool repaint = modelAdapter_->HandleTouchEvent(info, mainProperty);
148     if (repaint) {
149         MarkDirtyNode(PROPERTY_UPDATE_RENDER);
150     }
151 }
152 
NeedsRepaint()153 bool ModelPattern::NeedsRepaint()
154 {
155     CHECK_NULL_RETURN(modelAdapter_, false);
156     return modelAdapter_->NeedsRepaint();
157 }
158 
MarkDirtyNode(const PropertyChangeFlag flag)159 void ModelPattern::MarkDirtyNode(const PropertyChangeFlag flag)
160 {
161     auto host = GetHost();
162     CHECK_NULL_VOID(host);
163     host->MarkDirtyNode(flag);
164 }
165 
TextureImagesToStr(const RefPtr<ModelPaintProperty> & modelPaintProperty)166 static std::string TextureImagesToStr(const RefPtr<ModelPaintProperty>& modelPaintProperty)
167 {
168     std::string ret;
169     if (modelPaintProperty->GetModelImageTexturePathsValue().empty()) {
170         return ret;
171     }
172     auto& imageTextures = modelPaintProperty->GetModelImageTexturePaths().value();
173     for (auto& imageTexture : imageTextures) {
174         ret += imageTexture + " ";
175     }
176     return ret;
177 }
178 
ShaderInputBufferToStr(const RefPtr<ModelPaintProperty> & modelPaintProperty)179 static std::string ShaderInputBufferToStr(const RefPtr<ModelPaintProperty>& modelPaintProperty)
180 {
181     std::string ret;
182     const auto& shaderInputBuffer = modelPaintProperty->GetModelShaderInputBuffer().value();
183     if (!shaderInputBuffer || !shaderInputBuffer->IsValid()) {
184         return ret;
185     }
186     auto fSize = shaderInputBuffer->FloatSize();
187     auto buffer = shaderInputBuffer->Map(fSize);
188 
189     if (!buffer) {
190         return ret;
191     }
192     for (auto i = 0u; i < fSize; i++) {
193         ret += std::to_string(buffer[i]) + " ";
194     }
195     return ret;
196 }
197 
SurfaceTypeToStr(const RefPtr<ModelAdapterWrapper> & modelAdapter)198 static std::string SurfaceTypeToStr(const RefPtr<ModelAdapterWrapper>& modelAdapter)
199 {
200     std::string ret;
201     if (!modelAdapter) {
202         return ret;
203     }
204     auto surfaceType = modelAdapter->GetSurfaceType();
205     switch (surfaceType) {
206         case Render3D::SurfaceType::UNDEFINE: {
207             ret = "UNDEFINE";
208             break;
209         }
210         case Render3D::SurfaceType::SURFACE_WINDOW: {
211             ret = "ModelType.SURFACE";
212             break;
213         }
214         case Render3D::SurfaceType::SURFACE_TEXTURE: {
215             ret = "ModelType.TEXTURE";
216             break;
217         }
218         case Render3D::SurfaceType::SURFACE_BUFFER: {
219             ret = "SURFACE_BUFFER";
220             break;
221         }
222         default: {
223             ret = "SURFACE_WINDOW";
224             break;
225         }
226     }
227     return ret;
228 }
229 
SceneResourceToStr(const RefPtr<ModelPaintProperty> & modelPaintProperty)230 static std::string SceneResourceToStr(const RefPtr<ModelPaintProperty>& modelPaintProperty)
231 {
232     std::string ret;
233     if (modelPaintProperty->GetModelSourceValue().empty()) {
234         return ret;
235     }
236     ret = modelPaintProperty->GetModelSource().value();
237     return ret;
238 }
239 
SceneEnvironmentToStr(const RefPtr<ModelPaintProperty> & modelPaintProperty)240 static std::string SceneEnvironmentToStr(const RefPtr<ModelPaintProperty>& modelPaintProperty)
241 {
242     std::string ret;
243     if (modelPaintProperty->GetModelBackgroundValue().empty()) {
244         return ret;
245     }
246     ret = modelPaintProperty->GetModelBackground().value();
247     return ret;
248 }
249 
SceneCustomRenderToStr(const RefPtr<ModelPaintProperty> & modelPaintProperty)250 static std::string SceneCustomRenderToStr(const RefPtr<ModelPaintProperty>& modelPaintProperty)
251 {
252     std::string ret;
253     auto& customRender = modelPaintProperty->GetModelCustomRender().value();
254     if (!customRender) {
255         return ret;
256     }
257     ret = customRender->GetUri();
258     return ret;
259 }
260 
SceneShaderPathToStr(const RefPtr<ModelPaintProperty> & modelPaintProperty)261 static std::string SceneShaderPathToStr(const RefPtr<ModelPaintProperty>& modelPaintProperty)
262 {
263     std::string ret;
264     if (modelPaintProperty->GetShaderPathValue().empty()) {
265         return ret;
266     }
267     ret = modelPaintProperty->GetShaderPath().value();
268     return ret;
269 }
270 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const271 void ModelPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
272 {
273     Pattern::ToJsonValue(json, filter);
274     auto host = GetHost();
275     CHECK_NULL_VOID(host);
276     auto mainProperty = DynamicCast<ModelPaintProperty>(host->GetPaintProperty<ModelPaintProperty>());
277     CHECK_NULL_VOID(mainProperty);
278     auto widthScale = mainProperty->GetRenderWidth().value_or(1.0);
279     auto heightScale = mainProperty->GetRenderHeight().value_or(1.0);
280     json->PutExtAttr("renderWidth", std::to_string(widthScale).c_str(), filter);
281     json->PutExtAttr("renderHeight", std::to_string(heightScale).c_str(), filter);
282     json->PutExtAttr("shaderInputBuffer", ShaderInputBufferToStr(mainProperty).c_str(), filter);
283     json->PutExtAttr("shaderImageTexture", TextureImagesToStr(mainProperty).c_str(), filter);
284     json->PutExtAttr("modelType", SurfaceTypeToStr(modelAdapter_).c_str(), filter);
285 
286     json->PutExtAttr("environment", SceneEnvironmentToStr(mainProperty).c_str(), filter);
287     json->PutExtAttr("customRender", SceneCustomRenderToStr(mainProperty).c_str(), filter);
288     json->PutExtAttr("shader", SceneShaderPathToStr(mainProperty).c_str(), filter);
289     json->PutExtAttr("scene", SceneResourceToStr(mainProperty).c_str(), filter);
290 }
291 
~ModelPattern()292 ModelPattern::~ModelPattern()
293 {
294     CHECK_NULL_VOID(modelAdapter_);
295     modelAdapter_->Deinit();
296 }
297 } // namespace OHOS::Ace::NG
298