Apply N buffering
authorSung-jae Park <nicesj.park@samsung.com>
Tue, 28 Oct 2014 05:34:42 +0000 (14:34 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Tue, 28 Oct 2014 06:04:08 +0000 (15:04 +0900)
[model] Redwood,Kiran,B3(Wearable)
[binary_type] AP
[customer] Docomo/Orange/ATT/Open
[issue#] N/A
[problem]
[cause]
[solution]
[team] HomeTF
[request]
[horizontal_expansion]

Change-Id: I779a652d058896bdfd742ed2e4826214e90e710e

include/dynamicbox.h
src/dynamicbox.c
src/snapshot_window.c
src/virtual_window.c

index d0e97e9..7668a6d 100644 (file)
@@ -157,7 +157,7 @@ typedef void (*dynamicbox_flush_cb)(void *snapshot_window, const char *id, int s
  * @param[in] id Dynamic Box Instance Id
  * @param[in] gbar 1 for Glance Bar or 0
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return Handle of desc instance
  * @pre Should be loaded by data-provider-slave.
  * @post Should be destroyed(flushed) using dynamicbox_desc_close() API.
@@ -172,7 +172,7 @@ extern dynamicbox_desc_h dynamicbox_desc_open(const char *id, int gbar);
  * @remarks Must be used only by Inhouse Dynamic Box.
  * @param[in] handle Handle which is created by dynamicbox_desc_open() function
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return int type
  * @retval #DBOX_STATUS_ERROR_NONE If the flushing description data is successfully done
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER If the given handle is not valid
@@ -274,7 +274,7 @@ extern int dynamicbox_desc_del_block(dynamicbox_desc_h handle, int idx);
  * @param[in] id Instance Id
  * @param[in] gbar 1 if this object is created for Glance Bar or 0 (for Dynamic Box)
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return void* Object type
  * @retval Address Valid evas object
  * @retval @c NULL failed to create
@@ -459,7 +459,7 @@ extern int dynamicbox_content_is_updated(const char *id, int gbar);
  * @param[in] handler Event handling callback
  * @param[in] data User data for event handling callback
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return Buffer handle
  * @retval @c NULL Failed to acquire buffer
  * @retval handler Handle object
@@ -467,7 +467,27 @@ extern int dynamicbox_content_is_updated(const char *id, int gbar);
  * @post Allocated buffer object must be released via dynamicbox_release_buffer().
  * @see dynamicbox_release_buffer()
  */
-extern dynamicbox_buffer_h dynamicbox_acquire_buffer(const char *id, int gbar, int width, int height, int pixels, int auto_align, int (*handler)(dynamicbox_buffer_h, dynamicbox_buffer_event_data_t, void *), void *data);
+extern dynamicbox_buffer_h dynamicbox_create_buffer(const char *id, int gbar, int auto_align, int (*handler)(dynamicbox_buffer_h, dynamicbox_buffer_event_data_t, void *), void *data);
+
+/**
+ * @internal
+ * @brief Acquire a buffer for GBar or DBox.
+ * @since_tizen 2.3
+ * @param[in] handle
+ * @param[in] width
+ * @param[in] height
+ * @param[in] pixels
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
+ * @return int status
+ * @retval #DBOX_STATUS_ERROR_NONE Successfully allocated
+ * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred
+ * @pre dynamicbox_create_buffer() must be called
+ * @see dynamicbox_create_buffer()
+ * @see dynamicbox_release_buffer()
+ */
+extern int dynamicbox_acquire_buffer(dynamicbox_buffer_h handle, int width, int height, int pixels);
 
 /**
  * @internal
@@ -490,8 +510,8 @@ extern unsigned int dynamicbox_resource_id(dynamicbox_buffer_h handle);
  * @since_tizen 2.3
  * @param[in] handle Buffer handle
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
- * @return int type
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
+ * @return int status
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument
  * @retval #DBOX_STATUS_ERROR_NONE Successfully released
  * @pre Handle must be created using dynamicbox_acquire_buffer().
@@ -501,12 +521,66 @@ extern int dynamicbox_release_buffer(dynamicbox_buffer_h handle);
 
 /**
  * @internal
+ * @brief Destroy a buffer of dynamicbox
+ * @since_tizen 2.3
+ * @param[in] handle buffer handle
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
+ * @return int status
+ * @retval #DBOX_STATUS_ERROR_INVALID_PARAMTER Invalid argument
+ * @retval #DBOX_STATUS_ERROR_NONE Successfully destroyed
+ * @see dynamicbox_create_buffer()
+ */
+extern int dynamicbox_destroy_buffer(dynamicbox_buffer_h handle);
+
+/**
+ * @internal
+ * @brief Acquire an extra buffer for dynamicbox
+ * @since_tizen 2.3
+ * @param[in] handle buffer handle
+ * @param[in] idx index of extra buffer. max index is limited to dynamicbox configuration.
+ * @return unsigned int resource id
+ * @retval positive Reousrce Id
+ * @retval 0 Error
+ * @see dynamicbox_create_buffer()
+ * @see dynamicbox_acquire_buffer()
+ */
+extern unsigned int dynamicbox_acquire_extra_buffer(dynamicbox_buffer_h handle, int idx);
+
+/**
+ * @internal
+ * @brief Get the resource id of given index
+ * @since_tizen 2.3
+ * @param[in] handle buffer handle
+ * @param[in] idx index of extra buffer
+ * @return unsigned int resource id
+ * @retval positive resource id
+ * @retval 0 Error
+ */
+extern unsigned int dynamicbox_extra_buffer_resource_id(dynamicbox_buffer_h handle, int idx);
+
+/**
+ * @internal
+ * @brief Release the extra buffer of given index
+ * @since_tizen 2.3
+ * @param[in] handle buffer handle
+ * @param[in] idx index of extra buffer
+ * @return int status
+ * @retval DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval DBOX_STATUS_ERROR_NONE Successfully released
+ * @retval DBOX_STATUS_ERROR_FAULT Unrecoverable error
+ * @retval DBOX_STATUS_ERROR_DISABLED Extra buffer is not supported.
+ */
+extern int dynamicbox_release_extra_buffer(dynamicbox_buffer_h handle, int idx);
+
+/**
+ * @internal
  * @brief Gets the address of buffer for S/W rendering.
  * @details If you try to use this, after dynamicbox_create_hw_buffer(), you will get @c NULL.
  * @since_tizen 2.3
  * @param[in] handle Buffer handle
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return void* address of the render buffer
  * @retval @c NULL If it falis to get buffer address
  * @retval address If it succeed to get the buffer address
@@ -520,7 +594,7 @@ extern void *dynamicbox_ref_buffer(dynamicbox_buffer_h handle);
  * @since_tizen 2.3
  * @param[in] buffer Address of render buffer
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return int type
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid handle
  * @retval #DBOX_STATUS_ERROR_NONE Successfully unreference
@@ -536,7 +610,7 @@ extern int dynamicbox_unref_buffer(void *buffer);
  * @since_tizen 2.3
  * @param[in] handle Buffer handle
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return int type
  * @retval #DBOX_STATUS_ERROR_NONE Successfully sync'd
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument
@@ -550,7 +624,7 @@ extern int dynamicbox_sync_buffer(dynamicbox_buffer_h handle);
  * @since_tizen 2.3
  * @param[in] id Instance Id which is passed to you via the first parameter of every dynamicbox_XXXX interface functions
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return If succes returns 0 or return less than 0
  * @retval #DBOX_STATUS_ERROR_NONE Successfully triggered
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument
@@ -577,7 +651,7 @@ extern int dynamicbox_support_hw_buffer(dynamicbox_buffer_h handle);
  * @since_tizen 2.3
  * @param[in] handle Buffer handle
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return int type
  * @retval #DBOX_STATUS_ERROR_ALREADY H/W buffer is already created
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument
@@ -594,7 +668,7 @@ extern int dynamicbox_create_hw_buffer(dynamicbox_buffer_h handle);
  * @since_tizen 2.3
  * @param[in] handle Buffer handle
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return int type
  * @retval #DBOX_STATUS_ERROR_NONE Successfully destroyed
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument
@@ -609,7 +683,7 @@ extern int dynamicbox_destroy_hw_buffer(dynamicbox_buffer_h handle);
  * @since_tizen 2.3
  * @param[in] handle Buffer handle
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return void* type
  * @retval @c NULL Failed to get H/W accelerated buffer address
  * @retval addr H/W accelerated buffer address
@@ -637,7 +711,7 @@ extern int dynamicbox_buffer_stride(dynamicbox_buffer_h handle);
  * @since_tizen 2.3
  * @param[in] handle Buffer handle
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return int type
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid handle
  * @retval #DBOX_STATUS_ERROR_NONE Successfully done
@@ -653,7 +727,7 @@ extern int dynamicbox_buffer_pre_render(dynamicbox_buffer_h handle);
  * @since_tizen 2.3
  * @param[in] handle Buffer handle
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return If succes returns 0 or return less than 0
  * @retval #DBOX_STATUS_ERROR_NONE If succeed
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument
@@ -672,7 +746,7 @@ extern int dynamicbox_buffer_post_render(dynamicbox_buffer_h handle);
  * @param[in] id Instance Id which is passed to you via the first parameter of every dynamicbox_XXXX interface functions
  * @param[in] reason DBOX_STATUS_ERROR_NONE(0)
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return int type
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid parameters
  * @retval #DBOX_STATUS_ERROR_OUT_OF_MEMORY Out of memory
@@ -692,7 +766,7 @@ extern int dynamicbox_request_close_glance_bar(const char *dboxid, const char *i
  * @param[in] dboxid Dynamic Box Package Id
  * @param[in] id Instance Id which is passed to you via the first parameter of every dynamicbox_XXXX interface functions
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return int type
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid parameters
  * @retval #DBOX_STATUS_ERROR_OUT_OF_MEMORY Out of memory
@@ -713,7 +787,7 @@ extern int dynamicbox_freeze_scroller(const char *dboxid, const char *id);
  * @param[in] dboxid Dynamic Box Package Id
  * @param[in] id Instance Id which is passed to you via the first parameter of every dynamicbox_XXXX interface functions
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return int type
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid parameters
  * @retval #DBOX_STATUS_ERROR_OUT_OF_MEMORY Out of memory
@@ -735,7 +809,7 @@ extern int dynamicbox_thaw_scroller(const char *dboxid, const char *id);
  * @param[in] id
  * @param[in] size_type
  * @privlevel public
- * @privilege %http://tizen.org/privilege/core/dynamicbox.provider
+ * @privilege %http://tizen.org/privilege/core/dynamicbox
  * @return void* window
  * @retval #NULL failed to create a snapshot window
  * @retval elm_win window object
index cb33253..704717c 100644 (file)
@@ -28,6 +28,7 @@
 #include <dynamicbox_service.h>
 #include <dynamicbox_provider.h>
 #include <dynamicbox_provider_buffer.h>
+#include <dynamicbox_conf.h>
 #include <Evas.h>
 
 #include "debug.h"
@@ -628,68 +629,122 @@ PUBLIC int dynamicbox_desc_del_block(struct dynamicbox_desc *handle, int idx)
        return DBOX_STATUS_ERROR_NOT_EXIST;
 }
 
-PUBLIC dynamicbox_buffer_h dynamicbox_acquire_buffer(const char *filename, int is_gbar, int width, int height, int pixels, int auto_align, int (*handler)(dynamicbox_buffer_h , dynamicbox_buffer_event_data_t, void *), void *data)
+PUBLIC unsigned int dynamicbox_acquire_extra_buffer(dynamicbox_buffer_h handle, int idx)
 {
-       struct dynamicbox_buffer_data *user_data;
-       const char *pkgname;
-       dynamicbox_buffer_h handle;
-       char *uri;
+    int w;
+    int h;
+    int pixel_size;
+    unsigned int pixmap;
+
+    if (!handle) {
+       ErrPrint("Invalid handle\n");
+       return 0u;
+    }
+
+    if (dynamicbox_provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
+       ErrPrint("Failed to get buffer size\n");
+       return 0u;
+    }
+
+    if (dynamicbox_provider_buffer_extra_acquire(handle, idx, w, h, pixel_size) < 0) {
+       ErrPrint("Failed to acquire extra buffer\n");
+       return 0u;
+    }
+
+    pixmap = dynamicbox_provider_buffer_extra_resource_id(handle, idx);
+    if (pixmap == 0u) {
+       ErrPrint("Failed to get resource id\n");
+       dynamicbox_provider_buffer_extra_release(handle, idx);
+    }
+
+    return pixmap;
+}
 
-       if (!filename || !width || !height) {
-               ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
-               return NULL;
-       }
+PUBLIC unsigned int dynamicbox_extra_buffer_resource_id(dynamicbox_buffer_h handle, int idx)
+{
+    if (!handle || idx < 0 || idx > DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT) {
+       return DBOX_STATUS_ERROR_INVALID_PARAMETER;
+    }
 
-       user_data = calloc(1, sizeof(*user_data));
-       if (!user_data) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               return NULL;
-       }
+    return dynamicbox_provider_buffer_extra_resource_id(handle, idx);
+}
 
-       user_data->is_gbar = is_gbar;
-       user_data->handler = handler ? handler : default_event_handler;
-       user_data->cbdata = data;
+PUBLIC int dynamicbox_release_extra_buffer(dynamicbox_buffer_h handle, int idx)
+{
+    if (!handle || idx < 0 || idx > DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT) {
+       return DBOX_STATUS_ERROR_INVALID_PARAMETER;
+    }
 
-       uri = id_to_uri(filename);
-       if (!uri) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               free(user_data);
-               return NULL;
-       }
+    DbgPrint("Release resource: %u\n", dynamicbox_provider_buffer_extra_resource_id(handle, idx));
 
-       if (!s_info.find_pkgname) {
-               s_info.find_pkgname = dlsym(RTLD_DEFAULT, FUNC_DYNAMICBOX_FIND_PKGNAME);
-               if (!s_info.find_pkgname) {
-                       ErrPrint("Failed to find a \"dynamicbox_find_pkgname\"\n");
-                       free(user_data);
-                       free(uri);
-                       return NULL;
-               }
-       }
+    return dynamicbox_provider_buffer_extra_release(handle, idx);
+}
 
-       pkgname = s_info.find_pkgname(uri);
-       if (!pkgname) {
-               ErrPrint("Invalid Request\n");
-               free(user_data);
-               free(uri);
-               return NULL;
-       }
+PUBLIC int dynamicbox_acquire_buffer(dynamicbox_buffer_h handle, int width, int height, int pixel_size)
+{
+    if (!handle || width <= 0 || height <= 0 || pixel_size <= 0) {
+       return DBOX_STATUS_ERROR_INVALID_PARAMETER;
+    }
 
-       handle = dynamicbox_provider_buffer_create((!!is_gbar) ? DBOX_TYPE_GBAR : DBOX_TYPE_DBOX, pkgname, uri, auto_align, event_handler_wrapper, user_data);
-       free(uri);
-       if (!handle) {
-               free(user_data);
-               return NULL;
-       }
+    return dynamicbox_provider_buffer_acquire(handle, width, height, pixel_size);
+}
 
-       if (dynamicbox_provider_buffer_acquire(handle, width, height, pixels) < 0) {
-               dynamicbox_provider_buffer_destroy(handle);
-               free(user_data);
-               return NULL;
+PUBLIC dynamicbox_buffer_h dynamicbox_create_buffer(const char *filename, int is_gbar, int auto_align, int (*handler)(dynamicbox_buffer_h , dynamicbox_buffer_event_data_t, void *), void *data)
+{
+    struct dynamicbox_buffer_data *user_data;
+    const char *pkgname;
+    dynamicbox_buffer_h handle;
+    char *uri;
+
+    if (!filename) {
+       ErrPrint("Invalid argument: %p(%dx%d)\n", filename);
+       return NULL;
+    }
+
+    user_data = calloc(1, sizeof(*user_data));
+    if (!user_data) {
+       ErrPrint("Heap: %s\n", strerror(errno));
+       return NULL;
+    }
+
+    user_data->is_gbar = is_gbar;
+    user_data->handler = handler ? handler : default_event_handler;
+    user_data->cbdata = data;
+
+    uri = id_to_uri(filename);
+    if (!uri) {
+       ErrPrint("Heap: %s\n", strerror(errno));
+       free(user_data);
+       return NULL;
+    }
+
+    if (!s_info.find_pkgname) {
+       s_info.find_pkgname = dlsym(RTLD_DEFAULT, FUNC_DYNAMICBOX_FIND_PKGNAME);
+       if (!s_info.find_pkgname) {
+           ErrPrint("Failed to find a \"dynamicbox_find_pkgname\"\n");
+           free(user_data);
+           free(uri);
+           return NULL;
        }
+    }
 
-       (void)dynamicbox_provider_buffer_set_user_data(handle, user_data);
-       return handle;
+    pkgname = s_info.find_pkgname(uri);
+    if (!pkgname) {
+       ErrPrint("Invalid Request\n");
+       free(user_data);
+       free(uri);
+       return NULL;
+    }
+
+    handle = dynamicbox_provider_buffer_create((!!is_gbar) ? DBOX_TYPE_GBAR : DBOX_TYPE_DBOX, pkgname, uri, auto_align, event_handler_wrapper, user_data);
+    free(uri);
+    if (!handle) {
+       free(user_data);
+       return NULL;
+    }
+
+    (void)dynamicbox_provider_buffer_set_user_data(handle, user_data);
+    return handle;
 }
 
 PUBLIC int dynamicbox_request_update(const char *filename)
@@ -729,6 +784,12 @@ PUBLIC unsigned int dynamicbox_resource_id(dynamicbox_buffer_h handle)
 
 PUBLIC int dynamicbox_release_buffer(dynamicbox_buffer_h handle)
 {
+       DbgPrint("Release buffer\n");
+       return dynamicbox_provider_buffer_release(handle);
+}
+
+PUBLIC int dynamicbox_destroy_buffer(dynamicbox_buffer_h handle)
+{
        struct dynamicbox_buffer_data *user_data;
 
        if (!handle) {
@@ -745,11 +806,8 @@ PUBLIC int dynamicbox_release_buffer(dynamicbox_buffer_h handle)
                dynamicbox_provider_buffer_set_user_data(handle, NULL);
        }
 
-       (void)dynamicbox_provider_buffer_release(handle);
-       (void)dynamicbox_provider_buffer_destroy(handle);
-
-       DbgPrint("Release buffer\n");
-       return 0;
+       DbgPrint("Destroy buffer\n");
+       return dynamicbox_provider_buffer_destroy(handle);
 }
 
 PUBLIC void *dynamicbox_ref_buffer(dynamicbox_buffer_h handle)
index 3b7ad24..a950ea8 100644 (file)
@@ -114,7 +114,7 @@ static inline int destroy_virtual_canvas(Evas *e)
 
 
 
-static inline int flush_to_file(void *canvas, const char *filename, int w, int h)
+static inline int flush_to_file(const void *canvas, const char *filename, int w, int h)
 {
        int status;
        Evas *shot_e;
@@ -255,7 +255,7 @@ static Eina_Bool direct_snapshot_cb(void *data)
 {
        Evas *e;
        Ecore_Evas *ee;
-       void *canvas;
+       const void *canvas;
        int status;
        int w;
        int h;
index 4f482ff..0d1080d 100644 (file)
@@ -22,6 +22,7 @@
 #include <Ecore_X.h>
 #include <Evas.h>
 #include <dlfcn.h>
+#include <Eina.h>
 
 #include <X11/Xlib.h>
 
 #include <dynamicbox_errno.h>
 #include <dynamicbox_service.h>
 #include <dynamicbox_conf.h>
+#include <dynamicbox_buffer.h>
 
 #include "dynamicbox.h"
 #include "debug.h"
 
-#define IS_PD 1
+#define IS_GBAR 1
 
 #define PUBLIC __attribute__((visibility("default")))
 #define DBOX_WIN_TAG "dynamic,box,win"
 
+#define DBOX_DEFAULT_WIDTH 1
+#define DBOX_DEFAULT_HEIGHT 1
+#define GL_ENGINE "opengl_x11"
+
 static struct static_info {
-       Ecore_Evas *(*alloc_canvas)(int w, int h, void *(*a)(void *data, int size), void (*f)(void *data, void *ptr), void *data);
-       Ecore_Evas *(*alloc_canvas_with_stride)(int w, int h, void *(*a)(void *data, int size, int *stride, int *bpp), void (*f)(void *data, void *ptr), void *data);
+    Ecore_Evas *(*alloc_canvas)(int w, int h, void *(*a)(void *data, int size), void (*f)(void *data, void *ptr), void *data);
+    Ecore_Evas *(*alloc_canvas_with_stride)(int w, int h, void *(*a)(void *data, int size, int *stride, int *bpp), void (*f)(void *data, void *ptr), void *data);
+    Ecore_Evas *(*alloc_canvas_with_pixmap)(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h, Ecore_X_Pixmap (*alloc_cb)(void *data, Ecore_X_Window parent, int w, int h, int *depth), void (*free_cb)(void *data, Ecore_X_Pixmap pixmap), void *data);
 } s_info = {
-       .alloc_canvas = NULL,
-       .alloc_canvas_with_stride = NULL,
+    .alloc_canvas = NULL,
+    .alloc_canvas_with_stride = NULL,
+    .alloc_canvas_with_pixmap = NULL,
 };
 
 /**
  * @brief
  * Abstracted Data Type of Virtual Window
  */
-struct info {
-       char *id; /**< Identification */
-       struct dynamicbox_buffer *handle; /**< Livebox buffer handle */
-       int is_hw; /**< 1 if a buffer is created on the H/W accelerated place or 0 */
-       Ecore_Evas *ee;
-       Evas *e;
-       int is_gbar;
-       int deleted;
-       int w;
-       int h;
-};
+typedef struct virtual_window_info {
+    char *id; /**< Identification */
+    dynamicbox_buffer_h handle; /**< Livebox buffer handle */
+    int is_hw; /**< 1 if a buffer is created on the H/W accelerated place or 0 */
+    Ecore_Evas *ee;
+    Evas *e;
+    int is_gbar;
+    int deleted;
+    int w;
+    int h;
+    unsigned int *resource_array;
+    int resource_cnt;
+} *vwin_info_t;
 
 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
 {
@@ -77,9 +87,9 @@ static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
  * @note
  * Every user event (mouse) on the buffer will be passed via this event callback
  */
-static int event_handler_cb(struct dynamicbox_buffer *handler, struct dynamicbox_buffer_event_data *event_info, void *data)
+static int event_handler_cb(dynamicbox_buffer_h handler, struct dynamicbox_buffer_event_data *event_info, void *data)
 {
-       struct info *info = data;
+       vwin_info_t info = data;
        Elm_Access_Action_Info action_info;
        Elm_Access_Action_Type action_type;
        int ret = 0;
@@ -486,47 +496,163 @@ static int event_handler_cb(struct dynamicbox_buffer *handler, struct dynamicbox
        return ret;
 }
 
-static void *alloc_fb(void *data, int size)
+/**
+ * @note
+ * This callback can be called twice (or more) to get a several pixmaps
+ * Acquired pixmaps are used for double/tripple buffering for canvas
+ */
+static Ecore_X_Pixmap alloc_pixmap_cb(void *data, Ecore_X_Window parent, int w, int h, int *depth)
 {
-       struct info *info = data;
-       void *buffer;
+    vwin_info_t info = data;
+    Ecore_X_Pixmap pixmap;
 
-       if (info->ee) {
-               ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
-               DbgPrint("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
-       }
+    if (!info->handle) {
+       ErrPrint("Invalid handle\n");
+       return 0u;
+    }
 
-       /**
-        * Acquire a buffer for canvas.
-        */
-       info->handle = dynamicbox_acquire_buffer(info->id, info->is_gbar,
-                                       info->w, info->h, sizeof(int), (dynamicbox_conf_auto_align() || !s_info.alloc_canvas_with_stride),
-                                       event_handler_cb, info);
+    info->w = w;
+    info->h = h;
+    DbgPrint("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
 
+    if (dynamicbox_resource_id(info->handle) == 0u) {
        /**
-        * If it supports the H/W accelerated buffer,
-        * Use it.
+        * @note
+        * Need to allocate a primary buffer
         */
-       if (dynamicbox_support_hw_buffer(info->handle)) {
-               if (dynamicbox_create_hw_buffer(info->handle) == 0) {
-                       buffer = dynamicbox_buffer_hw_buffer(info->handle);
-                       if (buffer) {
-                               DbgPrint("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
-                               info->is_hw = 1;
-                               return buffer;
-                       }
+       dynamicbox_acquire_buffer(info->handle, info->w, info->h, sizeof(int));
+       if (!info->handle) {
+           ErrPrint("Failed to get the buffer\n");
+           return 0u;
+       }
+
+       pixmap = (Ecore_X_Pixmap)dynamicbox_resource_id(info->handle);
+    } else if (DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT > 0) {
+       int idx;
+
+       if (!info->resource_array) {
+           info->resource_array = calloc(sizeof(*info->resource_array), DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT);
+           if (!info->resource_array) {
+               ErrPrint("Out of memory: %s\n", strerror(errno));
+               return 0u;
+           }
+
+           idx = 0;
+       } else {
+           for (idx = 0; idx < DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT; idx++) {
+               if (info->resource_array[idx] == 0u) {
+                   break;
                }
+           }
 
-               ErrPrint("Failed to allocate HW Accelerated buffer\n");
+           if (idx == DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT) {
+               ErrPrint("Out of index: %d\n", idx);
+               return 0u;
+           }
        }
 
-       /**
-        * Or use the buffer of a S/W backend.
-        */
-       buffer = dynamicbox_ref_buffer(info->handle);
-       DbgPrint("SW buffer is created (%dx%d)\n", info->w, info->h);
-       info->is_hw = 0;
-       return buffer;
+       info->resource_array[idx] = dynamicbox_acquire_extra_buffer(info->handle, idx);
+       if (info->resource_array[idx] == 0u) {
+           ErrPrint("Failed to allocate pixmap\n");
+       }
+
+        DbgPrint("Allocated index: %d (%d) - %u\n", idx, DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT, info->resource_array[idx]);
+       pixmap = info->resource_array[idx];
+    }
+
+    /**
+     * Acquire a buffer for canvas.
+     */
+    info->is_hw = 0;
+    info->resource_cnt += !!pixmap;
+    return pixmap;
+}
+
+static void free_pixmap_cb(void *data, Ecore_X_Pixmap pixmap)
+{
+    vwin_info_t info = data;
+
+    if (!info->handle) {
+       return;
+    }
+
+    if (info->is_hw) {
+       ErrPrint("Impossible\n");
+    }
+
+    if (dynamicbox_resource_id(info->handle) == pixmap) {
+       if (dynamicbox_release_buffer(info->handle) < 0) {
+           DbgPrint("Failed to release buffer\n");
+       }
+       info->resource_cnt--;
+    } else {
+       int idx;
+
+       for (idx = 0; idx < DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT; idx++) {
+           if (info->resource_array[idx] == pixmap) {
+               if (dynamicbox_release_extra_buffer(info->handle, idx) < 0) {
+                   DbgPrint("Failed to release buffer\n");
+               }
+               info->resource_cnt--;
+               break;
+           }
+       }
+    }
+
+    if (info->deleted && info->resource_cnt == 0) {
+       DbgPrint("Destroy buffer handle\n");
+
+       dynamicbox_destroy_buffer(info->handle);
+       free(info->resource_array);
+       free(info->id);
+       free(info);
+    }
+}
+
+static void *alloc_fb(void *data, int size)
+{
+    vwin_info_t info = data;
+    void *buffer;
+
+    if (info->ee) {
+       ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
+       DbgPrint("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
+    }
+
+    if (!info->handle) {
+       ErrPrint("Failed to create a buffer\n");
+       return NULL;
+    }
+
+    if (dynamicbox_acquire_buffer(info->handle, info->w, info->h, sizeof(int)) < 0) {
+       ErrPrint("Failed to acquire buffer\n");
+       return NULL;
+    }
+
+    /**
+     * If it supports the H/W accelerated buffer,
+     * Use it.
+     */
+    if (dynamicbox_support_hw_buffer(info->handle)) {
+       if (dynamicbox_create_hw_buffer(info->handle) == 0) {
+           buffer = dynamicbox_buffer_hw_buffer(info->handle);
+           if (buffer) {
+               DbgPrint("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
+               info->is_hw = 1;
+               return buffer;
+           }
+       }
+
+       ErrPrint("Failed to allocate HW Accelerated buffer\n");
+    }
+
+    /**
+     * Or use the buffer of a S/W backend.
+     */
+    buffer = dynamicbox_ref_buffer(info->handle);
+    DbgPrint("SW buffer is created (%dx%d)\n", info->w, info->h);
+    info->is_hw = 0;
+    return buffer;
 }
 
 static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
@@ -535,7 +661,7 @@ static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
 
        buffer = alloc_fb(data, size);
        if (buffer) {
-               struct info *info = data;
+               vwin_info_t info = data;
                int _stride;
 
                *bpp = sizeof(int);
@@ -554,35 +680,36 @@ static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
 
 static void free_fb(void *data, void *ptr)
 {
-       struct info *info = data;
+    vwin_info_t info = data;
 
-       if (!info->handle) {
-               return;
-       }
+    if (!info->handle) {
+       return;
+    }
 
-       if (info->is_hw) {
-               if (dynamicbox_destroy_hw_buffer(info->handle) == 0) {
-                       DbgPrint("HW Accelerated buffer is destroyed\n");
-               }
-       } else {
-               DbgPrint("SW buffer is destroyed, %p\n", info);
-               dynamicbox_unref_buffer(ptr);
-       }
-
-       dynamicbox_release_buffer(info->handle);
-       info->handle = NULL;
-
-       if (info->deleted) {
-               free(info->id);
-               info->id = NULL;
-
-               free(info);
+    if (info->is_hw) {
+       if (dynamicbox_destroy_hw_buffer(info->handle) == 0) {
+           DbgPrint("HW Accelerated buffer is destroyed\n");
        }
+    } else {
+       DbgPrint("SW buffer is destroyed, %p\n", info);
+       dynamicbox_unref_buffer(ptr);
+    }
+
+    if (dynamicbox_release_buffer(info->handle) < 0) {
+       ErrPrint("Failed to release buffer\n");
+    }
+
+    if (info->deleted) {
+       dynamicbox_destroy_buffer(info->handle);
+       free(info->resource_array);
+       free(info->id);
+       free(info);
+    }
 }
 
 static void pre_render_cb(void *data, Evas *e, void *event_info)
 {
-       struct info *info = data;
+       vwin_info_t info = data;
 
        if (!info->handle) {
                return;
@@ -603,7 +730,7 @@ static void pre_render_cb(void *data, Evas *e, void *event_info)
 
 static void post_render_cb(void *data, Evas *e, void *event_info)
 {
-       struct info *info = data;
+       vwin_info_t info = data;
 
        if (!info->handle) {
                return;
@@ -633,7 +760,7 @@ static void post_render_cb(void *data, Evas *e, void *event_info)
 
 static void ecore_evas_free_cb(Ecore_Evas *ee)
 {
-       struct info *info;
+       vwin_info_t info;
 
        info = ecore_evas_data_get(ee, "dynamic,box,info");
        if (!info) {
@@ -652,95 +779,134 @@ static void ecore_evas_free_cb(Ecore_Evas *ee)
 
 PUBLIC void *dynamicbox_get_evas_object(const char *id, int is_gbar)
 {
-       struct info *info;
-       Evas_Object *rect;
-
-       if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride) {
-               s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
-               if (!s_info.alloc_canvas_with_stride) {
-                       DbgPrint("allocfunc_with_stirde_new is not found\n");
-               }
-
-               s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
-               if (!s_info.alloc_canvas) {
-                       ErrPrint("allocfunc_new is not found\n");
-               }
-
-               if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas) {
-                       ErrPrint("No way to allocate canvas\n");
-                       return NULL;
-               }
+    vwin_info_t info;
+    Evas_Object *rect;
+    const char *engine;
+
+    if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride && !s_info.alloc_canvas_with_pixmap) {
+       s_info.alloc_canvas_with_pixmap = dlsym(RTLD_DEFAULT, "ecore_evas_gl_x11_pixmap_allocfunc_new");
+       if (!s_info.alloc_canvas_with_pixmap) {
+           DbgPrint("pixmap_allocfunc_new is not found\n");
        }
 
-       if (!id) {
-               ErrPrint("Invalid parameter\n");
-               return NULL;
+       s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
+       if (!s_info.alloc_canvas_with_stride) {
+           DbgPrint("allocfunc_with_stirde_new is not found\n");
        }
 
-       info = calloc(1, sizeof(*info));
-       if (!info) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               return NULL;
+       s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
+       if (!s_info.alloc_canvas) {
+           ErrPrint("allocfunc_new is not found\n");
        }
 
-       info->id = strdup(id);
-       if (!info->id) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               free(info);
-               return NULL;
+       if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas && !s_info.alloc_canvas_with_pixmap) {
+           ErrPrint("No way to allocate canvas\n");
+           return NULL;
        }
+    }
+
+    if (!id) {
+       ErrPrint("Invalid parameter\n");
+       return NULL;
+    }
+
+    info = calloc(1, sizeof(*info));
+    if (!info) {
+       ErrPrint("Heap: %s\n", strerror(errno));
+       return NULL;
+    }
+
+    info->id = strdup(id);
+    if (!info->id) {
+       ErrPrint("Heap: %s\n", strerror(errno));
+       free(info);
+       return NULL;
+    }
+
+    info->is_gbar = is_gbar;
+
+    /**
+     * Acquire a buffer for canvas.
+     */
+    info->handle = dynamicbox_create_buffer(info->id, info->is_gbar,
+           (dynamicbox_conf_auto_align() || !s_info.alloc_canvas_with_stride),
+           event_handler_cb, info);
+
+    if (!info->handle) {
+       ErrPrint("Failed to create a dynamicbox buffer\n");
+       free(info->id);
+       free(info);
+       return NULL;
+    }
+
+    /**
+     * Size information must be initialized before call the ecore_evas_buffer_new.
+     */
+    info->w = DBOX_DEFAULT_WIDTH;
+    info->h = DBOX_DEFAULT_HEIGHT;
+
+    engine = elm_config_preferred_engine_get();
+    DbgPrint("Preferred engine: %s (%s)\n", engine, GL_ENGINE);
+    if (engine && !strcmp(engine, GL_ENGINE)) {
+       if (s_info.alloc_canvas_with_pixmap) {
+           info->ee = s_info.alloc_canvas_with_pixmap(NULL, 0u, 0, 0, info->w, info->h, alloc_pixmap_cb, free_pixmap_cb, info);
+           if (!info->ee) {
+               ErrPrint("Unable to create a ee for pixmap\n");
+           }
+       }
+    }
 
-       info->is_gbar = is_gbar;
-
-       /**
-        * Size information must be initialized before call the ecore_evas_buffer_new.
-        */
-       info->w = 1;
-       info->h = 1;
-
+    if (!info->ee) {
        if (!dynamicbox_conf_auto_align() && s_info.alloc_canvas_with_stride) {
-               info->ee = s_info.alloc_canvas_with_stride(1, 1, alloc_stride_fb, free_fb, info);
+           info->ee = s_info.alloc_canvas_with_stride(info->w, info->h, alloc_stride_fb, free_fb, info);
        } else if (s_info.alloc_canvas) {
-               info->ee = s_info.alloc_canvas(1, 1, alloc_fb, free_fb, info);
-       }
-
-       if (!info->ee) {
-               ErrPrint("Failed to create ecore_evas (%dx%d)\n", 1, 1);
-               free(info->id);
-               free(info);
-               return NULL;
+           info->ee = s_info.alloc_canvas(info->w, info->h, alloc_fb, free_fb, info);
        }
-
-       ecore_evas_data_set(info->ee, "dynamic,box,info", info);
-       ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
-
-       info->e = ecore_evas_get(info->ee);
-       if (!info->e) {
-               ErrPrint("Failed to get evas\n");
-               ecore_evas_free(info->ee);
-               return NULL;
-       }
-
-       pre_render_cb(info, NULL, NULL);
-       ecore_evas_alpha_set(info->ee, EINA_TRUE);
-       post_render_cb(info, NULL, NULL);
-
-       ecore_evas_manual_render_set(info->ee, EINA_FALSE);
-       ecore_evas_resize(info->ee, 1, 1);
-
-       evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
-       evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
-
-       rect = evas_object_rectangle_add(info->e);
-       if (!rect) {
-               ErrPrint("Failed to create evas_object\n");
-               ecore_evas_free(info->ee);
-               return NULL;
-       }
-
-       evas_object_resize(rect, 1, 1);
-       evas_object_color_set(rect, 0, 0, 0, 0);
-       return rect;
+    }
+
+    if (!info->ee) {
+       ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
+       dynamicbox_destroy_buffer(info->handle);
+       free(info->id);
+       free(info);
+       return NULL;
+    }
+
+    ecore_evas_data_set(info->ee, "dynamic,box,info", info);
+
+    /**
+     * @note
+     * Free callback must be prepared before use the ecore_evas_free()
+     */
+    ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
+
+    info->e = ecore_evas_get(info->ee);
+    if (!info->e) {
+       ErrPrint("Failed to get evas\n");
+       ecore_evas_free(info->ee);
+       return NULL;
+    }
+
+    pre_render_cb(info, NULL, NULL);
+    ecore_evas_alpha_set(info->ee, EINA_TRUE);
+    post_render_cb(info, NULL, NULL);
+
+    ecore_evas_manual_render_set(info->ee, EINA_FALSE);
+    ecore_evas_resize(info->ee, info->w, info->h);
+
+    evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
+    evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
+
+    rect = evas_object_rectangle_add(info->e);
+    if (!rect) {
+       ErrPrint("Failed to create evas_object\n");
+       ecore_evas_free(info->ee);
+       return NULL;
+    }
+
+    evas_object_resize(rect, info->w, info->h);
+    evas_object_color_set(rect, 0, 0, 0, 0);
+    return rect;
 }
 
 /* End of a file */