• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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