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