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