1 /*
2 * Copyright (c) 2021-2022 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 "native_window.h"
17
18 #include <cstdint>
19 #include <map>
20 #include <cinttypes>
21 #include "buffer_log.h"
22 #include "window.h"
23 #include "surface_type.h"
24 #include "sync_fence.h"
25
26 #ifndef WEAK_ALIAS
27 #define WEAK_ALIAS(old, new) \
28 extern __typeof(old) new __attribute__((__weak__, __alias__(#old)))
29 #endif
30
31 using namespace OHOS;
32
CreateNativeWindowFromSurface(void * pSurface)33 OHNativeWindow* CreateNativeWindowFromSurface(void* pSurface)
34 {
35 if (pSurface == nullptr) {
36 BLOGE("parameter error, please check input parameter");
37 return nullptr;
38 }
39 OHNativeWindow* nativeWindow = new OHNativeWindow();
40 nativeWindow->surface =
41 *reinterpret_cast<OHOS::sptr<OHOS::Surface> *>(pSurface);
42 nativeWindow->config.width = nativeWindow->surface->GetDefaultWidth();
43 nativeWindow->config.height = nativeWindow->surface->GetDefaultHeight();
44 nativeWindow->config.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_MEM_DMA;
45 nativeWindow->config.format = GRAPHIC_PIXEL_FMT_RGBA_8888;
46 nativeWindow->config.strideAlignment = 8; // default stride is 8
47 nativeWindow->config.timeout = 3000; // default timeout is 3000 ms
48 nativeWindow->config.colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
49 nativeWindow->config.transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
50
51 NativeObjectReference(nativeWindow);
52 return nativeWindow;
53 }
54
DestoryNativeWindow(OHNativeWindow * window)55 void DestoryNativeWindow(OHNativeWindow *window)
56 {
57 if (window == nullptr) {
58 BLOGE("parameter error, please check input parameter");
59 return;
60 }
61 // unreference nativewindow object
62 NativeObjectUnreference(window);
63 }
64
CreateNativeWindowBufferFromSurfaceBuffer(void * pSurfaceBuffer)65 OHNativeWindowBuffer* CreateNativeWindowBufferFromSurfaceBuffer(void* pSurfaceBuffer)
66 {
67 if (pSurfaceBuffer == nullptr) {
68 BLOGE("parameter error, please check input parameter");
69 return nullptr;
70 }
71 OHNativeWindowBuffer *nwBuffer = new OHNativeWindowBuffer();
72 nwBuffer->sfbuffer = *reinterpret_cast<OHOS::sptr<OHOS::SurfaceBuffer> *>(pSurfaceBuffer);
73 NativeObjectReference(nwBuffer);
74 return nwBuffer;
75 }
DestroyNativeWindowBuffer(OHNativeWindowBuffer * buffer)76 void DestroyNativeWindowBuffer(OHNativeWindowBuffer* buffer)
77 {
78 if (buffer == nullptr) {
79 BLOGE("parameter error, please check input parameter");
80 return;
81 }
82 NativeObjectUnreference(buffer);
83 }
84
NativeWindowRequestBuffer(OHNativeWindow * window,OHNativeWindowBuffer ** buffer,int * fenceFd)85 int32_t NativeWindowRequestBuffer(OHNativeWindow *window,
86 OHNativeWindowBuffer **buffer, int *fenceFd)
87 {
88 if (window == nullptr || buffer == nullptr || fenceFd == nullptr) {
89 BLOGE("parameter error, please check input parameter");
90 return OHOS::GSERROR_INVALID_ARGUMENTS;
91 }
92 OHOS::sptr<OHOS::SurfaceBuffer> sfbuffer;
93 OHOS::sptr<OHOS::SyncFence> releaseFence = OHOS::SyncFence::INVALID_FENCE;
94 int32_t ret = window->surface->RequestBuffer(sfbuffer, releaseFence, window->config);
95 if (ret != OHOS::GSError::GSERROR_OK || sfbuffer == nullptr) {
96 BLOGE("API failed, please check RequestBuffer function ret:%{public}d, Queue Id:%{public}" PRIu64,
97 ret, window->surface->GetUniqueId());
98 return OHOS::GSERROR_NO_BUFFER;
99 }
100 OHNativeWindowBuffer *nwBuffer = new OHNativeWindowBuffer();
101 nwBuffer->sfbuffer = sfbuffer;
102 nwBuffer->uiTimestamp = window->uiTimestamp;
103 *buffer = nwBuffer;
104 *fenceFd = releaseFence->Dup();
105 return OHOS::GSERROR_OK;
106 }
107
NativeWindowFlushBuffer(OHNativeWindow * window,OHNativeWindowBuffer * buffer,int fenceFd,struct Region region)108 int32_t NativeWindowFlushBuffer(OHNativeWindow *window, OHNativeWindowBuffer *buffer,
109 int fenceFd, struct Region region)
110 {
111 if (window == nullptr || buffer == nullptr || window->surface == nullptr) {
112 BLOGE("parameter error, please check input parameter");
113 return OHOS::GSERROR_INVALID_ARGUMENTS;
114 }
115
116 OHOS::BufferFlushConfigWithDamages config;
117 if ((region.rectNumber != 0) && (region.rects != nullptr)) {
118 config.damages.reserve(region.rectNumber);
119 for (int32_t i = 0; i < region.rectNumber; i++) {
120 OHOS::Rect damage = {
121 .x = region.rects[i].x,
122 .y = region.rects[i].y,
123 .w = static_cast<int32_t>(region.rects[i].w),
124 .h = static_cast<int32_t>(region.rects[i].h),
125 };
126 config.damages.emplace_back(damage);
127 }
128 config.timestamp = buffer->uiTimestamp;
129 } else {
130 config.damages.reserve(1);
131 OHOS::Rect damage = {
132 .x = 0,
133 .y = 0,
134 .w = window->config.width,
135 .h = window->config.height,
136 };
137 config.damages.emplace_back(damage);
138 config.timestamp = buffer->uiTimestamp;
139 }
140 OHOS::sptr<OHOS::SyncFence> acquireFence = new OHOS::SyncFence(fenceFd);
141 window->surface->FlushBuffer(buffer->sfbuffer, acquireFence, config);
142
143 return OHOS::GSERROR_OK;
144 }
145
NativeWindowCancelBuffer(OHNativeWindow * window,OHNativeWindowBuffer * buffer)146 int32_t NativeWindowCancelBuffer(OHNativeWindow *window, OHNativeWindowBuffer *buffer)
147 {
148 if (window == nullptr || buffer == nullptr) {
149 BLOGE("parameter error, please check input parameter");
150 return OHOS::GSERROR_INVALID_ARGUMENTS;
151 }
152
153 window->surface->CancelBuffer(buffer->sfbuffer);
154 return OHOS::GSERROR_OK;
155 }
156
InternalHandleNativeWindowOpt(OHNativeWindow * window,int code,va_list args)157 static int32_t InternalHandleNativeWindowOpt(OHNativeWindow *window, int code, va_list args)
158 {
159 switch (code) {
160 case SET_USAGE: {
161 uint64_t usage = va_arg(args, uint64_t);
162 window->config.usage = usage;
163 break;
164 }
165 case SET_BUFFER_GEOMETRY: {
166 int32_t width = va_arg(args, int32_t);
167 int32_t height = va_arg(args, int32_t);
168 window->config.height = height;
169 window->config.width = width;
170 break;
171 }
172 case SET_FORMAT: {
173 int32_t format = va_arg(args, int32_t);
174 window->config.format = format;
175 break;
176 }
177 case SET_STRIDE: {
178 int32_t stride = va_arg(args, int32_t);
179 window->config.strideAlignment = stride;
180 break;
181 }
182 case SET_TIMEOUT: {
183 int32_t timeout = va_arg(args, int32_t);
184 window->config.timeout = timeout;
185 break;
186 }
187 case SET_COLOR_GAMUT: {
188 int32_t colorGamut = va_arg(args, int32_t);
189 window->config.colorGamut = static_cast<GraphicColorGamut>(colorGamut);
190 break;
191 }
192 case SET_TRANSFORM : {
193 int32_t transform = va_arg(args, int32_t);
194 window->config.transform = static_cast<GraphicTransformType>(transform);
195 break;
196 }
197 case SET_UI_TIMESTAMP : {
198 uint64_t uiTimestamp = va_arg(args, uint64_t);
199 window->uiTimestamp = static_cast<int64_t>(uiTimestamp);
200 break;
201 }
202 case GET_USAGE: {
203 uint64_t *value = va_arg(args, uint64_t*);
204 uint64_t usage = window->config.usage;
205 *value = usage;
206 break;
207 }
208 case GET_BUFFER_GEOMETRY: {
209 int32_t *height = va_arg(args, int32_t*);
210 int32_t *width = va_arg(args, int32_t*);
211 *height = window->config.height;
212 *width = window->config.width;
213 break;
214 }
215 case GET_FORMAT: {
216 int32_t *format = va_arg(args, int32_t*);
217 *format = window->config.format;
218 break;
219 }
220 case GET_STRIDE: {
221 int32_t *stride = va_arg(args, int32_t*);
222 *stride = window->config.strideAlignment;
223 break;
224 }
225 case GET_TIMEOUT : {
226 int32_t *timeout = va_arg(args, int32_t*);
227 *timeout = window->config.timeout;
228 break;
229 }
230 case GET_COLOR_GAMUT: {
231 int32_t *colorGamut = va_arg(args, int32_t*);
232 *colorGamut = static_cast<int32_t>(window->config.colorGamut);
233 break;
234 }
235 case GET_TRANSFORM: {
236 int32_t *transform = va_arg(args, int32_t*);
237 *transform = static_cast<int32_t>(window->config.transform);
238 break;
239 }
240 default:
241 break;
242 }
243 return OHOS::GSERROR_OK;
244 }
245
NativeWindowHandleOpt(OHNativeWindow * window,int code,...)246 int32_t NativeWindowHandleOpt(OHNativeWindow *window, int code, ...)
247 {
248 if (window == nullptr) {
249 BLOGE("parameter error, please check input parameter");
250 return OHOS::GSERROR_INVALID_ARGUMENTS;
251 }
252 va_list args;
253 va_start(args, code);
254 InternalHandleNativeWindowOpt(window, code, args);
255 va_end(args);
256 return OHOS::GSERROR_OK;
257 }
258
GetBufferHandleFromNative(OHNativeWindowBuffer * buffer)259 BufferHandle *GetBufferHandleFromNative(OHNativeWindowBuffer *buffer)
260 {
261 if (buffer == nullptr) {
262 BLOGE("parameter error, please check input parameter");
263 return nullptr;
264 }
265 return buffer->sfbuffer->GetBufferHandle();
266 }
267
GetNativeObjectMagic(void * obj)268 int32_t GetNativeObjectMagic(void *obj)
269 {
270 if (obj == nullptr) {
271 BLOGE("parameter error, please check input parameter");
272 return OHOS::GSERROR_INVALID_ARGUMENTS;
273 }
274 NativeWindowMagic* nativeWindowMagic = reinterpret_cast<NativeWindowMagic *>(obj);
275 return nativeWindowMagic->magic;
276 }
277
NativeObjectReference(void * obj)278 int32_t NativeObjectReference(void *obj)
279 {
280 if (obj == nullptr) {
281 BLOGE("parameter error, please check input parameter");
282 return OHOS::GSERROR_INVALID_ARGUMENTS;
283 }
284 switch (GetNativeObjectMagic(obj)) {
285 case NATIVE_OBJECT_MAGIC_WINDOW:
286 case NATIVE_OBJECT_MAGIC_WINDOW_BUFFER:
287 break;
288 default:
289 return OHOS::GSERROR_TYPE_ERROR;
290 }
291 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(obj);
292 ref->IncStrongRef(ref);
293 return OHOS::GSERROR_OK;
294 }
295
NativeObjectUnreference(void * obj)296 int32_t NativeObjectUnreference(void *obj)
297 {
298 if (obj == nullptr) {
299 BLOGE("parameter error, please check input parameter");
300 return OHOS::GSERROR_INVALID_ARGUMENTS;
301 }
302 switch (GetNativeObjectMagic(obj)) {
303 case NATIVE_OBJECT_MAGIC_WINDOW:
304 case NATIVE_OBJECT_MAGIC_WINDOW_BUFFER:
305 break;
306 default:
307 return OHOS::GSERROR_TYPE_ERROR;
308 }
309 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(obj);
310 ref->DecStrongRef(ref);
311 return OHOS::GSERROR_OK;
312 }
313
NativeWindowSetScalingMode(OHNativeWindow * window,uint32_t sequence,OHScalingMode scalingMode)314 int32_t NativeWindowSetScalingMode(OHNativeWindow *window, uint32_t sequence, OHScalingMode scalingMode)
315 {
316 if (window == nullptr || window->surface == nullptr ||
317 scalingMode < OHScalingMode::OH_SCALING_MODE_FREEZE ||
318 scalingMode > OHScalingMode::OH_SCALING_MODE_NO_SCALE_CROP) {
319 BLOGE("parameter error, please check input parameter");
320 return OHOS::GSERROR_INVALID_ARGUMENTS;
321 }
322 return window->surface->SetScalingMode(sequence, static_cast<ScalingMode>(scalingMode));
323 }
324
NativeWindowSetMetaData(OHNativeWindow * window,uint32_t sequence,int32_t size,const OHHDRMetaData * metaData)325 int32_t NativeWindowSetMetaData(OHNativeWindow *window, uint32_t sequence, int32_t size,
326 const OHHDRMetaData *metaData)
327 {
328 if (window == nullptr || window->surface == nullptr || size <= 0 || metaData == nullptr) {
329 BLOGE("parameter error, please check input parameter");
330 return OHOS::GSERROR_INVALID_ARGUMENTS;
331 }
332
333 std::vector<GraphicHDRMetaData> data(reinterpret_cast<const GraphicHDRMetaData *>(metaData),
334 reinterpret_cast<const GraphicHDRMetaData *>(metaData) + size);
335 return window->surface->SetMetaData(sequence, data);
336 }
337
NativeWindowSetMetaDataSet(OHNativeWindow * window,uint32_t sequence,OHHDRMetadataKey key,int32_t size,const uint8_t * metaData)338 int32_t NativeWindowSetMetaDataSet(OHNativeWindow *window, uint32_t sequence, OHHDRMetadataKey key,
339 int32_t size, const uint8_t *metaData)
340 {
341 if (window == nullptr || window->surface == nullptr ||
342 key < OHHDRMetadataKey::OH_METAKEY_RED_PRIMARY_X || key > OHHDRMetadataKey::OH_METAKEY_HDR_VIVID ||
343 size <= 0 || metaData == nullptr) {
344 BLOGE("parameter error, please check input parameter");
345 return OHOS::GSERROR_INVALID_ARGUMENTS;
346 }
347 std::vector<uint8_t> data(metaData, metaData + size);
348 return window->surface->SetMetaDataSet(sequence, static_cast<GraphicHDRMetadataKey>(key), data);
349 }
350
NativeWindowSetTunnelHandle(OHNativeWindow * window,const OHExtDataHandle * handle)351 int32_t NativeWindowSetTunnelHandle(OHNativeWindow *window, const OHExtDataHandle *handle)
352 {
353 if (window == nullptr || window->surface == nullptr || handle == nullptr) {
354 BLOGE("parameter error, please check input parameter");
355 return OHOS::GSERROR_INVALID_ARGUMENTS;
356 }
357 return window->surface->SetTunnelHandle(reinterpret_cast<const OHOS::GraphicExtDataHandle*>(handle));
358 }
359
NativeWindow()360 NativeWindow::NativeWindow() : NativeWindowMagic(NATIVE_OBJECT_MAGIC_WINDOW), surface(nullptr)
361 {
362 }
363
~NativeWindow()364 NativeWindow::~NativeWindow()
365 {
366 }
367
~NativeWindowBuffer()368 NativeWindowBuffer::~NativeWindowBuffer()
369 {
370 }
371
NativeWindowBuffer()372 NativeWindowBuffer::NativeWindowBuffer() : NativeWindowMagic(NATIVE_OBJECT_MAGIC_WINDOW_BUFFER), sfbuffer(nullptr)
373 {
374 }
375
376 WEAK_ALIAS(CreateNativeWindowFromSurface, OH_NativeWindow_CreateNativeWindow);
377 WEAK_ALIAS(DestoryNativeWindow, OH_NativeWindow_DestroyNativeWindow);
378 WEAK_ALIAS(CreateNativeWindowBufferFromSurfaceBuffer, OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer);
379 WEAK_ALIAS(DestroyNativeWindowBuffer, OH_NativeWindow_DestroyNativeWindowBuffer);
380 WEAK_ALIAS(NativeWindowRequestBuffer, OH_NativeWindow_NativeWindowRequestBuffer);
381 WEAK_ALIAS(NativeWindowFlushBuffer, OH_NativeWindow_NativeWindowFlushBuffer);
382 WEAK_ALIAS(NativeWindowCancelBuffer, OH_NativeWindow_NativeWindowAbortBuffer);
383 WEAK_ALIAS(NativeWindowHandleOpt, OH_NativeWindow_NativeWindowHandleOpt);
384 WEAK_ALIAS(GetBufferHandleFromNative, OH_NativeWindow_GetBufferHandleFromNative);
385 WEAK_ALIAS(NativeObjectReference, OH_NativeWindow_NativeObjectReference);
386 WEAK_ALIAS(NativeObjectUnreference, OH_NativeWindow_NativeObjectUnreference);
387 WEAK_ALIAS(GetNativeObjectMagic, OH_NativeWindow_GetNativeObjectMagic);
388 WEAK_ALIAS(NativeWindowSetScalingMode, OH_NativeWindow_NativeWindowSetScalingMode);
389 WEAK_ALIAS(NativeWindowSetMetaData, OH_NativeWindow_NativeWindowSetMetaData);
390 WEAK_ALIAS(NativeWindowSetMetaDataSet, OH_NativeWindow_NativeWindowSetMetaDataSet);
391 WEAK_ALIAS(NativeWindowSetTunnelHandle, OH_NativeWindow_NativeWindowSetTunnelHandle);
392