1 /*****************************************************************************
2 * nativewindowpriv.c: Wrapper to android native window private api
3 *****************************************************************************
4 * Copyright (C) 2011 VLC authors and VideoLAN
6 * Authors: Thomas Guillem <guillem@archos.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
32 #include <android/native_window.h>
35 #include <ui/android_native_buffer.h>
36 #include <ui/egl/android_natives.h>
38 #include <system/window.h>
41 #include <hardware/gralloc.h>
43 #include <android/log.h>
46 typedef int32_t status_t
;
49 typedef android_native_buffer_t ANativeWindowBuffer_t
;
51 typedef struct native_window_priv native_window_priv
;
53 struct native_window_priv
56 gralloc_module_t
const* gralloc
;
60 #define LOG_TAG "VLC/ANW"
62 #define LOGD(...) __android_log_print( ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__ )
63 #define LOGE(...) __android_log_print( ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__ )
65 #define CHECK_ERR() do {\
66 if( err != NO_ERROR ) {\
67 LOGE( "error %d in %s line %d\n", err, __FUNCTION__, __LINE__ );\
72 #define CHECK_ANB() do {\
73 if( anb->common.magic != ANDROID_NATIVE_BUFFER_MAGIC &&\
74 anb->common.version != sizeof(ANativeWindowBuffer_t) ) {\
75 LOGE( "error, buffer not valid\n" );\
80 static int window_connect( ANativeWindow
*anw
)
83 return native_window_api_connect( anw
, NATIVE_WINDOW_API_MEDIA
);
87 static int window_disconnect( ANativeWindow
*anw
)
90 return native_window_api_disconnect( anw
, NATIVE_WINDOW_API_MEDIA
);
94 native_window_priv
*ANativeWindowPriv_connect( void *window
)
96 native_window_priv
*priv
;
97 hw_module_t
const* module
;
98 ANativeWindow
*anw
= (ANativeWindow
*)window
;
100 if( anw
->common
.magic
!= ANDROID_NATIVE_WINDOW_MAGIC
&&
101 anw
->common
.version
!= sizeof(ANativeWindow
) ) {
102 LOGE( "error, window not valid\n" );
106 if ( hw_get_module( GRALLOC_HARDWARE_MODULE_ID
,
110 if( window_connect( anw
) != 0 ) {
111 LOGE( "native_window_api_connect FAIL" );
115 priv
= calloc( 1, sizeof(native_window_priv
) );
118 window_disconnect( anw
);
122 priv
->gralloc
= (gralloc_module_t
const *) module
;
127 int ANativeWindowPriv_disconnect( native_window_priv
*priv
)
129 window_disconnect( priv
->anw
);
135 int ANativeWindowPriv_setup( native_window_priv
*priv
, int w
, int h
, int hal_format
, bool is_hw
, int hw_usage
)
139 LOGD( "setup: %p, %d, %d, %X, %X\n",
140 priv
->anw
, w
, h
, hal_format
, hw_usage
);
143 priv
->usage
= hw_usage
| GRALLOC_USAGE_HW_RENDER
| GRALLOC_USAGE_HW_TEXTURE
;
145 priv
->usage
= GRALLOC_USAGE_SW_READ_NEVER
| GRALLOC_USAGE_SW_WRITE_OFTEN
;
146 #if ANDROID_API >= 11
147 priv
->usage
|= GRALLOC_USAGE_EXTERNAL_DISP
;
150 err
= native_window_set_usage( priv
->anw
, priv
->usage
);
153 #if ANDROID_API <= 13
154 err
= native_window_set_buffers_geometry( priv
->anw
, w
, h
, hal_format
);
157 err
= native_window_set_scaling_mode( priv
->anw
, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW
);
160 err
= native_window_set_buffers_dimensions( priv
->anw
, w
, h
);
163 err
= native_window_set_buffers_format( priv
->anw
, hal_format
);
170 int ANativeWindowPriv_getMinUndequeued( native_window_priv
*priv
, unsigned int *min_undequeued
)
174 #if ANDROID_API >= 11
175 err
= priv
->anw
->query( priv
->anw
, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS
, min_undequeued
);
178 /* set a minimum value of min_undequeued in case query fails */
179 if( *min_undequeued
== 0 )
182 LOGD( "getMinUndequeued: %p %u", priv
->anw
, *min_undequeued
);
187 int ANativeWindowPriv_setBufferCount(native_window_priv
*priv
, unsigned int count
)
191 LOGD( "setBufferCount: %p %u", priv
->anw
, count
);
193 err
= native_window_set_buffer_count( priv
->anw
, count
);
199 int ANativeWindowPriv_setCrop( native_window_priv
*priv
, int ofs_x
, int ofs_y
, int w
, int h
)
201 android_native_rect_t crop
;
205 crop
.right
= ofs_x
+ w
;
206 crop
.bottom
= ofs_y
+ h
;
207 return native_window_set_crop( priv
->anw
, &crop
);
210 int ANativeWindowPriv_dequeue( native_window_priv
*priv
, void **pp_handle
)
212 ANativeWindowBuffer_t
*anb
;
213 status_t err
= NO_ERROR
;
215 #if ANDROID_API >= 18
216 err
= priv
->anw
->dequeueBuffer_DEPRECATED( priv
->anw
, &anb
);
218 err
= priv
->anw
->dequeueBuffer( priv
->anw
, &anb
);
227 int ANativeWindowPriv_lock( native_window_priv
*priv
, void *p_handle
)
229 ANativeWindowBuffer_t
*anb
= (ANativeWindowBuffer_t
*)p_handle
;
230 status_t err
= NO_ERROR
;
234 #if ANDROID_API >= 18
235 err
= priv
->anw
->lockBuffer_DEPRECATED( priv
->anw
, anb
);
237 err
= priv
->anw
->lockBuffer( priv
->anw
, anb
);
244 int ANativeWindowPriv_lockData( native_window_priv
*priv
, void *p_handle
,
245 ANativeWindow_Buffer
*p_out_anb
)
247 ANativeWindowBuffer_t
*anb
= (ANativeWindowBuffer_t
*)p_handle
;
248 status_t err
= NO_ERROR
;
253 err
= priv
->gralloc
->lock( priv
->gralloc
, anb
->handle
, priv
->usage
,
254 0, 0, anb
->width
, anb
->height
, &p_data
);
257 p_out_anb
->bits
= p_data
;
258 p_out_anb
->width
= anb
->width
;
259 p_out_anb
->height
= anb
->height
;
260 p_out_anb
->stride
= anb
->stride
;
261 p_out_anb
->format
= anb
->format
;
267 int ANativeWindowPriv_unlockData( native_window_priv
*priv
, void *p_handle
)
269 ANativeWindowBuffer_t
*anb
= (ANativeWindowBuffer_t
*)p_handle
;
270 status_t err
= NO_ERROR
;
274 err
= priv
->gralloc
->unlock(priv
->gralloc
, anb
->handle
);
280 int ANativeWindowPriv_queue( native_window_priv
*priv
, void *p_handle
)
282 ANativeWindowBuffer_t
*anb
= (ANativeWindowBuffer_t
*)p_handle
;
283 status_t err
= NO_ERROR
;
287 #if ANDROID_API >= 18
288 err
= priv
->anw
->queueBuffer_DEPRECATED( priv
->anw
, anb
);
290 err
= priv
->anw
->queueBuffer( priv
->anw
, anb
);
297 int ANativeWindowPriv_cancel( native_window_priv
*priv
, void *p_handle
)
299 ANativeWindowBuffer_t
*anb
= (ANativeWindowBuffer_t
*)p_handle
;
300 status_t err
= NO_ERROR
;
304 #if ANDROID_API >= 18
305 err
= priv
->anw
->cancelBuffer_DEPRECATED( priv
->anw
, anb
);
307 err
= priv
->anw
->cancelBuffer( priv
->anw
, anb
);
314 int ANativeWindowPriv_setOrientation( native_window_priv
*priv
, int orientation
)
316 status_t err
= NO_ERROR
;
319 switch( orientation
)
322 transform
= NATIVE_WINDOW_TRANSFORM_ROT_90
;
325 transform
= NATIVE_WINDOW_TRANSFORM_ROT_180
;
328 transform
= NATIVE_WINDOW_TRANSFORM_ROT_270
;
334 err
= native_window_set_buffers_transform( priv
->anw
, transform
);