1 /*
2  * Copyright (c) 2023 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 "surface_adapter_impl.h"
17 
18 #include <unordered_map>
19 
20 #include "drivers/peripheral/display/interfaces/include/display_type.h"
21 #include "nweb_log.h"
22 
23 namespace OHOS::NWeb {
24 namespace {
IsSupportFormat(int32_t format)25 bool IsSupportFormat(int32_t format)
26 {
27     switch (format) {
28         case PixelFormat::PIXEL_FMT_RGBA_8888:
29         case PixelFormat::PIXEL_FMT_YCBCR_420_SP:
30             return true;
31         default:
32             return false;
33     }
34 }
35 } // namespace
36 
SurfaceBufferAdapterImpl(sptr<SurfaceBuffer> buffer)37 SurfaceBufferAdapterImpl::SurfaceBufferAdapterImpl(sptr<SurfaceBuffer> buffer) : buffer_(buffer) {}
38 
GetFileDescriptor()39 int32_t SurfaceBufferAdapterImpl::GetFileDescriptor()
40 {
41     if (!buffer_) {
42         WVLOG_E("buffer_ is nullptr");
43         return -1;
44     }
45     return buffer_->GetFileDescriptor();
46 }
47 
GetWidth()48 int32_t SurfaceBufferAdapterImpl::GetWidth()
49 {
50     if (!buffer_) {
51         WVLOG_E("buffer_ is nullptr");
52         return -1;
53     }
54     return buffer_->GetWidth();
55 }
56 
GetHeight()57 int32_t SurfaceBufferAdapterImpl::GetHeight()
58 {
59     if (!buffer_) {
60         WVLOG_E("buffer_ is nullptr");
61         return -1;
62     }
63     return buffer_->GetHeight();
64 }
65 
GetStride()66 int32_t SurfaceBufferAdapterImpl::GetStride()
67 {
68     if (!buffer_) {
69         WVLOG_E("buffer_ is nullptr");
70         return -1;
71     }
72     return buffer_->GetStride();
73 }
74 
GetFormat()75 int32_t SurfaceBufferAdapterImpl::GetFormat()
76 {
77     if (!buffer_) {
78         WVLOG_E("buffer_ is nullptr");
79         return -1;
80     }
81     return buffer_->GetFormat();
82 }
83 
GetSize()84 uint32_t SurfaceBufferAdapterImpl::GetSize()
85 {
86     if (!buffer_) {
87         WVLOG_E("buffer_ is nullptr");
88         return 0;
89     }
90     return buffer_->GetSize();
91 }
92 
GetVirAddr()93 void* SurfaceBufferAdapterImpl::GetVirAddr()
94 {
95     if (!buffer_) {
96         WVLOG_E("buffer_ is nullptr");
97         return nullptr;
98     }
99     return buffer_->GetVirAddr();
100 }
101 
GetBuffer()102 sptr<SurfaceBuffer>& SurfaceBufferAdapterImpl::GetBuffer()
103 {
104     return buffer_;
105 }
106 
BufferConsumerListenerImpl(wptr<IConsumerSurface> surface,std::shared_ptr<IBufferConsumerListenerAdapter> listener)107 BufferConsumerListenerImpl::BufferConsumerListenerImpl(
108     wptr<IConsumerSurface> surface, std::shared_ptr<IBufferConsumerListenerAdapter> listener)
109     : cSurface_(surface), listener_(std::move(listener))
110 {}
111 
OnBufferAvailable()112 void BufferConsumerListenerImpl::OnBufferAvailable()
113 {
114     if (cSurface_ == nullptr || listener_ == nullptr) {
115         WVLOG_E("cSurface_ or listener_ is nullptr");
116         return;
117     }
118     auto surfaceTemp = cSurface_.promote();
119     if (surfaceTemp == nullptr) {
120         WVLOG_E("surface is nullptr");
121         return;
122     }
123     sptr<SurfaceBuffer> buffer;
124     int32_t fence;
125     int64_t timestamp;
126     Rect damage;
127     GSError ret = surfaceTemp->AcquireBuffer(buffer, fence, timestamp, damage);
128     if (ret != (int32_t)GSERROR_OK) {
129         WVLOG_E("acquire buffer failed, ret=%{public}d", ret);
130         return;
131     }
132     int32_t format = buffer->GetFormat();
133     if (!IsSupportFormat(format)) {
134         WVLOG_E("unsupport format for:%{public}d", format);
135         surfaceTemp->ReleaseBuffer(buffer, -1);
136         return;
137     }
138     auto bufferAdapter = std::make_shared<SurfaceBufferAdapterImpl>(buffer);
139     listener_->OnBufferAvailable(std::move(bufferAdapter));
140 }
141 
ConsumerSurfaceAdapterImpl()142 ConsumerSurfaceAdapterImpl::ConsumerSurfaceAdapterImpl() : cSurface_(IConsumerSurface::Create()) {}
143 
RegisterConsumerListener(std::shared_ptr<IBufferConsumerListenerAdapter> listenerAdapter)144 int32_t ConsumerSurfaceAdapterImpl::RegisterConsumerListener(
145     std::shared_ptr<IBufferConsumerListenerAdapter> listenerAdapter)
146 {
147     if (!cSurface_ || !listenerAdapter) {
148         WVLOG_E("cSurface_ or listener_ is nullptr");
149         return -1;
150     }
151     sptr<IBufferConsumerListener> listener =
152         new (std::nothrow) BufferConsumerListenerImpl(cSurface_, std::move(listenerAdapter));
153     if (!listener) {
154         WVLOG_E("listener create failed");
155         return -1;
156     }
157     return cSurface_->RegisterConsumerListener(listener);
158 }
159 
ReleaseBuffer(std::shared_ptr<SurfaceBufferAdapter> bufferAdapter,int32_t fence)160 int32_t ConsumerSurfaceAdapterImpl::ReleaseBuffer(std::shared_ptr<SurfaceBufferAdapter> bufferAdapter, int32_t fence)
161 {
162     if (!cSurface_ || !bufferAdapter) {
163         WVLOG_E("cSurface_ or bufferAdapter is nullptr");
164         return -1;
165     }
166     auto bufferImpl = static_cast<SurfaceBufferAdapterImpl*>(bufferAdapter.get());
167     return cSurface_->ReleaseBuffer(bufferImpl->GetBuffer(), fence);
168 }
169 
SetUserData(const std::string & key,const std::string & val)170 int32_t ConsumerSurfaceAdapterImpl::SetUserData(const std::string& key, const std::string& val)
171 {
172     if (!cSurface_) {
173         WVLOG_E("cSurface_ is nullptr");
174         return -1;
175     }
176     return cSurface_->SetUserData(key, val);
177 }
178 
SetQueueSize(uint32_t queueSize)179 int32_t ConsumerSurfaceAdapterImpl::SetQueueSize(uint32_t queueSize)
180 {
181     if (!cSurface_) {
182         WVLOG_E("cSurface_ is nullptr");
183         return -1;
184     }
185     return cSurface_->SetQueueSize(queueSize);
186 }
187 
GetConsumerSurface()188 sptr<IConsumerSurface>& ConsumerSurfaceAdapterImpl::GetConsumerSurface()
189 {
190     return cSurface_;
191 }
192 
193 const std::unordered_map<TransformTypeAdapter, GraphicTransformType> TO_TRANSFORM_TYPE_MAP = {
194     { TransformTypeAdapter::ROTATE_NONE, GraphicTransformType::GRAPHIC_ROTATE_NONE },
195     { TransformTypeAdapter::ROTATE_90, GraphicTransformType::GRAPHIC_ROTATE_90 },
196     { TransformTypeAdapter::ROTATE_180, GraphicTransformType::GRAPHIC_ROTATE_180 },
197     { TransformTypeAdapter::ROTATE_270, GraphicTransformType::GRAPHIC_ROTATE_270 },
198     { TransformTypeAdapter::FLIP_H, GraphicTransformType::GRAPHIC_FLIP_H },
199     { TransformTypeAdapter::FLIP_V, GraphicTransformType::GRAPHIC_FLIP_V },
200     { TransformTypeAdapter::FLIP_H_ROT90, GraphicTransformType::GRAPHIC_FLIP_H_ROT90 },
201     { TransformTypeAdapter::FLIP_V_ROT90, GraphicTransformType::GRAPHIC_FLIP_V_ROT90 },
202     { TransformTypeAdapter::FLIP_H_ROT180, GraphicTransformType::GRAPHIC_FLIP_H_ROT180 },
203     { TransformTypeAdapter::FLIP_V_ROT180, GraphicTransformType::GRAPHIC_FLIP_V_ROT180 },
204     { TransformTypeAdapter::FLIP_H_ROT270, GraphicTransformType::GRAPHIC_FLIP_H_ROT270 },
205     { TransformTypeAdapter::FLIP_V_ROT270, GraphicTransformType::GRAPHIC_FLIP_V_ROT270 },
206     { TransformTypeAdapter::ROTATE_BUTT, GraphicTransformType::GRAPHIC_ROTATE_BUTT },
207 };
208 
209 const std::unordered_map<ColorGamutAdapter, GraphicColorGamut> TO_GRAPHIC_COLOR_GAMUT_MAP = {
210     { ColorGamutAdapter::INVALID, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_INVALID },
211     { ColorGamutAdapter::NATIVE, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_NATIVE },
212     { ColorGamutAdapter::STANDARD_BT601, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_STANDARD_BT601 },
213     { ColorGamutAdapter::STANDARD_BT709, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_STANDARD_BT709 },
214     { ColorGamutAdapter::DCI_P3, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DCI_P3 },
215     { ColorGamutAdapter::SRGB, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB },
216     { ColorGamutAdapter::ADOBE_RGB, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_ADOBE_RGB },
217     { ColorGamutAdapter::DISPLAY_P3, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DISPLAY_P3 },
218     { ColorGamutAdapter::BT2020, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_BT2020 },
219     { ColorGamutAdapter::BT2100_PQ, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_BT2100_PQ },
220     { ColorGamutAdapter::BT2100_HLG, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_BT2100_HLG },
221     { ColorGamutAdapter::DISPLAY_BT2020, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DISPLAY_BT2020 },
222 };
223 
ProducerSurfaceAdapterImpl(sptr<Surface> surface)224 ProducerSurfaceAdapterImpl::ProducerSurfaceAdapterImpl(sptr<Surface> surface) : surface_(surface) {}
225 
TransToTransformType(const TransformTypeAdapter & type)226 GraphicTransformType ProducerSurfaceAdapterImpl::TransToTransformType(const TransformTypeAdapter& type)
227 {
228     auto item = TO_TRANSFORM_TYPE_MAP.find(type);
229     if (item == TO_TRANSFORM_TYPE_MAP.end()) {
230         WVLOG_E("to graphic transform type %{public}d not found", type);
231         return GraphicTransformType::GRAPHIC_ROTATE_NONE;
232     }
233     return item->second;
234 }
235 
TransToGraphicColorGamut(const ColorGamutAdapter & colorGamut)236 GraphicColorGamut ProducerSurfaceAdapterImpl::TransToGraphicColorGamut(const ColorGamutAdapter& colorGamut)
237 {
238     auto item = TO_GRAPHIC_COLOR_GAMUT_MAP.find(colorGamut);
239     if (item == TO_GRAPHIC_COLOR_GAMUT_MAP.end()) {
240         WVLOG_E("to graphic color gamut %{public}d not found", colorGamut);
241         return GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
242     }
243     return item->second;
244 }
245 
TransToBufferConfig(const std::shared_ptr<BufferRequestConfigAdapter> configAdapter,BufferRequestConfig & config)246 void ProducerSurfaceAdapterImpl::TransToBufferConfig(
247     const std::shared_ptr<BufferRequestConfigAdapter> configAdapter, BufferRequestConfig& config)
248 {
249     if (!configAdapter) {
250         WVLOG_E("TransToBufferConfig configAdapter is null");
251         return;
252     }
253 
254     config.width = configAdapter->GetWidth();
255     config.height = configAdapter->GetHeight();
256     config.strideAlignment = configAdapter->GetStrideAlignment();
257     config.format = GRAPHIC_PIXEL_FMT_YCBCR_420_P;
258     config.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA;
259     config.timeout = configAdapter->GetTimeout();
260     config.colorGamut = TransToGraphicColorGamut(configAdapter->GetColorGamut());
261     config.transform = TransToTransformType(configAdapter->GetTransformType());
262 }
263 
RequestBuffer(int32_t & fence,std::shared_ptr<BufferRequestConfigAdapter> configAdapter)264 std::shared_ptr<SurfaceBufferAdapter> ProducerSurfaceAdapterImpl::RequestBuffer(
265     int32_t& fence, std::shared_ptr<BufferRequestConfigAdapter> configAdapter)
266 {
267     if (!surface_) {
268         WVLOG_E("Surface_ is nullptr when request");
269         return nullptr;
270     }
271 
272     if (!configAdapter) {
273         WVLOG_E("configAdapter is nullptr when request");
274         return nullptr;
275     }
276 
277     OHOS::sptr<OHOS::SurfaceBuffer> buffer = nullptr;
278     BufferRequestConfig config;
279     TransToBufferConfig(configAdapter, config);
280     surface_->RequestBuffer(buffer, fence, config);
281     return std::make_shared<SurfaceBufferAdapterImpl>(buffer);
282 }
283 
FlushBuffer(std::shared_ptr<SurfaceBufferAdapter> bufferAdapter,int32_t fence,std::shared_ptr<BufferFlushConfigAdapter> flushConfigAdapter)284 int32_t ProducerSurfaceAdapterImpl::FlushBuffer(std::shared_ptr<SurfaceBufferAdapter> bufferAdapter, int32_t fence,
285     std::shared_ptr<BufferFlushConfigAdapter> flushConfigAdapter)
286 {
287     if (!surface_ || !bufferAdapter || !flushConfigAdapter) {
288         WVLOG_E("Surface_ or params is nullptr when flush");
289         return -1;
290     }
291     auto bufferImpl = static_cast<SurfaceBufferAdapterImpl*>(bufferAdapter.get());
292     BufferFlushConfig config;
293     config.damage.x = flushConfigAdapter->GetX();
294     config.damage.y = flushConfigAdapter->GetY();
295     config.damage.w = flushConfigAdapter->GetW();
296     config.damage.h = flushConfigAdapter->GetH();
297     config.timestamp = flushConfigAdapter->GetTimestamp();
298     return surface_->FlushBuffer(bufferImpl->GetBuffer(), fence, config);
299 }
300 } // namespace OHOS::NWeb
301