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