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>
34 #define ANDROID_HC_OR_LATER (ANDROID_API >= 11)
35 #define ANDROID_ICS_OR_LATER (ANDROID_API >= 14)
36 #define ANDROID_JBMR2_OR_LATER (ANDROID_API >= 18)
38 #if ANDROID_ICS_OR_LATER
39 #include <system/window.h>
41 #include <ui/android_native_buffer.h>
42 #include <ui/egl/android_natives.h>
45 #include <hardware/gralloc.h>
47 #include <android/log.h>
50 typedef int32_t status_t;
52 #if !ANDROID_ICS_OR_LATER
53 typedef android_native_buffer_t ANativeWindowBuffer_t;
55 typedef struct native_window_priv native_window_priv;
57 struct native_window_priv
60 gralloc_module_t const* gralloc;
64 #define LOG_TAG "VLC/ANW"
66 #define LOGD(...) __android_log_print( ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__ )
67 #define LOGE(...) __android_log_print( ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__ )
69 #define CHECK_ERR() do {\
70 if( err != NO_ERROR ) {\
71 LOGE( "error %d in %s line %d\n", err, __FUNCTION__, __LINE__ );\
76 #define CHECK_ANB() do {\
77 if( anb->common.magic != ANDROID_NATIVE_BUFFER_MAGIC &&\
78 anb->common.version != sizeof(ANativeWindowBuffer_t) ) {\
79 LOGE( "error, buffer not valid\n" );\
84 static int window_connect( ANativeWindow *anw )
86 #if ANDROID_ICS_OR_LATER
87 return native_window_api_connect( anw, NATIVE_WINDOW_API_MEDIA );
91 static int window_disconnect( ANativeWindow *anw )
93 #if ANDROID_ICS_OR_LATER
94 return native_window_api_disconnect( anw, NATIVE_WINDOW_API_MEDIA );
98 native_window_priv *ANativeWindowPriv_connect( void *window )
100 native_window_priv *priv;
101 hw_module_t const* module;
102 ANativeWindow *anw = (ANativeWindow *)window;
104 if( anw->common.magic != ANDROID_NATIVE_WINDOW_MAGIC &&
105 anw->common.version != sizeof(ANativeWindow) ) {
106 LOGE( "error, window not valid\n" );
110 if ( hw_get_module( GRALLOC_HARDWARE_MODULE_ID,
114 if( window_connect( anw ) != 0 ) {
115 LOGE( "native_window_api_connect FAIL" );
119 priv = calloc( 1, sizeof(native_window_priv) );
122 window_disconnect( anw );
126 priv->gralloc = (gralloc_module_t const *) module;
131 int ANativeWindowPriv_disconnect( native_window_priv *priv )
133 window_disconnect( priv->anw );
139 int ANativeWindowPriv_setup( native_window_priv *priv, int w, int h, int hal_format, bool is_hw, int hw_usage )
143 LOGD( "setup: %p, %d, %d, %X, %X\n",
144 priv->anw, w, h, hal_format, hw_usage );
147 priv->usage = hw_usage | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
149 priv->usage= GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN;
150 #if ANDROID_HC_OR_LATER
151 priv->usage |= GRALLOC_USAGE_EXTERNAL_DISP;
154 err = native_window_set_usage( priv->anw, priv->usage );
157 #if ANDROID_ICS_OR_LATER
158 err = native_window_set_scaling_mode( priv->anw, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW );
161 err = native_window_set_buffers_dimensions( priv->anw, w, h );
164 err = native_window_set_buffers_format( priv->anw, hal_format );
167 err = native_window_set_buffers_geometry( priv->anw, w, h, hal_format );
174 int ANativeWindowPriv_getMinUndequeued( native_window_priv *priv, unsigned int *min_undequeued )
178 #if ANDROID_HC_OR_LATER
179 err = priv->anw->query( priv->anw, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, min_undequeued );
182 /* set a minimum value of min_undequeued in case query fails */
183 if( *min_undequeued == 0 )
186 LOGD( "getMinUndequeued: %p %u", priv->anw, *min_undequeued );
191 int ANativeWindowPriv_getMaxBufferCount( native_window_priv *priv, unsigned int *max_buffer_count )
193 #if ANDROID_ICS_OR_LATER
194 *max_buffer_count = 32;
196 *max_buffer_count = 15;
201 int ANativeWindowPriv_setBufferCount(native_window_priv *priv, unsigned int count )
205 LOGD( "setBufferCount: %p %u", priv->anw, count );
207 err = native_window_set_buffer_count( priv->anw, count );
213 int ANativeWindowPriv_setCrop( native_window_priv *priv, int ofs_x, int ofs_y, int w, int h )
215 android_native_rect_t crop;
219 crop.right = ofs_x + w;
220 crop.bottom = ofs_y + h;
221 return native_window_set_crop( priv->anw, &crop );
224 int ANativeWindowPriv_dequeue( native_window_priv *priv, void **pp_handle )
226 ANativeWindowBuffer_t *anb;
227 status_t err = NO_ERROR;
229 #if ANDROID_JBMR2_OR_LATER
230 err = priv->anw->dequeueBuffer_DEPRECATED( priv->anw, &anb );
232 err = priv->anw->dequeueBuffer( priv->anw, &anb );
241 int ANativeWindowPriv_lock( native_window_priv *priv, void *p_handle )
243 ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
244 status_t err = NO_ERROR;
248 #if ANDROID_JBMR2_OR_LATER
249 err = priv->anw->lockBuffer_DEPRECATED( priv->anw, anb );
251 err = priv->anw->lockBuffer( priv->anw, anb );
258 int ANativeWindowPriv_lockData( native_window_priv *priv, void *p_handle,
259 ANativeWindow_Buffer *p_out_anb )
261 ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
262 status_t err = NO_ERROR;
267 err = priv->gralloc->lock( priv->gralloc, anb->handle, priv->usage,
268 0, 0, anb->width, anb->height, &p_data );
271 p_out_anb->bits = p_data;
272 p_out_anb->width = anb->width;
273 p_out_anb->height = anb->height;
274 p_out_anb->stride = anb->stride;
275 p_out_anb->format = anb->format;
281 int ANativeWindowPriv_unlockData( native_window_priv *priv, void *p_handle )
283 ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
284 status_t err = NO_ERROR;
288 err = priv->gralloc->unlock(priv->gralloc, anb->handle);
294 int ANativeWindowPriv_queue( native_window_priv *priv, void *p_handle )
296 ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
297 status_t err = NO_ERROR;
301 #if ANDROID_JBMR2_OR_LATER
302 err = priv->anw->queueBuffer_DEPRECATED( priv->anw, anb );
304 err = priv->anw->queueBuffer( priv->anw, anb );
311 int ANativeWindowPriv_cancel( native_window_priv *priv, void *p_handle )
313 ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
314 status_t err = NO_ERROR;
318 #if ANDROID_JBMR2_OR_LATER
319 err = priv->anw->cancelBuffer_DEPRECATED( priv->anw, anb );
321 err = priv->anw->cancelBuffer( priv->anw, anb );
328 int ANativeWindowPriv_setOrientation( native_window_priv *priv, int orientation )
330 status_t err = NO_ERROR;
333 switch( orientation )
336 transform = NATIVE_WINDOW_TRANSFORM_ROT_90;
339 transform = NATIVE_WINDOW_TRANSFORM_ROT_180;
342 transform = NATIVE_WINDOW_TRANSFORM_ROT_270;
348 err = native_window_set_buffers_transform( priv->anw, transform );