• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "feature/lpp/lpp_video_handler.h"
16 
17 #include "rs_trace.h"
18 
19 #include "common/rs_optional_trace.h"
20 #include "pipeline/main_thread/rs_main_thread.h"
21 #include "platform/common/rs_log.h"
22 namespace OHOS::Rosen {
Instance()23 LppVideoHandler& LppVideoHandler::Instance()
24 {
25     static LppVideoHandler instance;
26     return instance;
27 }
28 
ConsumeAndUpdateLppBuffer(const std::shared_ptr<RSSurfaceRenderNode> & surfaceNode)29 void LppVideoHandler::ConsumeAndUpdateLppBuffer(const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode)
30 {
31     std::lock_guard<std::mutex> lock(mutex_);
32     std::shared_ptr<RSSurfaceHandler> surfaceHandler;
33     if (UNLIKELY(surfaceNode == nullptr) || (surfaceHandler = surfaceNode->GetMutableRSSurfaceHandler()) == nullptr ||
34         surfaceHandler->GetSourceType() != OHSurfaceSource::OH_SURFACE_SOURCE_LOWPOWERVIDEO) {
35         return;
36     }
37 
38     const auto& consumer = surfaceHandler->GetConsumer();
39     if (consumer == nullptr) {
40         return;
41     }
42     lowPowerSurfaceNode_.push_back(surfaceNode);
43     sptr<SurfaceBuffer> buffer = nullptr;
44     sptr<SyncFence> acquireFence = SyncFence::InvalidFence();
45     int64_t timestamp = 0;
46     std::vector<Rect> damages;
47     consumer->AcquireBuffer(buffer, acquireFence, timestamp, damages, true);
48     if (buffer == nullptr) {
49         return;
50     }
51     std::shared_ptr<RSSurfaceHandler::SurfaceBufferEntry> surfaceBuffer =
52         std::make_shared<RSSurfaceHandler::SurfaceBufferEntry>();
53     surfaceBuffer->buffer = buffer;
54     surfaceBuffer->acquireFence = acquireFence;
55     surfaceBuffer->timestamp = timestamp;
56     RSBaseRenderUtil::MergeBufferDamages(surfaceBuffer->damageRect, damages);
57     if (surfaceBuffer->damageRect.h <= 0 || surfaceBuffer->damageRect.w <= 0) {
58         RS_LOGW("RsDebug ConsumerLowPowerBuffer(id: %{public}" PRIu64 ") buffer damage is invalid",
59             surfaceHandler->GetNodeId());
60     }
61     surfaceBuffer->damageRect.y =
62         surfaceBuffer->buffer->GetHeight() - surfaceBuffer->damageRect.y - surfaceBuffer->damageRect.h;
63     surfaceHandler->ConsumeAndUpdateBuffer(*surfaceBuffer);
64     RS_TRACE_NAME_FMT("ConsumeAndUpdateLowPowerBuffer node: [%lu]", surfaceHandler->GetNodeId());
65     surfaceBuffer = nullptr;
66 }
67 
JudgeRsDrawLppState(bool needDrawFrame,bool doDirectComposition)68 void LppVideoHandler::JudgeRsDrawLppState(bool needDrawFrame, bool doDirectComposition)
69 {
70     std::lock_guard<std::mutex> lock(mutex_);
71     bool requestVsync = false;
72     for (const auto& surfaceNode : lowPowerSurfaceNode_) {
73         sptr<IConsumerSurface> consumer;
74         if (UNLIKELY(surfaceNode == nullptr) ||
75             surfaceNode->GetAbilityState() == RSSurfaceNodeAbilityState::BACKGROUND ||
76             surfaceNode->GetMutableRSSurfaceHandler() == nullptr ||
77             (consumer = surfaceNode->GetMutableRSSurfaceHandler()->GetConsumer()) == nullptr) {
78             continue;
79         }
80 
81         bool isHardware = !(surfaceNode->IsHardwareForcedDisabled());
82         bool requestNextVsyncForLpp = false;
83         bool isShbDrawLpp = true;
84 
85         if (!needDrawFrame) {
86             // Render nothing to update
87             requestNextVsyncForLpp = true;
88             isShbDrawLpp = false;
89         } else {
90             if (!doDirectComposition && !isHardware) {
91                 // GPU
92                 requestNextVsyncForLpp = true;
93                 isShbDrawLpp = false;
94             }
95             if (doDirectComposition || (!doDirectComposition && isHardware)) {
96                 // Hareware
97                 requestNextVsyncForLpp = false;
98                 isShbDrawLpp = true;
99             }
100         }
101 
102         if (hasVirtualMirrorDisplay_.load()) {
103             // Virtual screen needs to keep Vsync awake
104             RS_TRACE_NAME_FMT("Virtual screen needs to keep Vsync awake");
105             requestNextVsyncForLpp = true;
106         }
107         if (consumer->SetLppDrawSource(isShbDrawLpp, requestNextVsyncForLpp) != GSError::GSERROR_OK) {
108             RS_TRACE_NAME_FMT("Stop By SetLppDrawSource");
109             requestNextVsyncForLpp = false;
110         }
111         requestVsync = requestVsync || requestNextVsyncForLpp;
112     }
113     if (requestVsync) {
114         RSMainThread::Instance()->RequestNextVSync();
115     }
116 }
117 
SetHasVirtualMirrorDisplay(bool hasVirtualMirrorDisplay)118 void LppVideoHandler::SetHasVirtualMirrorDisplay(bool hasVirtualMirrorDisplay)
119 {
120     hasVirtualMirrorDisplay_.store(hasVirtualMirrorDisplay);
121 }
122 
ClearLppSurfaceNode()123 void LppVideoHandler::ClearLppSurfaceNode()
124 {
125     std::lock_guard<std::mutex> lock(mutex_);
126     lowPowerSurfaceNode_.clear();
127 }
128 } // namespace OHOS::Rosen