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 "native_window.h"
17
18 #include <map>
19 #include "buffer_log.h"
20 #include "display_type.h"
21 #include "external_window.h"
22 #include "surface_type.h"
23
24 #ifndef weak_alias
25 #define weak_alias(old, new) \
26 extern __typeof(old) new __attribute__((__weak__, __alias__(#old)))
27 #endif
28
29 using namespace OHOS;
30
CreateNativeWindowFromSurface(void * pSuface)31 struct NativeWindow* CreateNativeWindowFromSurface(void* pSuface)
32 {
33 if (pSuface == nullptr) {
34 BLOGD("CreateNativeWindowFromSurface pSuface is nullptr");
35 return nullptr;
36 }
37 NativeWindow* nativeWindow = new NativeWindow();
38 nativeWindow->surface =
39 *reinterpret_cast<OHOS::sptr<OHOS::Surface> *>(pSuface);
40 nativeWindow->config.width = nativeWindow->surface->GetDefaultWidth();
41 nativeWindow->config.height = nativeWindow->surface->GetDefaultHeight();
42 nativeWindow->config.usage = HBM_USE_CPU_READ | HBM_USE_MEM_DMA;
43 nativeWindow->config.format = PIXEL_FMT_RGBA_8888;
44 nativeWindow->config.stride = 8; // default stride is 8
45 nativeWindow->config.timeout = 3000; // default timout is 3000 ms
46 nativeWindow->config.colorGamut = OHOS::SurfaceColorGamut::COLOR_GAMUT_SRGB;
47
48 NativeObjectReference(nativeWindow);
49 return nativeWindow;
50 }
51
DestoryNativeWindow(struct NativeWindow * window)52 void DestoryNativeWindow(struct NativeWindow *window)
53 {
54 if (window == nullptr) {
55 return;
56 }
57 // unreference nativewindow object
58 NativeObjectUnreference(window);
59 }
60
CreateNativeWindowBufferFromSurfaceBuffer(void * pSurfaceBuffer)61 struct NativeWindowBuffer* CreateNativeWindowBufferFromSurfaceBuffer(void* pSurfaceBuffer)
62 {
63 if (pSurfaceBuffer == nullptr) {
64 return nullptr;
65 }
66 NativeWindowBuffer *nwBuffer = new NativeWindowBuffer();
67 nwBuffer->sfbuffer = *reinterpret_cast<OHOS::sptr<OHOS::SurfaceBuffer> *>(pSurfaceBuffer);
68 NativeObjectReference(nwBuffer);
69 return nwBuffer;
70 }
DestoryNativeWindowBuffer(struct NativeWindowBuffer * buffer)71 void DestoryNativeWindowBuffer(struct NativeWindowBuffer* buffer)
72 {
73 if (buffer == nullptr) {
74 return;
75 }
76 NativeObjectUnreference(buffer);
77 }
78
NativeWindowRequestBuffer(struct NativeWindow * window,struct NativeWindowBuffer ** buffer,int * fenceFd)79 int32_t NativeWindowRequestBuffer(struct NativeWindow *window,
80 struct NativeWindowBuffer **buffer, int *fenceFd)
81 {
82 if (window == nullptr || buffer == nullptr || fenceFd == nullptr) {
83 BLOGD("NativeWindowRequestBuffer window or buffer or fenceid is nullptr");
84 return OHOS::GSERROR_INVALID_ARGUMENTS;
85 }
86 BLOGD("NativeWindowRequestBuffer width is %{public}d, height is %{public}d",
87 window->config.width, window->config.height);
88 OHOS::BufferRequestConfig config = {
89 .width = window->config.width,
90 .height = window->config.height,
91 .strideAlignment = window->config.stride,
92 .format = window->config.format,
93 .usage = window->config.usage,
94 .timeout = window->config.timeout,
95 .colorGamut = window->config.colorGamut,
96 };
97 OHOS::sptr<OHOS::SurfaceBuffer> sfbuffer;
98 if (window->surface->RequestBuffer(sfbuffer, *fenceFd, config) != OHOS::GSError::GSERROR_OK ||
99 sfbuffer == nullptr) {
100 *buffer = nullptr;
101 return OHOS::GSERROR_NO_BUFFER;
102 }
103 NativeWindowBuffer *nwBuffer = new NativeWindowBuffer();
104 nwBuffer->sfbuffer = sfbuffer;
105 *buffer = nwBuffer;
106 return OHOS::GSERROR_OK;
107 }
108
NativeWindowFlushBuffer(struct NativeWindow * window,struct NativeWindowBuffer * buffer,int fenceFd,struct Region region)109 int32_t NativeWindowFlushBuffer(struct NativeWindow *window, struct NativeWindowBuffer *buffer,
110 int fenceFd, struct Region region)
111 {
112 if (window == nullptr || buffer == nullptr || window->surface == nullptr) {
113 BLOGD("NativeWindowFlushBuffer window,buffer is nullptr");
114 return OHOS::GSERROR_INVALID_ARGUMENTS;
115 }
116
117 OHOS::BufferFlushConfig config;
118 if ((region.rectNumber != 0) && (region.rects != nullptr)) {
119 config.damage.x = region.rects->x;
120 config.damage.y = region.rects->y;
121 config.damage.w = static_cast<int32_t>(region.rects->w);
122 config.damage.h = static_cast<int32_t>(region.rects->h);
123 config.timestamp = 0;
124 } else {
125 config.damage.x = 0;
126 config.damage.y = 0;
127 config.damage.w = window->config.width;
128 config.damage.h = window->config.height;
129 config.timestamp = 0;
130 }
131
132 BLOGD("NativeWindowFlushBuffer damage w is %{public}d, h is %{public}d, acquire fence: %{public}d",
133 config.damage.w, config.damage.h, fenceFd);
134 window->surface->FlushBuffer(buffer->sfbuffer, fenceFd, config);
135
136 return OHOS::GSERROR_OK;
137 }
138
NativeWindowCancelBuffer(struct NativeWindow * window,struct NativeWindowBuffer * buffer)139 int32_t NativeWindowCancelBuffer(struct NativeWindow *window, struct NativeWindowBuffer *buffer)
140 {
141 if (window == nullptr || buffer == nullptr) {
142 return OHOS::GSERROR_INVALID_ARGUMENTS;
143 }
144 window->surface->CancelBuffer(buffer->sfbuffer);
145
146 return OHOS::GSERROR_OK;
147 }
148
InternalHanleNativeWindowOpt(struct NativeWindow * window,int code,va_list args)149 static int32_t InternalHanleNativeWindowOpt(struct NativeWindow *window, int code, va_list args)
150 {
151 switch (code) {
152 case SET_USAGE: {
153 int32_t usage = va_arg(args, int32_t);
154 window->config.usage = usage;
155 break;
156 }
157 case SET_BUFFER_GEOMETRY: {
158 int32_t width = va_arg(args, int32_t);
159 int32_t height = va_arg(args, int32_t);
160 window->config.height = height;
161 window->config.width = width;
162 break;
163 }
164 case SET_FORMAT: {
165 int32_t format = va_arg(args, int32_t);
166 window->config.format = format;
167 break;
168 }
169 case SET_STRIDE: {
170 int32_t stride = va_arg(args, int32_t);
171 window->config.stride = stride;
172 break;
173 }
174 case SET_COLOR_GAMUT: {
175 int32_t colorGamut = va_arg(args, int32_t);
176 window->config.colorGamut = static_cast<OHOS::SurfaceColorGamut>(colorGamut);
177 break;
178 }
179 case GET_USAGE: {
180 int32_t *value = va_arg(args, int32_t*);
181 int32_t usage = window->config.usage;
182 *value = usage;
183 break;
184 }
185 case GET_BUFFER_GEOMETRY: {
186 int32_t *height = va_arg(args, int32_t*);
187 int32_t *width = va_arg(args, int32_t*);
188 *height = window->config.height;
189 *width = window->config.width;
190 break;
191 }
192 case GET_FORMAT: {
193 int32_t *format = va_arg(args, int32_t*);
194 *format = window->config.format;
195 break;
196 }
197 case GET_STRIDE: {
198 int32_t *stride = va_arg(args, int32_t*);
199 *stride = window->config.stride;
200 break;
201 }
202 case GET_COLOR_GAMUT: {
203 int32_t *colorGamut = va_arg(args, int32_t*);
204 *colorGamut = static_cast<int32_t>(window->config.colorGamut);
205 break;
206 }
207 default:
208 break;
209 }
210 return OHOS::GSERROR_OK;
211 }
212
NativeWindowHandleOpt(struct NativeWindow * window,int code,...)213 int32_t NativeWindowHandleOpt(struct NativeWindow *window, int code, ...)
214 {
215 if (window == nullptr) {
216 return OHOS::GSERROR_INVALID_ARGUMENTS;
217 }
218 va_list args;
219 va_start(args, code);
220 InternalHanleNativeWindowOpt(window, code, args);
221 va_end(args);
222 return OHOS::GSERROR_OK;
223 }
224
GetBufferHandleFromNative(struct NativeWindowBuffer * buffer)225 BufferHandle *GetBufferHandleFromNative(struct NativeWindowBuffer *buffer)
226 {
227 if (buffer == nullptr) {
228 return nullptr;
229 }
230 return buffer->sfbuffer->GetBufferHandle();
231 }
232
GetNativeObjectMagic(void * obj)233 int32_t GetNativeObjectMagic(void *obj)
234 {
235 if (obj == nullptr) {
236 return OHOS::GSERROR_INVALID_ARGUMENTS;
237 }
238 NativeWindowMagic* nativeWindowMagic = reinterpret_cast<NativeWindowMagic *>(obj);
239 return nativeWindowMagic->magic;
240 }
241
NativeObjectReference(void * obj)242 int32_t NativeObjectReference(void *obj)
243 {
244 if (obj == nullptr) {
245 return OHOS::GSERROR_INVALID_ARGUMENTS;
246 }
247 switch (GetNativeObjectMagic(obj)) {
248 case NATIVE_OBJECT_MAGIC_WINDOW:
249 case NATIVE_OBJECT_MAGIC_WINDOW_BUFFER:
250 break;
251 default:
252 return OHOS::GSERROR_TYPE_ERROR;
253 }
254 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(obj);
255 ref->IncStrongRef(ref);
256 return OHOS::GSERROR_OK;
257 }
258
NativeObjectUnreference(void * obj)259 int32_t NativeObjectUnreference(void *obj)
260 {
261 if (obj == nullptr) {
262 return OHOS::GSERROR_INVALID_ARGUMENTS;
263 }
264 switch (GetNativeObjectMagic(obj)) {
265 case NATIVE_OBJECT_MAGIC_WINDOW:
266 case NATIVE_OBJECT_MAGIC_WINDOW_BUFFER:
267 break;
268 default:
269 return OHOS::GSERROR_TYPE_ERROR;
270 }
271 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(obj);
272 ref->DecStrongRef(ref);
273 return OHOS::GSERROR_OK;
274 }
275
NativeWindow()276 NativeWindow::NativeWindow() : NativeWindowMagic(NATIVE_OBJECT_MAGIC_WINDOW)
277 {
278 }
279
~NativeWindow()280 NativeWindow::~NativeWindow()
281 {
282 }
283
~NativeWindowBuffer()284 NativeWindowBuffer::~NativeWindowBuffer()
285 {
286 }
287
NativeWindowBuffer()288 NativeWindowBuffer::NativeWindowBuffer() : NativeWindowMagic(NATIVE_OBJECT_MAGIC_WINDOW_BUFFER)
289 {
290 }
291
292 weak_alias(CreateNativeWindowFromSurface, OH_NativeWindow_CreateNativeWindow);
293 weak_alias(DestoryNativeWindow, OH_NativeWindow_DestroyNativeWindow);
294 weak_alias(CreateNativeWindowBufferFromSurfaceBuffer, OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer);
295 weak_alias(DestoryNativeWindowBuffer, OH_NativeWindow_DestroyNativeWindowBuffer);
296 weak_alias(NativeWindowRequestBuffer, OH_NativeWindow_NativeWindowRequestBuffer);
297 weak_alias(NativeWindowFlushBuffer, OH_NativeWindow_NativeWindowFlushBuffer);
298 weak_alias(NativeWindowCancelBuffer, OH_NativeWindow_NativeWindowAbortBuffer);
299 weak_alias(NativeWindowHandleOpt, OH_NativeWindow_NativeWindowHandleOpt);
300 weak_alias(GetBufferHandleFromNative, OH_NativeWindow_GetBufferHandleFromNative);
301 weak_alias(NativeObjectReference, OH_NativeWindow_NativeObjectReference);
302 weak_alias(NativeObjectUnreference, OH_NativeWindow_NativeObjectUnreference);
303 weak_alias(GetNativeObjectMagic, OH_NativeWindow_GetNativeObjectMagic);
304