1 /*
2 * Copyright (C) 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 "texture_layer.h"
17
18 #include <native_buffer.h>
19 #include <render_service_base/include/pipeline/rs_recording_canvas.h>
20 #include <render_service_base/include/property/rs_properties_def.h>
21 #include <render_service_client/core/pipeline/rs_node_map.h>
22 #include <render_service_client/core/transaction/rs_interfaces.h>
23 #include <render_service_client/core/ui/rs_canvas_node.h>
24 #include <render_service_client/core/ui/rs_root_node.h>
25 #include <render_service_client/core/ui/rs_surface_node.h>
26 #include <surface_buffer.h>
27 #include <surface_utils.h>
28 #include <window.h>
29
30 #include "data_type/constants.h"
31 #include "3d_widget_adapter_log.h"
32 #include "graphics_manager.h"
33 #include "offscreen_context_helper.h"
34 #include "widget_trace.h"
35
36 namespace OHOS {
37 namespace Render3D {
38 struct TextureImage {
TextureImageOHOS::Render3D::TextureImage39 explicit TextureImage(const TextureInfo& textureInfo): textureInfo_(textureInfo) {}
40 TextureImage() = default;
41 TextureInfo textureInfo_;
42 };
43
44 class TextureLayerImpl : public TextureLayer {
45 public:
46 explicit TextureLayerImpl(int32_t key);
47 virtual ~TextureLayerImpl();
48
49 void DestroyRenderTarget() override;
50 TextureInfo GetTextureInfo() override;
51
52 void SetParent(std::shared_ptr<Rosen::RSNode>& parent) override;
53 TextureInfo OnWindowChange(float offsetX, float offsetY, float width, float height, float scale,
54 bool recreateWindow, SurfaceType surfaceType = SurfaceType::SURFACE_WINDOW) override;
55 TextureInfo OnWindowChange(const WindowChangeInfo& windowChangeInfo) override;
56
57 private:
58 void* CreateNativeWindow(uint32_t width, uint32_t height);
59 void ConfigWindow(float offsetX, float offsetY, float width, float height, float scale,
60 bool recreateWindow);
61 void ConfigTexture(float width, float height);
62 void RemoveChild();
63
64 int32_t offsetX_ = 0u;
65 int32_t offsetY_ = 0u;
66 int32_t width_ = 0u;
67 int32_t height_ = 0u;
68 int32_t key_ = INT32_MAX;
69 uint32_t transform_ = 0U;
70
71 std::shared_ptr<Rosen::RSNode> rsNode_ = nullptr;
72 std::shared_ptr<Rosen::RSNode> parent_ = nullptr;
73 sptr<OHOS::Surface> producerSurface_ = nullptr;
74 SurfaceType surface_ = SurfaceType::UNDEFINE;
75 TextureImage image_;
76 };
77
GetTextureInfo()78 TextureInfo TextureLayerImpl::GetTextureInfo()
79 {
80 return image_.textureInfo_;
81 }
82
SetParent(std::shared_ptr<Rosen::RSNode> & parent)83 void TextureLayerImpl::SetParent(std::shared_ptr<Rosen::RSNode>& parent)
84 {
85 parent_ = parent;
86 // delete previous rs node reference
87 RemoveChild();
88
89 if (parent_ && rsNode_) {
90 parent_->AddChild(rsNode_, 0); // second paramenter is added child at the index of parent's children;
91 }
92 }
93
RemoveChild()94 void TextureLayerImpl::RemoveChild()
95 {
96 if (parent_ && rsNode_) {
97 parent_->RemoveChild(rsNode_);
98 }
99 }
100
RotationToTransform(uint32_t rotation)101 GraphicTransformType RotationToTransform(uint32_t rotation)
102 {
103 GraphicTransformType transform = GraphicTransformType::GRAPHIC_ROTATE_BUTT;
104 switch (rotation) {
105 case 0:
106 transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
107 break;
108 case 90:
109 transform = GraphicTransformType::GRAPHIC_ROTATE_90;
110 break;
111 case 180:
112 transform = GraphicTransformType::GRAPHIC_ROTATE_180;
113 break;
114 case 270:
115 transform = GraphicTransformType::GRAPHIC_ROTATE_270;
116 break;
117 default:
118 transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
119 break;
120 }
121 return transform;
122 }
123
CreateNativeWindow(uint32_t width,uint32_t height)124 void* TextureLayerImpl::CreateNativeWindow(uint32_t width, uint32_t height)
125 {
126 std::string bundleName = GraphicsManager::GetInstance().GetHapInfo().bundleName_;
127 struct Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
128 if (bundleName.find("totemweather") != std::string::npos) {
129 surfaceNodeConfig = {.SurfaceNodeName = std::string("SceneViewer Model totemweather") + std::to_string(key_)};
130 } else {
131 surfaceNodeConfig = {.SurfaceNodeName = std::string("SceneViewer Model") + std::to_string(key_)};
132 }
133
134 rsNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, false);
135 if (!rsNode_) {
136 WIDGET_LOGE("Create rs node fail");
137 return nullptr;
138 }
139
140 auto surfaceNode = OHOS::Rosen::RSBaseNode::ReinterpretCast<OHOS::Rosen::RSSurfaceNode>(rsNode_);
141 surfaceNode->SetFrameGravity(Rosen::Gravity::RESIZE);
142 if (surface_ == SurfaceType::SURFACE_WINDOW) {
143 surfaceNode->SetHardwareEnabled(true);
144 }
145 if (surface_ == SurfaceType::SURFACE_TEXTURE) {
146 surfaceNode->SetHardwareEnabled(false);
147 }
148 std::string hapPath = GraphicsManager::GetInstance().GetHapInfo().hapPath_;
149 if (hapPath.find("SceneBoard_MetaBallsTurbo") != std::string::npos) {
150 surfaceNode->SetHardwareEnabled(true);
151 } else if (hapPath.find("HwWeather") != std::string::npos) {
152 surfaceNode->SetHardwareEnabled(true);
153 uint32_t argbWhite = 0xFFFFFFFF; // set a white background color for dss
154 surfaceNode->SetBackgroundColor(argbWhite);
155 }
156
157 producerSurface_ = surfaceNode->GetSurface();
158 if (!producerSurface_) {
159 WIDGET_LOGE("Get producer surface fail");
160 return nullptr;
161 }
162
163 auto transform = RotationToTransform(transform_);
164 producerSurface_->SetTransformHint(transform);
165
166 auto ret = SurfaceUtils::GetInstance()->Add(producerSurface_->GetUniqueId(), producerSurface_);
167 if (ret != SurfaceError::SURFACE_ERROR_OK) {
168 WIDGET_LOGE("add surface error");
169 return nullptr;
170 }
171
172 producerSurface_->SetQueueSize(3); // 3 seems ok
173 producerSurface_->SetUserData("SURFACE_STRIDE_ALIGNMENT", "8");
174 producerSurface_->SetUserData("SURFACE_FORMAT", std::to_string(GRAPHIC_PIXEL_FMT_RGBA_8888));
175 producerSurface_->SetUserData("SURFACE_WIDTH", std::to_string(width));
176 producerSurface_->SetUserData("SURFACE_HEIGHT", std::to_string(height));
177 auto window = CreateNativeWindowFromSurface(&producerSurface_);
178
179 return reinterpret_cast<void *>(window);
180 }
181
ConfigWindow(float offsetX,float offsetY,float width,float height,float scale,bool recreateWindow)182 void TextureLayerImpl::ConfigWindow(float offsetX, float offsetY, float width, float height, float scale,
183 bool recreateWindow)
184 {
185 float widthScale = image_.textureInfo_.widthScale_;
186 float heightScale = image_.textureInfo_.heightScale_;
187 if (surface_ == SurfaceType::SURFACE_WINDOW || surface_ == SurfaceType::SURFACE_TEXTURE) {
188 image_.textureInfo_.recreateWindow_ = recreateWindow;
189
190 if (!image_.textureInfo_.nativeWindow_) {
191 image_.textureInfo_.nativeWindow_ = reinterpret_cast<void *>(CreateNativeWindow(
192 static_cast<uint32_t>(width * widthScale), static_cast<uint32_t>(height * heightScale)));
193 }
194 // need check recreate window flag
195 NativeWindowHandleOpt(reinterpret_cast<OHNativeWindow *>(image_.textureInfo_.nativeWindow_),
196 SET_BUFFER_GEOMETRY, static_cast<uint32_t>(width * scale * widthScale),
197 static_cast<uint32_t>(height * scale * heightScale));
198 rsNode_->SetBounds(offsetX, offsetY, width, height);
199 }
200 }
201
OnWindowChange(float offsetX,float offsetY,float width,float height,float scale,bool recreateWindow,SurfaceType surfaceType)202 TextureInfo TextureLayerImpl::OnWindowChange(float offsetX, float offsetY, float width, float height, float scale,
203 bool recreateWindow, SurfaceType surfaceType)
204 {
205 DestroyRenderTarget();
206 surface_ = surfaceType;
207 offsetX_ = offsetX;
208 offsetY_ = offsetY;
209 image_.textureInfo_.width_ = static_cast<uint32_t>(width);
210 image_.textureInfo_.height_ = static_cast<uint32_t>(height);
211
212 image_.textureInfo_.widthScale_ = scale;
213 image_.textureInfo_.heightScale_ = scale;
214
215 ConfigWindow(offsetX, offsetY, width, height, scale, recreateWindow);
216 WIDGET_LOGD("TextureLayer OnWindowChange offsetX %f, offsetY %f, width %d, height %d, float scale %f,"
217 "recreateWindow %d window empty %d", offsetX, offsetY, image_.textureInfo_.width_, image_.textureInfo_.height_,
218 scale, recreateWindow, image_.textureInfo_.nativeWindow_ == nullptr);
219 return image_.textureInfo_;
220 }
221
OnWindowChange(const WindowChangeInfo & windowChangeInfo)222 TextureInfo TextureLayerImpl::OnWindowChange(const WindowChangeInfo& windowChangeInfo)
223 {
224 DestroyRenderTarget();
225 surface_ = windowChangeInfo.surfaceType;
226 offsetX_ = (int)windowChangeInfo.offsetX;
227 offsetY_ = (int)windowChangeInfo.offsetY;
228 transform_ = windowChangeInfo.transformType;
229
230 image_.textureInfo_.width_ = static_cast<uint32_t>(windowChangeInfo.width);
231 image_.textureInfo_.height_ = static_cast<uint32_t>(windowChangeInfo.height);
232
233 image_.textureInfo_.widthScale_ = static_cast<float>(windowChangeInfo.widthScale);
234 image_.textureInfo_.heightScale_ = static_cast<float>(windowChangeInfo.heightScale);
235
236 ConfigWindow(windowChangeInfo.offsetX, windowChangeInfo.offsetY, windowChangeInfo.width,
237 windowChangeInfo.height, windowChangeInfo.scale, windowChangeInfo.recreateWindow);
238
239 return image_.textureInfo_;
240 }
241
DestroyRenderTarget()242 void TextureLayerImpl::DestroyRenderTarget()
243 {
244 // window release
245 RemoveChild();
246 rsNode_ = nullptr;
247 parent_ = nullptr;
248 image_.textureInfo_ = {};
249 }
250
TextureLayerImpl(int32_t key)251 TextureLayerImpl::TextureLayerImpl(int32_t key): key_(key)
252 {
253 }
254
~TextureLayerImpl()255 TextureLayerImpl::~TextureLayerImpl()
256 {
257 // explicity release resource before destructor
258 }
259
GetTextureInfo()260 TextureInfo TextureLayer::GetTextureInfo()
261 {
262 return textureLayer_->GetTextureInfo();
263 }
264
SetParent(std::shared_ptr<Rosen::RSNode> & parent)265 void TextureLayer::SetParent(std::shared_ptr<Rosen::RSNode>& parent)
266 {
267 return textureLayer_->SetParent(parent);
268 }
269
OnWindowChange(float offsetX,float offsetY,float width,float height,float scale,bool recreateWindow,SurfaceType surfaceType)270 TextureInfo TextureLayer::OnWindowChange(float offsetX, float offsetY, float width, float height, float scale,
271 bool recreateWindow, SurfaceType surfaceType)
272 {
273 return textureLayer_->OnWindowChange(offsetX, offsetY, width, height, scale, recreateWindow, surfaceType);
274 }
275
OnWindowChange(const WindowChangeInfo & windowChangeInfo)276 TextureInfo TextureLayer::OnWindowChange(const WindowChangeInfo& windowChangeInfo)
277 {
278 return textureLayer_->OnWindowChange(windowChangeInfo);
279 }
280
DestroyRenderTarget()281 void TextureLayer::DestroyRenderTarget()
282 {
283 textureLayer_->DestroyRenderTarget();
284 }
285
TextureLayer(int32_t key)286 TextureLayer::TextureLayer(int32_t key)
287 {
288 textureLayer_ = std::make_shared<TextureLayerImpl>(key);
289 }
290
~TextureLayer()291 TextureLayer::~TextureLayer()
292 {
293 // explicit release resource before destructor
294 }
295
296 } // Render3D
297 } // OHOS
298