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