1 /*
2 * Copyright (c) 2022-2024 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 #include "core/components_ng/render/adapter/rosen_render_surface.h"
16
17 #include "render_service_client/core/ui/rs_surface_node.h"
18 #include "surface_utils.h"
19 #include "transaction/rs_interfaces.h"
20 #include "base/log/dump_log.h"
21 #include "core/common/ace_engine.h"
22 #include "core/components_ng/render/adapter/rosen_render_context.h"
23 #include "core/pipeline_ng/pipeline_context.h"
24
25 namespace OHOS::Ace::NG {
26 namespace {
27 const char* const SURFACE_STRIDE_ALIGNMENT = "8";
28 constexpr int32_t EXT_SURFACE_DEFAULT_SIZE = 1;
29 constexpr int32_t MAX_BUFFER_SIZE = 3;
30 const std::string PATTERN_TYPE_WEB = "WEBPATTERN";
31 const uint32_t ADJUST_WEB_DRAW_LENGTH = 3000;
32 const uint32_t DEFAULT_WEB_DRAW_LENGTH = 6167;
33 const std::string SURFACE_WIDTH = "surface_width";
34 const std::string SURFACE_HEIGHT = "surface_height";
35 const int32_t SIZE_LIMIT = 5999;
36 const int32_t PERMITTED_DIFFERENCE = 100;
37 const int32_t FAILED_LIMIT = 3;
38 const int32_t WAIT_FENCE_TIME = 5000;
39
ConvertRotation(uint32_t rotation)40 GraphicTransformType ConvertRotation(uint32_t rotation)
41 {
42 GraphicTransformType transform = GraphicTransformType::GRAPHIC_ROTATE_BUTT;
43 switch (rotation) {
44 case 0:
45 transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
46 break;
47 case 90:
48 transform = GraphicTransformType::GRAPHIC_ROTATE_90;
49 break;
50 case 180:
51 transform = GraphicTransformType::GRAPHIC_ROTATE_180;
52 break;
53 case 270:
54 transform = GraphicTransformType::GRAPHIC_ROTATE_270;
55 break;
56 default:
57 transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
58 break;
59 }
60 return transform;
61 }
62 } // namespace
63
64 #ifdef OHOS_PLATFORM
65 struct SurfaceBufferNode {
SurfaceBufferNodeOHOS::Ace::NG::SurfaceBufferNode66 SurfaceBufferNode(sptr<SurfaceBuffer> buf, sptr<SyncFence> fence, OffsetF orgin)
67 : buffer_(std::move(buf)), fence_(std::move(fence)), orgin_(orgin)
68 {}
69 ~SurfaceBufferNode() noexcept = default;
70
71 sptr<SurfaceBuffer> buffer_;
72 sptr<SyncFence> fence_;
73 OffsetF orgin_ { 0, 0 };
74 uint32_t bufferId_ {};
75 uint32_t sendTimes_ = 0;
76 };
77 #endif
~RosenRenderSurface()78 RosenRenderSurface::~RosenRenderSurface()
79 {
80 if (SystemProperties::GetExtSurfaceEnabled() && surfaceDelegate_) {
81 surfaceDelegate_->ReleaseSurface();
82 return;
83 }
84 if (nativeWindow_) {
85 DestoryNativeWindow(nativeWindow_);
86 nativeWindow_ = nullptr;
87 }
88 UnregisterSurface();
89 if (isTexture_) {
90 Rosen::RSInterfaces::GetInstance().UnregisterSurfaceBufferCallback(getpid(), GetUniqueIdNum());
91 std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
92 while (!availableBuffers_.empty()) {
93 auto surfaceNode = availableBuffers_.front();
94 availableBuffers_.pop();
95 if (surfaceNode) {
96 consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
97 }
98 }
99 auto iter = availableBufferList_.begin();
100 while (iter != availableBufferList_.end()) {
101 auto surfaceNode = *iter;
102 if (surfaceNode) {
103 consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
104 }
105 iter = availableBufferList_.erase(iter);
106 }
107 }
108 }
109
InitSurface()110 void RosenRenderSurface::InitSurface()
111 {
112 auto renderContext = renderContext_.Upgrade();
113 if (!renderContext && SystemProperties::GetExtSurfaceEnabled()) {
114 auto context = PipelineContext::GetCurrentContext();
115 CHECK_NULL_VOID(context);
116 auto windowId = context->GetWindowId();
117 surfaceDelegate_ = new OHOS::SurfaceDelegate(windowId);
118 surfaceDelegate_->CreateSurface();
119 if (extSurfaceCallbackInterface_) {
120 surfaceDelegate_->AddSurfaceCallback(new ExtSurfaceCallback(extSurfaceCallbackInterface_));
121 } else {
122 surfaceDelegate_->SetBounds(0, 0, EXT_SURFACE_DEFAULT_SIZE, EXT_SURFACE_DEFAULT_SIZE);
123 }
124 producerSurface_ = surfaceDelegate_->GetSurface();
125 } else {
126 CHECK_NULL_VOID(renderContext);
127 auto rosenRenderContext = AceType::DynamicCast<NG::RosenRenderContext>(renderContext);
128 CHECK_NULL_VOID(rosenRenderContext);
129 auto rsNode = rosenRenderContext->GetRSNode();
130 CHECK_NULL_VOID(rsNode);
131 if (isTexture_) {
132 rsNode->SetFrameGravity(OHOS::Rosen::Gravity::RESIZE);
133 consumerSurface_ = IConsumerSurface::Create();
134 if (consumerSurface_ == nullptr) {
135 return;
136 }
137 sptr<IBufferProducer> producer = consumerSurface_->GetProducer();
138 if (producer == nullptr) {
139 return;
140 }
141 producerSurface_ = Surface::CreateSurfaceAsProducer(producer);
142 if (producerSurface_ == nullptr) {
143 return;
144 }
145 if (drawBufferListener_ == nullptr) {
146 drawBufferListener_ = new DrawBufferListener(WeakClaim(this));
147 }
148 consumerSurface_->RegisterConsumerListener(drawBufferListener_);
149 } else {
150 auto surfaceNode = OHOS::Rosen::RSBaseNode::ReinterpretCast<OHOS::Rosen::RSSurfaceNode>(rsNode);
151 CHECK_NULL_VOID(surfaceNode);
152 producerSurface_ = surfaceNode->GetSurface();
153 }
154 }
155 RegisterSurface();
156 }
157
Connect() const158 void RosenRenderSurface::Connect() const
159 {
160 CHECK_NULL_VOID(producerSurface_);
161 producerSurface_->Connect();
162 }
163
Disconnect() const164 void RosenRenderSurface::Disconnect() const
165 {
166 CHECK_NULL_VOID(producerSurface_);
167 producerSurface_->Disconnect();
168 }
169
RegisterSurface() const170 void RosenRenderSurface::RegisterSurface() const
171 {
172 CHECK_NULL_VOID(producerSurface_);
173 auto* surfaceUtils = SurfaceUtils::GetInstance();
174 CHECK_NULL_VOID(surfaceUtils);
175 auto ret = surfaceUtils->Add(producerSurface_->GetUniqueId(), producerSurface_);
176 if (ret != SurfaceError::SURFACE_ERROR_OK) {
177 LOGE("add surface error: %{public}d", ret);
178 }
179 }
180
UnregisterSurface() const181 void RosenRenderSurface::UnregisterSurface() const
182 {
183 CHECK_NULL_VOID(producerSurface_);
184 auto* surfaceUtils = SurfaceUtils::GetInstance();
185 CHECK_NULL_VOID(surfaceUtils);
186 auto ret = surfaceUtils->Remove(producerSurface_->GetUniqueId());
187 if (ret != SurfaceError::SURFACE_ERROR_OK) {
188 LOGE("remove surface error: %{public}d", ret);
189 }
190 }
191
UpdateSurfaceConfig()192 void RosenRenderSurface::UpdateSurfaceConfig()
193 {
194 CHECK_NULL_VOID(producerSurface_);
195 producerSurface_->SetQueueSize(queueSize_);
196 producerSurface_->SetUserData("SURFACE_STRIDE_ALIGNMENT", SURFACE_STRIDE_ALIGNMENT);
197 producerSurface_->SetUserData("SURFACE_FORMAT", std::to_string(GRAPHIC_PIXEL_FMT_RGBA_8888));
198 }
199
GetNativeWindow()200 void* RosenRenderSurface::GetNativeWindow()
201 {
202 return nativeWindow_;
203 }
204
SetRenderContext(const RefPtr<RenderContext> & renderContext)205 void RosenRenderSurface::SetRenderContext(const RefPtr<RenderContext>& renderContext)
206 {
207 renderContext_ = WeakClaim(RawPtr(renderContext));
208 }
209
ConfigSurface(uint32_t surfaceWidth,uint32_t surfaceHeight)210 void RosenRenderSurface::ConfigSurface(uint32_t surfaceWidth, uint32_t surfaceHeight)
211 {
212 CHECK_NULL_VOID(producerSurface_);
213 producerSurface_->SetUserData("SURFACE_WIDTH", std::to_string(surfaceWidth));
214 producerSurface_->SetUserData("SURFACE_HEIGHT", std::to_string(surfaceHeight));
215 }
216
IsSurfaceValid() const217 bool RosenRenderSurface::IsSurfaceValid() const
218 {
219 return producerSurface_ != nullptr;
220 }
221
CreateNativeWindow()222 void RosenRenderSurface::CreateNativeWindow()
223 {
224 nativeWindow_ = CreateNativeWindowFromSurface(&producerSurface_);
225 }
226
AdjustNativeWindowSize(uint32_t width,uint32_t height)227 void RosenRenderSurface::AdjustNativeWindowSize(uint32_t width, uint32_t height)
228 {
229 CHECK_NULL_VOID(nativeWindow_);
230 NativeWindowHandleOpt(nativeWindow_, SET_BUFFER_GEOMETRY, width, height);
231 }
232
UpdateSurfaceSizeInUserData(uint32_t width,uint32_t height)233 void RosenRenderSurface::UpdateSurfaceSizeInUserData(uint32_t width, uint32_t height)
234 {
235 CHECK_NULL_VOID(producerSurface_);
236 producerSurface_->SetUserData(SURFACE_WIDTH, std::to_string(width));
237 producerSurface_->SetUserData(SURFACE_HEIGHT, std::to_string(height));
238 }
239
GetUniqueId() const240 std::string RosenRenderSurface::GetUniqueId() const
241 {
242 if (!producerSurface_) {
243 return "";
244 }
245 return std::to_string(producerSurface_->GetUniqueId());
246 }
247
GetUniqueIdNum() const248 uint64_t RosenRenderSurface::GetUniqueIdNum() const
249 {
250 if (!producerSurface_) {
251 return 0;
252 }
253 return producerSurface_->GetUniqueId();
254 }
255
SetExtSurfaceBounds(int32_t left,int32_t top,int32_t width,int32_t height)256 void RosenRenderSurface::SetExtSurfaceBounds(int32_t left, int32_t top, int32_t width, int32_t height)
257 {
258 if (SystemProperties::GetExtSurfaceEnabled() && surfaceDelegate_) {
259 surfaceDelegate_->SetBounds(left, top, width, height);
260 }
261 }
262
SetExtSurfaceCallback(const RefPtr<ExtSurfaceCallbackInterface> & extSurfaceCallback)263 void RosenRenderSurface::SetExtSurfaceCallback(const RefPtr<ExtSurfaceCallbackInterface>& extSurfaceCallback)
264 {
265 extSurfaceCallbackInterface_ = extSurfaceCallback;
266 }
267
SetTransformHint(uint32_t rotation)268 void RosenRenderSurface::SetTransformHint(uint32_t rotation)
269 {
270 auto transform = ConvertRotation(rotation);
271 CHECK_NULL_VOID(producerSurface_);
272 producerSurface_->SetTransformHint(transform);
273 }
274
DumpInfo()275 void RosenRenderSurface::DumpInfo()
276 {
277 DumpLog::GetInstance().AddDesc(
278 std::string("UserData[surface_width]: ")
279 .append(producerSurface_ ? producerSurface_->GetUserData(SURFACE_WIDTH) : "NoSurface"));
280 DumpLog::GetInstance().AddDesc(
281 std::string("UserData[surface_height]: ")
282 .append(producerSurface_ ? producerSurface_->GetUserData(SURFACE_HEIGHT) : "NoSurface"));
283 }
284
SetSurfaceDefaultSize(int32_t width,int32_t height)285 void RosenRenderSurface::SetSurfaceDefaultSize(int32_t width, int32_t height)
286 {
287 if (consumerSurface_) {
288 consumerSurface_->SetDefaultWidthAndHeight(width, height);
289 }
290 }
291
DrawBuffer(int32_t width,int32_t height)292 void RosenRenderSurface::DrawBuffer(int32_t width, int32_t height)
293 {
294 #ifdef OHOS_PLATFORM
295 auto renderContext = renderContext_.Upgrade();
296 CHECK_NULL_VOID(renderContext);
297 auto rosenRenderContext = DynamicCast<RosenRenderContext>(renderContext);
298 CHECK_NULL_VOID(rosenRenderContext);
299 std::shared_ptr<SurfaceBufferNode> surfaceNode = nullptr;
300 {
301 std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
302
303 if (availableBuffers_.size() >= 1) {
304 surfaceNode = availableBuffers_.back();
305 }
306 }
307 if (!surfaceNode) {
308 return;
309 }
310 CompareBufferSize(width, height, surfaceNode);
311 ACE_SCOPED_TRACE("Web DrawBuffer");
312 rosenRenderContext->StartRecording();
313 auto rsNode = rosenRenderContext->GetRSNode();
314 CHECK_NULL_VOID(rsNode);
315 rsNode->DrawOnNode(
316 #ifndef USE_ROSEN_DRAWING
317 Rosen::RSModifierType::CONTENT_STYLE, [surfaceNode](const std::shared_ptr<SkCanvas>& canvas) {
318 CHECK_NULL_VOID(canvas);
319 Rosen::RSSurfaceBufferInfo info { surfaceNode->buffer_, surfaceNode->orgin_.GetX(),
320 surfaceNode->orgin_.GetY(), surfaceNode->buffer_->GetSurfaceBufferWidth(),
321 surfaceNode->buffer_->GetSurfaceBufferHeight() };
322 auto* recordingCanvas = static_cast<Rosen::RSRecordingCanvas*>(canvas.get());
323 CHECK_NULL_VOID(recordingCanvas);
324 recordingCanvas->DrawSurfaceBuffer(info);
325 #else
326 Rosen::RSModifierType::CONTENT_STYLE,
327 [surfaceNode](const std::shared_ptr<RSCanvas>& canvas) {
328 CHECK_NULL_VOID(canvas);
329 Rosen::DrawingSurfaceBufferInfo info {surfaceNode->buffer_, surfaceNode->orgin_.GetX(),
330 surfaceNode->orgin_.GetY(), surfaceNode->buffer_->GetSurfaceBufferWidth(),
331 surfaceNode->buffer_->GetSurfaceBufferHeight()};
332 auto* recordingCanvas = static_cast<RSRecordingCanvas*>(canvas.get());
333 CHECK_NULL_VOID(recordingCanvas);
334 recordingCanvas->DrawSurfaceBuffer(info);
335 #endif
336 });
337 rosenRenderContext->StopRecordingIfNeeded();
338 #endif
339 }
340
341 #ifdef OHOS_PLATFORM
342 bool RosenRenderSurface::CompareBufferSize(int32_t width, int32_t height,
343 std::shared_ptr<SurfaceBufferNode> surfaceNode)
344 {
345 int32_t bufferWidth = surfaceNode->buffer_->GetSurfaceBufferWidth();
346 int32_t bufferHeight = surfaceNode->buffer_->GetSurfaceBufferHeight();
347 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(PipelineBase::GetCurrentContext());
348
349 if (bufferWidth > SIZE_LIMIT || bufferHeight > SIZE_LIMIT
350 || (abs(height - bufferHeight) < PERMITTED_DIFFERENCE && abs(width - bufferWidth) < PERMITTED_DIFFERENCE)) {
351 failTimes_ = 0;
352 } else {
353 failTimes_++;
354 if (failTimes_ <= FAILED_LIMIT) {
355 pipeline->SetIsFreezeFlushMessage(true);
356 ACE_SCOPED_TRACE("Web SetIsFreezeFlushMessage (width %d, height %d, bufferWidth %d, bufferHeight %d)",
357 width, height, bufferWidth, bufferHeight);
358 return false;
359 }
360 }
361 return true;
362 }
363 #endif
364
365 void RosenRenderSurface::ConsumeWebBuffer()
366 {
367 #ifdef OHOS_PLATFORM
368 ContainerScope scope(instanceId_);
369 CHECK_NULL_VOID(consumerSurface_);
370
371 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
372 sptr<SyncFence> fence = SyncFence::INVALID_FENCE;
373 int64_t timestamp = 0;
374 OHOS::Rect damage;
375
376 SurfaceError surfaceErr = consumerSurface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
377 if (surfaceErr != SURFACE_ERROR_OK) {
378 LOGE("cannot acquire buffer error = %{public}d", surfaceErr);
379 return;
380 }
381 CHECK_NULL_VOID(fence);
382 auto errorCode = fence->Wait(WAIT_FENCE_TIME);
383 LOGD("RosenRenderSurface::ConsumeWebBuffer, wait Fence ,errorCode : %{public}d", errorCode);
384 PostRenderOnlyTaskToUI();
385
386 int32_t bufferWidth = surfaceBuffer->GetSurfaceBufferWidth();
387 int32_t bufferHeight = surfaceBuffer->GetSurfaceBufferHeight();
388 if (axis_ == Axis::VERTICAL) {
389 if (webOffset_ >= 0 || bufferHeight < ADJUST_WEB_DRAW_LENGTH * 2 || bufferHeight >= DEFAULT_WEB_DRAW_LENGTH) {
390 orgin_.SetY(0);
391 } else {
392 int32_t stepStear = bufferHeight - ADJUST_WEB_DRAW_LENGTH * 2;
393 orgin_.SetY(stepStear * ADJUST_WEB_DRAW_LENGTH);
394 }
395 } else if (axis_ == Axis::HORIZONTAL) {
396 if (webOffset_ >= 0 || bufferWidth < ADJUST_WEB_DRAW_LENGTH * 2 || bufferWidth >= DEFAULT_WEB_DRAW_LENGTH) {
397 orgin_.SetX(0);
398 } else {
399 int32_t stepStear = bufferWidth - ADJUST_WEB_DRAW_LENGTH * 2;
400 orgin_.SetX(stepStear * ADJUST_WEB_DRAW_LENGTH);
401 }
402 }
403 LOGD("ConsumeWebBuffer x : %{public}f, y : %{public}f, width : %{public}d, height : %{public}d",
404 orgin_.GetX(), orgin_.GetY(), bufferWidth, bufferHeight);
405 std::shared_ptr<SurfaceBufferNode> surfaceNode = nullptr;
406 {
407 std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
408 if (availableBuffers_.size() >= MAX_BUFFER_SIZE) {
409 surfaceNode = availableBuffers_.front();
410 availableBuffers_.pop();
411 consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
412 }
413 availableBuffers_.push(std::make_shared<SurfaceBufferNode>(surfaceBuffer, fence, orgin_));
414 }
415 #endif
416 }
417
418 void RosenRenderSurface::PostRenderOnlyTaskToUI()
419 {
420 auto task = [weak = renderContext_]() {
421 auto renderContext = weak.Upgrade();
422 CHECK_NULL_VOID(renderContext);
423 auto host = renderContext->GetHost();
424 CHECK_NULL_VOID(host);
425 host->MarkNeedRenderOnly();
426 };
427 auto container = AceEngine::Get().GetContainer(instanceId_);
428 CHECK_NULL_VOID(container);
429 auto context = container->GetPipelineContext();
430 CHECK_NULL_VOID(context);
431 auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
432 if (uiTaskExecutor.IsRunOnCurrentThread()) {
433 task();
434 } else {
435 uiTaskExecutor.PostTask(task, "ArkUIMarkNeedRenderOnly");
436 }
437 }
438
439 void RosenRenderSurface::ConsumeXComponentBuffer()
440 {
441 #ifdef OHOS_PLATFORM
442 ContainerScope scope(instanceId_);
443 CHECK_NULL_VOID(consumerSurface_);
444
445 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
446 sptr<SyncFence> fence = SyncFence::INVALID_FENCE;
447 int64_t timestamp = 0;
448 OHOS::Rect damage;
449
450 SurfaceError surfaceErr = consumerSurface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
451 if (surfaceErr != SURFACE_ERROR_OK || !surfaceBuffer) {
452 TAG_LOGW(AceLogTag::ACE_XCOMPONENT, "XComponent cannot acquire buffer error = %{public}d", surfaceErr);
453 return;
454 }
455 PostRenderOnlyTaskToUI();
456 auto surfaceNode = std::make_shared<SurfaceBufferNode>(surfaceBuffer, fence, orgin_);
457 CHECK_NULL_VOID(surfaceNode);
458 surfaceNode->bufferId_ = surfaceBuffer->GetSeqNum();
459 {
460 std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
461 auto lastSurfaceNode = availableBufferList_.empty() ? nullptr : availableBufferList_.back();
462 if (lastSurfaceNode && lastSurfaceNode->sendTimes_ <= 0) {
463 ACE_SCOPED_TRACE("ReleaseXComponentBuffer[id:%u][sendTimes:%d]", lastSurfaceNode->bufferId_,
464 lastSurfaceNode->sendTimes_);
465 consumerSurface_->ReleaseBuffer(lastSurfaceNode->buffer_, SyncFence::INVALID_FENCE);
466 availableBufferList_.pop_back();
467 }
468 availableBufferList_.emplace_back(surfaceNode);
469 }
470 ACE_SCOPED_TRACE("ConsumeXComponentBuffer[id:%u][sendTimes:%d][size:%u]", surfaceNode->bufferId_,
471 surfaceNode->sendTimes_, static_cast<uint32_t>(availableBufferList_.size()));
472 #endif
473 }
474
475 void RosenRenderSurface::ReleaseSurfaceBuffers()
476 {
477 #ifdef OHOS_PLATFORM
478 CHECK_NULL_VOID(producerSurface_);
479 producerSurface_->CleanCache();
480 CHECK_NULL_VOID(consumerSurface_);
481 {
482 std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
483 if (!availableBufferList_.empty()) {
484 auto iter = availableBufferList_.begin();
485 auto lastIter = std::prev(availableBufferList_.end());
486 while (iter != lastIter) {
487 auto surfaceNode = *iter;
488 if (surfaceNode) {
489 consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
490 }
491 iter = availableBufferList_.erase(iter);
492 }
493 }
494 }
495 consumerSurface_->CleanCache();
496 #endif
497 }
498
499 void RosenRenderSurface::DrawBufferForXComponent(
500 RSCanvas& canvas, float width, float height, float offsetX, float offsetY)
501 {
502 #ifdef OHOS_PLATFORM
503 auto renderContext = renderContext_.Upgrade();
504 CHECK_NULL_VOID(renderContext);
505 std::shared_ptr<SurfaceBufferNode> surfaceNode = nullptr;
506 {
507 std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
508
509 if (!availableBufferList_.empty()) {
510 surfaceNode = availableBufferList_.back();
511 }
512 if (!surfaceNode) {
513 TAG_LOGW(AceLogTag::ACE_XCOMPONENT, "surfaceNode is null");
514 return;
515 }
516 ++surfaceNode->sendTimes_;
517 }
518 ACE_SCOPED_TRACE("DrawXComponentBuffer[id:%u][sendTimes:%d]", surfaceNode->bufferId_, surfaceNode->sendTimes_);
519 #ifndef USE_ROSEN_DRAWING
520 auto rsCanvas = canvas.GetImpl<RSSkCanvas>();
521 CHECK_NULL_VOID(rsCanvas);
522 auto* skCanvas = rsCanvas->ExportSkCanvas();
523 CHECK_NULL_VOID(skCanvas);
524 auto* recordingCanvas = static_cast<OHOS::Rosen::RSRecordingCanvas*>(skCanvas);
525 CHECK_NULL_VOID(recordingCanvas);
526 Rosen::RSSurfaceBufferInfo info { surfaceNode->buffer_, offsetX, offsetY, static_cast<int32_t>(width),
527 static_cast<int32_t>(height) };
528 recordingCanvas->DrawSurfaceBuffer(info);
529 #else
530 auto& recordingCanvas = static_cast<RSRecordingCanvas&>(canvas);
531 Rosen::DrawingSurfaceBufferInfo info { surfaceNode->buffer_, offsetX, offsetY, static_cast<int32_t>(width),
532 static_cast<int32_t>(height), getpid(), GetUniqueIdNum(), surfaceNode->fence_ };
533 recordingCanvas.DrawSurfaceBuffer(info);
534 #endif
535 #endif
536 }
537
538 void RosenRenderSurface::RegisterBufferCallback()
539 {
540 #ifdef OHOS_PLATFORM
541 CHECK_EQUAL_VOID(isTexture_, false);
542 auto pid = getpid();
543 auto uid = GetUniqueIdNum();
544 if (!bufferCallback_) {
545 bufferCallback_ = std::make_shared<XComponentSurfaceBufferCallback>(WeakClaim(this));
546 }
547 Rosen::RSInterfaces::GetInstance().RegisterSurfaceBufferCallback(pid, uid, bufferCallback_);
548 #endif
549 }
550
551 void RosenRenderSurface::ReleaseSurfaceBufferById(uint32_t bufferId)
552 {
553 std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
554 auto iter = availableBufferList_.begin();
555 while (iter != availableBufferList_.end()) {
556 auto surfaceNode = *iter;
557 if (!surfaceNode) {
558 iter = availableBufferList_.erase(iter);
559 } else if (surfaceNode->bufferId_ == bufferId) {
560 // at least reserve one buffer
561 auto isLast = (iter == std::prev(availableBufferList_.end()));
562 ACE_SCOPED_TRACE(
563 "ReleaseXComponentBuffer[id:%u][sendTimes:%d][isLast:%d]", bufferId, surfaceNode->sendTimes_, isLast);
564 if (--surfaceNode->sendTimes_ <= 0 && !isLast) {
565 consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
566 availableBufferList_.erase(iter);
567 }
568 return;
569 } else {
570 ++iter;
571 }
572 }
573 }
574
575 void DrawBufferListener::OnBufferAvailable()
576 {
577 auto renderSurface = renderSurface_.Upgrade();
578 CHECK_NULL_VOID(renderSurface);
579 if (renderSurface->GetPatternType() == PATTERN_TYPE_WEB) {
580 renderSurface->ConsumeWebBuffer();
581 } else {
582 renderSurface->ConsumeXComponentBuffer();
583 }
584 }
585
586 #ifdef OHOS_PLATFORM
587 void XComponentSurfaceBufferCallback::OnFinish(uint64_t uid, const std::vector<uint32_t>& surfaceBufferIds)
588 {
589 auto renderSurface = renderSurface_.Upgrade();
590 CHECK_NULL_VOID(renderSurface);
591 if (uid != renderSurface->GetUniqueIdNum()) {
592 return;
593 }
594 for (const auto& bufferId : surfaceBufferIds) {
595 renderSurface->ReleaseSurfaceBufferById(bufferId);
596 }
597 }
598 #endif
599
600 void ExtSurfaceCallback::OnSurfaceCreated(const sptr<Surface>& /* surface */)
601 {
602 auto interface = weakInterface_.Upgrade();
603 if (interface) {
604 interface->ProcessSurfaceCreate();
605 }
606 }
607
608 void ExtSurfaceCallback::OnSurfaceChanged(const sptr<Surface>& /* surface */, int32_t width, int32_t height)
609 {
610 auto interface = weakInterface_.Upgrade();
611 if (interface) {
612 interface->ProcessSurfaceChange(width, height);
613 }
614 }
615
616 void ExtSurfaceCallback::OnSurfaceDestroyed()
617 {
618 auto interface = weakInterface_.Upgrade();
619 if (interface) {
620 interface->ProcessSurfaceDestroy();
621 }
622 }
623 } // namespace OHOS::Ace::NG
624