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_ = Surface::CreateSurfaceAsConsumer("FrameBuffer");
56
57 sptr<IBufferProducer> producer = consumerSurface_->GetProducer();
58 producerSurface_ = Surface::CreateSurfaceAsProducer(producer);
59
60 sptr<IBufferConsumerListener> listener = fbSurface;
61 SurfaceError ret = consumerSurface_->RegisterConsumerListener(listener);
62 if (ret != SURFACE_ERROR_OK) {
63 return SURFACE_ERROR_NO_CONSUMER;
64 }
65
66 return SURFACE_ERROR_OK;
67 }
68
SetBufferQueueSize(uint32_t bufferSize)69 SurfaceError HdiFramebufferSurface::SetBufferQueueSize(uint32_t bufferSize)
70 {
71 SurfaceError ret = consumerSurface_->SetQueueSize(bufferSize);
72 if (ret != SURFACE_ERROR_OK) {
73 HLOGE("fb SetQueueSize failed, ret is %{public}d", ret);
74 return ret;
75 }
76
77 return SURFACE_ERROR_OK;
78 }
79
OnBufferAvailable()80 void HdiFramebufferSurface::OnBufferAvailable()
81 {
82 sptr<SurfaceBuffer> buffer;
83 int64_t timestamp = 0;
84 Rect damage = {0};
85 sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
86 SurfaceError ret = consumerSurface_->AcquireBuffer(buffer, acquireFence,
87 timestamp, damage);
88 if (ret != SURFACE_ERROR_OK || buffer == nullptr) {
89 HLOGE("AcquireBuffer failed, ret is %{public}d", ret);
90 return;
91 }
92
93 std::lock_guard<std::mutex> lock(mutex_);
94 availableBuffers_.push(std::make_unique<FrameBufferEntry>(buffer, acquireFence, timestamp, damage));
95 bufferCond_.notify_one();
96 }
97
GetSurface()98 sptr<OHOS::Surface> HdiFramebufferSurface::GetSurface()
99 {
100 return producerSurface_;
101 }
102
GetFramebuffer()103 std::unique_ptr<FrameBufferEntry> HdiFramebufferSurface::GetFramebuffer()
104 {
105 using namespace std::chrono_literals;
106 std::unique_lock<std::mutex> lock(mutex_);
107 if (availableBuffers_.empty()) {
108 bufferCond_.wait_for(lock, 1000ms, [this]() { return !availableBuffers_.empty(); });
109 }
110 if (availableBuffers_.empty()) {
111 return nullptr;
112 }
113 auto fbEntry = std::move(availableBuffers_.front());
114 availableBuffers_.pop();
115 return fbEntry;
116 }
117
ReleaseFramebuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & releaseFence)118 int32_t HdiFramebufferSurface::ReleaseFramebuffer(
119 sptr<SurfaceBuffer> &buffer, const sptr<SyncFence>& releaseFence)
120 {
121 if (buffer == nullptr) {
122 HLOGI("HdiFramebufferSurface::ReleaseFramebuffer: buffer is null, no need to release.");
123 return 0;
124 }
125
126 SurfaceError ret = consumerSurface_->ReleaseBuffer(buffer, releaseFence);
127 if (ret != SURFACE_ERROR_OK) {
128 HLOGE("ReleaseBuffer failed ret is %{public}d", ret);
129 }
130
131 return ret;
132 }
133
Dump(std::string & result)134 void HdiFramebufferSurface::Dump(std::string &result)
135 {
136 if (consumerSurface_ != nullptr) {
137 consumerSurface_->Dump(result);
138 }
139 }
140 } // namespace Rosen
141 } // namespace OHOS
142