1 /*
2  * Copyright (c) 2021 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 "hdi_framebuffer_surface.h"
17 
18 #include "hdi_log.h"
19 #include "sync_fence.h"
20 
21 using namespace OHOS;
22 
23 namespace OHOS {
24 namespace Rosen {
25 
HdiFramebufferSurface()26 HdiFramebufferSurface::HdiFramebufferSurface()
27 {
28 }
29 
~HdiFramebufferSurface()30 HdiFramebufferSurface::~HdiFramebufferSurface() noexcept
31 {
32 }
33 
CreateFramebufferSurface()34 sptr<HdiFramebufferSurface> HdiFramebufferSurface::CreateFramebufferSurface()
35 {
36     sptr<HdiFramebufferSurface> fbSurface = new HdiFramebufferSurface();
37 
38     SurfaceError ret = fbSurface->CreateSurface(fbSurface);
39     if (ret != SURFACE_ERROR_OK) {
40         HLOGE("FramebufferSurface CreateSurface failed, ret is %{public}d", ret);
41         return nullptr;
42     }
43 
44     ret = fbSurface->SetBufferQueueSize(MAX_BUFFER_SIZE);
45     if (ret != SURFACE_ERROR_OK) {
46         HLOGE("FramebufferSurface SetBufferQueueSize failed, ret is %{public}d", ret);
47         return nullptr;
48     }
49 
50     return fbSurface;
51 }
52 
CreateSurface(sptr<HdiFramebufferSurface> & fbSurface)53 SurfaceError HdiFramebufferSurface::CreateSurface(sptr<HdiFramebufferSurface> &fbSurface)
54 {
55     consumerSurface_ = IConsumerSurface::Create("FrameBuffer");
56     if (consumerSurface_ == nullptr) {
57         return SURFACE_ERROR_NO_CONSUMER;
58     }
59 
60     sptr<IBufferProducer> producer = consumerSurface_->GetProducer();
61     producerSurface_ = Surface::CreateSurfaceAsProducer(producer);
62 
63     sptr<IBufferConsumerListener> listener = fbSurface;
64     SurfaceError ret = consumerSurface_->RegisterConsumerListener(listener);
65     if (ret != SURFACE_ERROR_OK) {
66         return SURFACE_ERROR_NO_CONSUMER;
67     }
68 
69     return SURFACE_ERROR_OK;
70 }
71 
SetBufferQueueSize(uint32_t bufferSize)72 SurfaceError HdiFramebufferSurface::SetBufferQueueSize(uint32_t bufferSize)
73 {
74     if (consumerSurface_ == nullptr) {
75         return SURFACE_ERROR_NO_CONSUMER;
76     }
77     SurfaceError ret = consumerSurface_->SetQueueSize(bufferSize);
78     if (ret != SURFACE_ERROR_OK) {
79         HLOGE("fb SetQueueSize failed, ret is %{public}d", ret);
80         return ret;
81     }
82 
83     return SURFACE_ERROR_OK;
84 }
85 
GetBufferQueueSize()86 uint32_t HdiFramebufferSurface::GetBufferQueueSize()
87 {
88     if (consumerSurface_ == nullptr) {
89         HLOGE("consumer surface is nullptr.");
90         return 0;
91     }
92     return consumerSurface_->GetQueueSize();
93 }
94 
OnBufferAvailable()95 void HdiFramebufferSurface::OnBufferAvailable()
96 {
97     if (consumerSurface_ == nullptr) {
98         return;
99     }
100     sptr<SurfaceBuffer> buffer = nullptr;
101     int64_t timestamp = 0;
102     Rect damage = {0};
103     sptr<SyncFence> acquireFence = SyncFence::InvalidFence();
104     SurfaceError ret = consumerSurface_->AcquireBuffer(buffer, acquireFence,
105                                                        timestamp, damage);
106     if (ret != SURFACE_ERROR_OK || buffer == nullptr) {
107         HLOGE("AcquireBuffer failed, ret is %{public}d", ret);
108         return;
109     }
110 
111     std::lock_guard<std::mutex> lock(mutex_);
112     availableBuffers_.push(std::make_unique<FrameBufferEntry>(buffer, acquireFence, timestamp, damage));
113     bufferCond_.notify_one();
114 }
115 
GetSurface()116 sptr<OHOS::Surface> HdiFramebufferSurface::GetSurface()
117 {
118     return producerSurface_;
119 }
120 
GetFramebuffer()121 std::unique_ptr<FrameBufferEntry> HdiFramebufferSurface::GetFramebuffer()
122 {
123     using namespace std::chrono_literals;
124     std::unique_lock<std::mutex> lock(mutex_);
125     if (availableBuffers_.empty()) {
126         bufferCond_.wait_for(lock, 1000ms, [this]() { return !availableBuffers_.empty(); });
127     }
128     if (availableBuffers_.empty()) {
129         return nullptr;
130     }
131     auto fbEntry = std::move(availableBuffers_.front());
132     availableBuffers_.pop();
133     return fbEntry;
134 }
135 
ReleaseFramebuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & releaseFence)136 int32_t HdiFramebufferSurface::ReleaseFramebuffer(
137     sptr<SurfaceBuffer> &buffer, const sptr<SyncFence>& releaseFence)
138 {
139     if (buffer == nullptr || consumerSurface_ == nullptr) {
140         HLOGI("HdiFramebufferSurface::ReleaseFramebuffer:"
141             " buffer or consumerSurface_ is null, no need to release.");
142         return 0;
143     }
144 
145     SurfaceError ret = consumerSurface_->ReleaseBuffer(buffer, releaseFence);
146     if (ret != SURFACE_ERROR_OK) {
147         HLOGE("ReleaseBuffer failed ret is %{public}d", ret);
148     }
149 
150     return ret;
151 }
152 
ClearFrameBuffer()153 void HdiFramebufferSurface::ClearFrameBuffer()
154 {
155     std::unique_lock<std::mutex> lock(mutex_);
156     while (!availableBuffers_.empty()) {
157         availableBuffers_.pop();
158     }
159 }
160 
Dump(std::string & result)161 void HdiFramebufferSurface::Dump(std::string &result)
162 {
163     if (consumerSurface_ != nullptr) {
164         consumerSurface_->Dump(result);
165     }
166 }
167 } // namespace Rosen
168 } // namespace OHOS
169