#include "evas_common_private.h"
#include "evas_private.h"
#ifdef EVAS_CSERVE2
-# include "evas_cs2_private.h"
+#include "evas_cs2_private.h"
#endif
-
#include "evas_engine.h"
-#include "../software_generic/evas_native_common.h"
+#include "evas_native_common.h"
+#include <tbm_surface.h>
#ifdef HAVE_DLSYM
# include <dlfcn.h>
/* evas function tables - filled in later (func and parent func) */
static Evas_Func func, pfunc;
-Evas_Native_Tbm_Surface_Image_Set_Call glsym_evas_native_tbm_surface_image_set = NULL;
+/* For wl_buffer's native set */
+static void *tbm_server_lib = NULL;
+static tbm_surface_h (*glsym_wayland_tbm_server_get_surface) (struct wayland_tbm_server *tbm_srv, struct wl_resource *wl_buffer) = NULL;
/* engine structure data */
typedef struct _Render_Engine Render_Engine;
};
/* LOCAL FUNCTIONS */
-Render_Engine *
-_render_engine_swapbuf_setup(int w, int h, unsigned int rotation, unsigned int depth, Eina_Bool alpha, void *tbm_queue)
+static Render_Engine *
+_render_engine_ouput_setup(Evas_Engine_Info_Software_Tbm *info, int w, int h)
{
- Render_Engine *re;
+ Render_Engine *re = NULL;
Outbuf *ob;
- Render_Engine_Merge_Mode merge_mode = MERGE_SMART;
- const char *s;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* try to allocate space for our render engine structure */
+ if (!(re = calloc(1, sizeof(Render_Engine))))
+ goto on_error;
- /* try to allocate space for new render engine */
- if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
-
- ob = _evas_software_tbm_outbuf_setup(w, h, rotation, depth, alpha, tbm_queue);
- if (!ob) goto err;
+ /* try to create new outbuf */
+ if (!(ob = evas_outbuf_setup(info, w, h)))
+ goto on_error;
if (!evas_render_engine_software_generic_init(&re->generic, ob,
- _evas_software_tbm_outbuf_swap_mode_get,
- _evas_software_tbm_outbuf_rotation_get,
- NULL,
- NULL,
- _evas_software_tbm_outbuf_update_region_new,
- _evas_software_tbm_outbuf_update_region_push,
- _evas_software_tbm_outbuf_update_region_free,
- _evas_software_tbm_outbuf_idle_flush,
- _evas_software_tbm_outbuf_flush,
- _evas_software_tbm_outbuf_free,
- w, h))
- goto err;
-
- re->outbuf_reconfigure = _evas_software_tbm_outbuf_reconfigure;
-
- s = getenv("EVAS_SOFTWARE_TBM_PARTIAL_MERGE");
- if (s)
- {
- if ((!strcmp(s, "bounding")) || (!strcmp(s, "b")))
- merge_mode = MERGE_BOUNDING;
- else if ((!strcmp(s, "full")) || (!strcmp(s, "f")))
- merge_mode = MERGE_FULL;
- else if ((!strcmp(s, "smart")) || (!strcmp(s, "s")))
- merge_mode = MERGE_SMART;
- }
-
- evas_render_engine_software_generic_merge_mode_set(&re->generic, merge_mode);
-
- /* return allocated render engine */
+ evas_outbuf_swap_mode_get,
+ evas_outbuf_rot_get,
+ evas_outbuf_reconfigure,
+ evas_outbuf_update_region_first_rect,
+ evas_outbuf_update_region_new,
+ evas_outbuf_update_region_push,
+ evas_outbuf_update_region_free,
+ evas_output_idle_flush,
+ evas_outbuf_flush,
+ evas_outbuf_free,
+ ob->w, ob->h))
+ goto on_error;
+
+ /* return the allocated render_engine structure */
return re;
-err:
- if (ob) _evas_software_tbm_outbuf_free(ob);
+ on_error:
+ if (re) evas_render_engine_software_generic_clean(&re->generic);
+
free(re);
return NULL;
}
_symbols(void)
{
static int done = 0;
+ int fail = 0;
+ const char *wayland_tbm_server_lib = "libwayland-tbm-server.so.0";
if (done) return;
#define LINK2GENERIC(sym) \
glsym_##sym = dlsym(RTLD_DEFAULT, #sym);
- // Get function pointer to native_common that is now provided through the link of SW_Generic.
- LINK2GENERIC(evas_native_tbm_surface_image_set);
+ tbm_server_lib = dlopen(wayland_tbm_server_lib, RTLD_LOCAL | RTLD_LAZY);
+ if (tbm_server_lib)
+ {
+ LINK2GENERIC(wayland_tbm_server_get_surface);
+ if (fail == 1)
+ {
+ ERR("fail to dlsym about wayland_tbm_server_get_surface symbol");
+ dlclose(tbm_server_lib);
+ tbm_server_lib = NULL;
+ return;
+ }
+ }
+ else
+ return;
done = 1;
}
-
-
/* ENGINE API FUNCTIONS WE PROVIDE */
static void *
eng_info(Evas *eo_evas EINA_UNUSED)
/* if we have no engine data, assume we have not initialized yet */
evas_common_init();
- re = _render_engine_swapbuf_setup(epd->output.w, epd->output.h,
- einfo->info.rotation,
- einfo->info.depth,
- einfo->info.destination_alpha,
- einfo->info.tbm_queue);
+ re = _render_engine_ouput_setup(einfo, epd->output.w, epd->output.h);
if (re)
re->generic.ob->info = einfo;
{
Outbuf *ob;
- ob = _evas_software_tbm_outbuf_setup(epd->output.w, epd->output.h,
- einfo->info.rotation, einfo->info.depth,
- einfo->info.destination_alpha,
- einfo->info.tbm_queue);
- if (ob)
+ ob = evas_outbuf_setup(einfo, epd->output.w, epd->output.h);
+ if (!ob)
{
- ob->info = einfo;
- evas_render_engine_software_generic_update(&re->generic, ob,
- epd->output.w,
- epd->output.h);
+ ERR("Failed to evas_outbuf_setup");
+ return 0;
}
+
+ evas_render_engine_software_generic_update(&re->generic, ob,
+ epd->output.w,
+ epd->output.h);
}
epd->engine.data.output = re;
free(re);
}
- evas_common_shutdown();
-}
-
-static void
-eng_output_resize(void *data, int w, int h)
-{
- Render_Engine *re;
- Evas_Engine_Info_Software_Tbm *einfo;
- int dx = 0, dy = 0;
- Eina_Bool resize = EINA_FALSE;
-
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
- if (!(re = (Render_Engine *)data)) return;
- if (!(einfo = re->generic.ob->info)) return;
-
- if (einfo->info.edges & 4) // resize from left
+ if (tbm_server_lib)
{
- if ((einfo->info.rotation == 90) || (einfo->info.rotation == 270))
- dx = re->generic.ob->h - h;
- else
- dx = re->generic.ob->w - w;
+ dlclose(tbm_server_lib);
+ tbm_server_lib = NULL;
}
- if (einfo->info.edges & 1) // resize from top
- {
- if ((einfo->info.rotation == 90) || (einfo->info.rotation == 270))
- dy = re->generic.ob->w - w;
- else
- dy = re->generic.ob->h - h;
- }
-
- if (einfo->info.edges) resize = EINA_TRUE;
-
- re->outbuf_reconfigure(re->generic.ob, dx, dy, w, h,
- einfo->info.rotation, einfo->info.depth,
- einfo->info.destination_alpha, resize);
-
- evas_common_tilebuf_free(re->generic.tb);
- if ((re->generic.tb = evas_common_tilebuf_new(w, h)))
- evas_common_tilebuf_set_tile_size(re->generic.tb, TILESIZE, TILESIZE);
-
- re->generic.w = w;
- re->generic.h = h;
+ evas_common_shutdown();
}
static void *
return im;
}
}
+ else if (ns->type == EVAS_NATIVE_SURFACE_WL)
+ {
+ if (im->native.data)
+ {
+ Evas_Native_Surface *ens;
- if ((ns->type == EVAS_NATIVE_SURFACE_OPENGL) &&
- (ns->version == EVAS_NATIVE_SURFACE_VERSION))
- im2 = evas_cache_image_data(evas_common_image_cache_get(),
- ie->w, ie->h,
- ns->data.x11.visual, 1,
- EVAS_COLORSPACE_ARGB8888);
- else
- im2 = evas_cache_image_data(evas_common_image_cache_get(),
+ ens = im->native.data;
+ if (ens->data.wl.legacy_buffer == ns->data.wl.legacy_buffer)
+ return im;
+ }
+ }
+
+ im2 = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
ie->w, ie->h,
NULL, 1,
EVAS_COLORSPACE_ARGB8888);
evas_cache2_image_close(ie);
else
#endif
- evas_cache_image_drop(ie);
+ evas_cache_image_drop(ie);
+
im = im2;
if (ns->type == EVAS_NATIVE_SURFACE_TBM)
- return glsym_evas_native_tbm_surface_image_set(NULL, im, ns);
+ {
+ return evas_native_tbm_surface_image_set(NULL, im, ns);
+ }
+ else if (ns->type == EVAS_NATIVE_SURFACE_WL)
+ {
+ // TODO : need the code for all wl_buffer type
+ // For TBM surface
+ if (glsym_wayland_tbm_server_get_surface)
+ {
+ tbm_surface_h _tbm_surface;
+ tbm_surface_info_s info;
+
+ _tbm_surface = glsym_wayland_tbm_server_get_surface(NULL,ns->data.wl.legacy_buffer);
+
+ tbm_surface_get_info(_tbm_surface, &info);
+
+ return evas_native_tbm_surface_image_set(_tbm_surface, im, ns);
+ }
+ else
+ {
+ return NULL;
+ }
+ }
return im;
}
ORD(info_free);
ORD(setup);
ORD(output_free);
- ORD(output_resize);
ORD(image_native_set);
ORD(image_native_get);
-#include "evas_common_private.h"
-#include "evas_private.h"
+#include "evas_engine.h"
#ifdef EVAS_CSERVE2
-# include "evas_cs2_private.h"
-#endif
-#ifdef HAVE_DLSYM
-# include <dlfcn.h>
+#include "evas_cs2_private.h"
#endif
-#include "evas_engine.h"
-#define RED_MASK 0xff0000
-#define GREEN_MASK 0x00ff00
-#define BLUE_MASK 0x0000ff
+#include <tbm_surface.h>
+#include <tbm_surface_queue.h>
+#include <tbm_surface_internal.h>
+
+static const int key_evas_buffer;
+#define KEY_EVAS_BUFFER ((unsigned long)&key_evas_buffer)
-static void *tbm_lib = NULL;
-static int tbm_ref = 0;
+typedef struct {
+ RGBA_Image *im;
+ unsigned int age;
+ tbm_surface_h tbm_surface;
+}evas_buffer_info;
-static int (*sym_tbm_surface_map) (tbm_surface_h surface, int opt, tbm_surface_info_s *info) = NULL;
-static int (*sym_tbm_surface_unmap) (tbm_surface_h surface) = NULL;
-static int (*sym_tbm_surface_queue_can_dequeue) (void *tbm_queue, int value) = NULL;
-static int (*sym_tbm_surface_queue_dequeue) (void *tbm_queue, tbm_surface_h *surface) = NULL;
-static int (*sym_tbm_surface_queue_enqueue) (void *tbm_queue, tbm_surface_h surface) = NULL;
-static int (*sym_tbm_surface_get_width) (tbm_surface_h surface) = NULL;
-static int (*sym_tbm_surface_get_height) (tbm_surface_h surface) = NULL;
+//#define ENG_DEBUG
-static Eina_Bool
-tbm_init(void)
+static void
+_tbm_surface_evas_buffer_info_free(void *data)
{
- if (tbm_lib)
- {
- tbm_ref++;
- return EINA_TRUE;
- }
+ evas_buffer_info* ebuf_info = data;
- const char *tbm_libs[] =
- {
- "libtbm.so.1",
- "libtbm.so.0",
- NULL,
- };
- int i, fail;
-#define SYM(lib, xx) \
- do { \
- sym_ ## xx = dlsym(lib, #xx); \
- if (!(sym_ ## xx)) { \
- ERR("%s", dlerror()); \
- fail = 1; \
- } \
- } while (0)
-
- for (i = 0; tbm_libs[i]; i++)
- {
- tbm_lib = dlopen(tbm_libs[i], RTLD_LOCAL | RTLD_LAZY);
- if (tbm_lib)
- {
- fail = 0;
- SYM(tbm_lib, tbm_surface_map);
- SYM(tbm_lib, tbm_surface_unmap);
- SYM(tbm_lib, tbm_surface_queue_can_dequeue);
- SYM(tbm_lib, tbm_surface_queue_dequeue);
- SYM(tbm_lib, tbm_surface_queue_enqueue);
- SYM(tbm_lib, tbm_surface_get_width);
- SYM(tbm_lib, tbm_surface_get_height);
- if (fail)
- {
- dlclose(tbm_lib);
- tbm_lib = NULL;
- }
- else break;
- }
- }
- if (!tbm_lib) return EINA_FALSE;
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_close(&ebuf_info->im->cache_entry);
+ else
+#endif
+ evas_cache_image_drop(&ebuf_info->im->cache_entry);
- tbm_ref++;
- return EINA_TRUE;
+ free(data);
}
-static void
-tbm_shutdown(void)
+static evas_buffer_info *
+_tbm_surface_evas_buffer_info_get(tbm_surface_h surface, Eina_Bool *is_first)
{
- if (tbm_ref > 0)
+ tbm_surface_info_s tbm_info;
+ evas_buffer_info *ebuf_info = NULL;
+ RGBA_Image *img = NULL;
+
+ if(!tbm_surface_internal_get_user_data(surface, KEY_EVAS_BUFFER, (void**)&ebuf_info))
{
- tbm_ref--;
+ tbm_surface_internal_add_user_data(surface, KEY_EVAS_BUFFER,
+ _tbm_surface_evas_buffer_info_free);
+ tbm_surface_get_info(surface, &tbm_info);
- if (tbm_ref == 0)
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ {
+ img = (RGBA_Image *)
+ evas_cache2_image_data(evas_common_image_cache2_get(),
+ tbm_info.planes[0].stride/4, tbm_info.height,
+ (DATA32*)tbm_info.planes[0].ptr,
+ 1,
+ EVAS_COLORSPACE_ARGB8888);
+ }
+ else
+#endif
{
- if (tbm_lib)
- {
- dlclose(tbm_lib);
- tbm_lib = NULL;
- }
+ img = (RGBA_Image *)
+ evas_cache_image_data(evas_common_image_cache_get(),
+ tbm_info.planes[0].stride/4, tbm_info.height,
+ (DATA32*)tbm_info.planes[0].ptr,
+ 1,
+ EVAS_COLORSPACE_ARGB8888);
}
+
+ if (!img)
+ ERR("fail to evas_cache_image_data()");
+
+ ebuf_info = calloc(1, sizeof(evas_buffer_info));
+ ebuf_info->im = img;
+ ebuf_info->tbm_surface = surface;
+ tbm_surface_internal_set_user_data(surface, KEY_EVAS_BUFFER, ebuf_info);
+
+ if (is_first)
+ *is_first = EINA_TRUE;
}
+
+ return ebuf_info;
}
+static void
+_tbm_surface_queue_reset_cb(tbm_surface_queue_h surface_queue EINA_UNUSED, void *data)
+{
+ Outbuf *ob = data;
+ ob->priv.queue_reset = EINA_TRUE;
+}
Outbuf *
-_evas_software_tbm_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, void *tbm_queue)
+evas_outbuf_setup(Evas_Engine_Info_Software_Tbm *info, int w, int h)
{
- Outbuf *ob = NULL;
- char *num;
-
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ Outbuf *ob;
- /* try to allocate space for new Outbuf */
+ /* try to allocate space for outbuf */
if (!(ob = calloc(1, sizeof(Outbuf)))) return NULL;
- if (!tbm_init())
- {
- ERR("Could not initialize TBM!");
- goto setup_err;
- }
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng setup %dx%d(%p) => %dx%d(%p)\n",
+ ob->w, ob->h, ob->priv.tbm_queue,
+ w,h,info->info.tbm_queue);
+#endif
- /* set outbuf properties */
+ /* set properties of outbuf */
ob->w = w;
ob->h = h;
- ob->rotation = rot;
- ob->depth = depth;
- ob->priv.destination_alpha = alpha;
- ob->tbm_queue = tbm_queue;
- tbm_surface_info_s info;
- eina_array_step_set(&ob->priv.onebuf_regions, sizeof(Eina_Array), 8);
+ ob->info = info;
+ ob->depth = info->info.depth;
+ ob->rotation = info->info.rotation;
- return ob;
+ if (!info->info.tbm_queue)
+ {
+ ob->priv.tbm_queue = tbm_surface_queue_create(3,
+ ob->w, ob->h,
+ TBM_FORMAT_ARGB8888,
+ TBM_BO_DEFAULT);
+ if (!ob->priv.tbm_queue)
+ ERR("Cannot create tbm_queue! w:%d, h%d", ob->w, ob->h);
+ ob->priv.queue_need_destroy = EINA_TRUE;
+ info->info.tbm_queue = ob->priv.tbm_queue;
+ }
+ else
+ {
+ ob->priv.tbm_queue = info->info.tbm_queue;
+ }
-setup_err:
- free(ob);
- return NULL;
+ tbm_surface_queue_add_reset_cb(ob->priv.tbm_queue, _tbm_surface_queue_reset_cb, ob);
+
+ return ob;
}
void
-_evas_software_tbm_outbuf_free(Outbuf *ob)
+evas_outbuf_free(Outbuf *ob)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
- while (ob->priv.pending_writes)
- {
- RGBA_Image *img;
- Eina_Rectangle *rect;
-
- img = ob->priv.pending_writes->data;
- ob->priv.pending_writes =
- eina_list_remove_list(ob->priv.pending_writes, ob->priv.pending_writes);
-
- rect = img->extended_info;
-
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- evas_cache2_image_close(&img->cache_entry);
- else
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng free tbm_queue:%p need_destroy:%d\n",
+ ob->priv.tbm_queue, ob->priv.queue_need_destroy);
#endif
- evas_cache_image_drop(&img->cache_entry);
- eina_rectangle_free(rect);
+ /* free allocate space for outbuf */
+ if (ob->priv.tbm_queue && ob->priv.queue_need_destroy)
+ {
+ tbm_surface_queue_destroy(ob->priv.tbm_queue);
+ ob->priv.tbm_queue = NULL;
+ ob->priv.queue_need_destroy = EINA_FALSE;
}
- _evas_software_tbm_outbuf_flush(ob, NULL, EVAS_RENDER_MODE_UNDEF);
- _evas_software_tbm_outbuf_idle_flush(ob);
-
- eina_array_flush(&ob->priv.onebuf_regions);
-
- tbm_shutdown();
-
free(ob);
}
void
-_evas_software_tbm_outbuf_idle_flush(Outbuf *ob)
+evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot EINA_UNUSED, Outbuf_Depth depth EINA_UNUSED)
{
- RGBA_Image *img;
- Eina_Rectangle *rect;
-
- if (ob->priv.onebuf)
- {
- img = ob->priv.onebuf;
- ob->priv.onebuf = NULL;
-
- rect = img->extended_info;
- eina_rectangle_free(rect);
-
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- evas_cache2_image_close(&img->cache_entry);
- else
-#endif
- evas_cache_image_drop(&img->cache_entry);
- }
- else
- {
- while (ob->priv.prev_pending_writes)
- {
- img = ob->priv.prev_pending_writes->data;
- ob->priv.prev_pending_writes =
- eina_list_remove_list(ob->priv.prev_pending_writes,
- ob->priv.prev_pending_writes);
- rect = img->extended_info;
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- evas_cache2_image_close(&img->cache_entry);
- else
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng reconfig %dx%d(%p) => %dx%d\n",
+ ob->w, ob->h, ob->priv.tbm_queue,
+ w,h);
#endif
- evas_cache_image_drop(&img->cache_entry);
- eina_rectangle_free(rect);
- }
+ if ((ob->w != w) || (ob->h != h))
+ {
+ ob->w = w;
+ ob->h = h;
+ tbm_surface_queue_reset(ob->priv.tbm_queue, w, h, TBM_FORMAT_ARGB8888);
}
}
-void
-_evas_software_tbm_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode)
+Render_Engine_Swap_Mode
+evas_outbuf_swap_mode_get(Outbuf *ob)
{
- Eina_Rectangle *result;
- RGBA_Image *img;
- unsigned int n = 0, i = 0;
-
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ tbm_surface_h surface = NULL;
+ evas_buffer_info *ebuf_info;
+ Eina_Bool is_first = EINA_FALSE;
+ Render_Engine_Swap_Mode mode = MODE_FULL;
+ tbm_surface_info_s tbm_info;
- if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return;
+ tbm_surface_queue_dequeue(ob->priv.tbm_queue, &surface);
+ if (!surface)
+ ERR("Fail to dequeue_buffer");
- /* check for pending writes */
- if (!ob->priv.pending_writes)
- {
- Eina_Rectangle *rect;
- Eina_Array_Iterator it;
-
- /* get number of buffer regions */
- n = eina_array_count_get(&ob->priv.onebuf_regions);
- if (n == 0) return;
-
- /* allocate rectangles */
- if (!(result = alloca(n * sizeof(Eina_Rectangle)))) return;
-
- /* loop the buffer regions and assign to result */
- EINA_ARRAY_ITER_NEXT(&ob->priv.onebuf_regions, i, rect, it)
- {
- result[i] = *rect;
- eina_rectangle_free(rect);
- }
+ ebuf_info = _tbm_surface_evas_buffer_info_get(surface, &is_first);
+ if (!ebuf_info)
+ ERR("Fail to get evas_buffer_info");
- sym_tbm_surface_unmap(ob->surface);
+ ob->priv.ebuf_info = ebuf_info;
- /* clean array */
- eina_array_clean(&ob->priv.onebuf_regions);
-
- img = ob->priv.onebuf;
- ob->priv.onebuf = NULL;
- if (img)
- {
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- evas_cache2_image_close(&img->cache_entry);
- else
-#endif
- evas_cache_image_drop(&img->cache_entry);
- }
- }
+ if (!ob->priv.frame_age || is_first == EINA_TRUE)
+ mode = MODE_FULL;
else
{
- /* get number of pending writes */
- n = eina_list_count(ob->priv.pending_writes);
- if (n == 0) return;
-
- /* allocate rectangles */
- if (!(result = alloca(n * sizeof(Eina_Rectangle)))) return;
-
- /* loop the pending writes */
- EINA_LIST_FREE(ob->priv.pending_writes, img)
+ if (ebuf_info->age < ob->priv.frame_age)
{
- Eina_Rectangle *rect;
- int x = 0, y = 0, w = 0, h = 0;
-
- if (!(rect = img->extended_info)) continue;
-
- x = rect->x; y = rect->y; w = rect->w; h = rect->h;
-
- /* based on rotation, set rectangle position */
- if (ob->rotation == 0)
- {
- result[i].x = x;
- result[i].y = y;
- }
- else if (ob->rotation == 90)
- {
- result[i].x = y;
- result[i].y = (ob->w - x - w);
- }
- else if (ob->rotation == 180)
- {
- result[i].x = (ob->w - x - w);
- result[i].y = (ob->h - y - h);
- }
- else if (ob->rotation == 270)
- {
- result[i].x = (ob->h - y - h);
- result[i].y = x;
- }
-
- /* based on rotation, set rectangle size */
- if ((ob->rotation == 0) || (ob->rotation == 180))
- {
- result[i].w = w;
- result[i].h = h;
- }
- else if ((ob->rotation == 90) || (ob->rotation == 270))
- {
- result[i].w = h;
- result[i].h = w;
- }
-
- eina_rectangle_free(rect);
-
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- evas_cache2_image_close(&img->cache_entry);
- else
-#endif
- evas_cache_image_drop(&img->cache_entry);
-
- i++;
+ unsigned int diff;
+ diff = ob->priv.frame_age - ebuf_info->age;
+ switch(diff)
+ {
+ case 0:
+ mode = MODE_COPY;
+ break;
+ case 1:
+ mode = MODE_DOUBLE;
+ break;
+ case 2:
+ mode = MODE_TRIPLE;
+ break;
+ case 3:
+ mode = MODE_QUADRUPLE;
+ break;
+ default:
+ mode = MODE_FULL;
+ }
}
-
- sym_tbm_surface_unmap(ob->surface);
}
- sym_tbm_surface_queue_enqueue(ob->tbm_queue, ob->surface);
-}
-Render_Engine_Swap_Mode
-_evas_software_tbm_outbuf_swap_mode_get(Outbuf *ob)
-{
- /* TODO: implement if we need buffer age */
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &tbm_info);
+ tbm_surface_internal_ref(surface);
- return MODE_FULL;
-}
-
-int
-_evas_software_tbm_outbuf_rotation_get(Outbuf *ob)
-{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng swap_mod(%d) frm_age:%d buf_age:%d tbm_surf:%p\n",
+ mode,
+ ob->priv.frame_age, ebuf_info->age,
+ surface);
+#endif
- return ob->rotation;
+ return MODE_FULL;
}
-void
-_evas_software_tbm_outbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha, Eina_Bool resize)
+Eina_Bool
+evas_outbuf_update_region_first_rect(Outbuf *ob)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
- if ((depth == OUTBUF_DEPTH_NONE) ||
- (depth == OUTBUF_DEPTH_INHERIT))
- depth = ob->depth;
+ Eina_Bool reset = ob->priv.queue_reset;
- if ((ob->w == w) && (ob->h == h) &&
- (ob->rotation == rot) && (ob->depth == depth) &&
- (ob->priv.destination_alpha == alpha))
- return;
+ ob->priv.queue_reset = EINA_FALSE;
- ob->w = w;
- ob->h = h;
- ob->rotation = rot;
- ob->depth = depth;
- ob->priv.destination_alpha = alpha;
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng first_rect(%d)\n", reset);
+#endif
- _evas_software_tbm_outbuf_idle_flush(ob);
+ return reset;
}
void *
-_evas_software_tbm_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
+evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
{
- RGBA_Image *img;
- Eina_Rectangle *rect;
- tbm_surface_info_s info;
+ evas_buffer_info *ebuf_info;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if ((w <= 0) || (h <= 0)) return NULL;
RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, ob->w, ob->h);
- if ((w <= 0) || (h <= 0)) return NULL;
- if (ob->rotation == 0)
+ ebuf_info = ob->priv.ebuf_info;
+ if (!ebuf_info)
{
- if (!(img = ob->priv.onebuf))
- {
- int bw = 0, bh = 0;
- void *data = NULL;
-
- if (sym_tbm_surface_queue_can_dequeue(ob->tbm_queue, 1))
- {
- sym_tbm_surface_queue_dequeue(ob->tbm_queue, &ob->surface);
- sym_tbm_surface_map(ob->surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
- data = info.planes[0].ptr;
- if (!data)
- {
- ERR("Could not get surface data");
- return NULL;
- }
- bw = info.planes[0].stride / 4;
- bh = sym_tbm_surface_get_height(ob->surface);
- }
- else {
- ERR("sym_tbm_surface_queue_can_dequeue fail");
- return NULL;
- }
-
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- {
- img = (RGBA_Image *)
- evas_cache2_image_data(evas_common_image_cache2_get(),
- bw, bh, data,
- ob->priv.destination_alpha,
- EVAS_COLORSPACE_ARGB8888);
- }
- else
-#endif
- {
- img = (RGBA_Image *)
- evas_cache_image_data(evas_common_image_cache_get(),
- bw, bh, data,
- ob->priv.destination_alpha,
- EVAS_COLORSPACE_ARGB8888);
-
- }
-
- ob->priv.onebuf = img;
- if (!img) return NULL;
- }
+ ERR("evas_outbuf_update_region_new ebuf_info is NULL");
+ return NULL;
+ }
- if (!(rect = eina_rectangle_new(x, y, w, h)))
- return NULL;
+ if (cx) *cx = x;
+ if (cy) *cy = y;
+ if (cw) *cw = w;
+ if (ch) *ch = h;
- if (!eina_array_push(&ob->priv.onebuf_regions, rect))
- {
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- evas_cache2_image_close(&img->cache_entry);
- else
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng region_new %dx%d+%d+%d cx:%dx%d+%d+%d img:%p\n",
+ x,y,w,h,
+ *cx, *cy, *cw, *ch,
+ ebuf_info->im);
#endif
- evas_cache_image_drop(&img->cache_entry);
-
- eina_rectangle_free(rect);
- return NULL;
- }
- if (cx) *cx = x;
- if (cy) *cy = y;
- if (cw) *cw = w;
- if (ch) *ch = h;
-
- img->extended_info = rect;
-
- return img;
- }
- else
- {
- if (!(rect = eina_rectangle_new(x, y, w, h)))
- return NULL;
+ return (void*)ebuf_info->im;
+}
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- img = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
- else
+void
+evas_outbuf_update_region_push(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED)
+{
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng region_push img:%p %dx%d+%d+%d\n",
+ update,
+ x, y, w, h);
#endif
- img = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
-
- if (!img)
- {
- eina_rectangle_free(rect);
- return NULL;
- }
-
- img->cache_entry.w = w;
- img->cache_entry.h = h;
- img->cache_entry.flags.alpha |= ob->priv.destination_alpha ? 1 : 0;
+}
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- evas_cache2_image_surface_alloc(&img->cache_entry, w, h);
- else
+void
+evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
+{
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng region_free img:%p\n",
+ update);
#endif
- evas_cache_image_surface_alloc(&img->cache_entry, w, h);
-
- img->extended_info = rect;
-
- ob->priv.pending_writes =
- eina_list_append(ob->priv.pending_writes, img);
-
- if (cx) *cx = 0;
- if (cy) *cy = 0;
- if (cw) *cw = w;
- if (ch) *ch = h;
- return img;
- }
-
- return NULL;
}
void
-_evas_software_tbm_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h)
+evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode EINA_UNUSED)
{
- Gfx_Func_Convert func = NULL;
- Eina_Rectangle rect = {0, 0, 0, 0}, pr;
- DATA32 *src;
- DATA8 *dst;
- int depth = 32, bpp = 0, bpl = 0, wid = 0;
- int ww = 0, hh = 0;
- int rx = 0, ry = 0;
- tbm_surface_info_s info;
-
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
- /* check for valid output buffer */
- if (!ob) return;
-
- /* check for pending writes */
- if (!ob->priv.pending_writes) return;
-
- if ((ob->rotation == 0) || (ob->rotation == 180))
- {
- func =
- evas_common_convert_func_get(0, w, h, depth,
- RED_MASK, GREEN_MASK, BLUE_MASK,
- PAL_MODE_NONE, ob->rotation);
- }
- else if ((ob->rotation == 90) || (ob->rotation == 270))
- {
- func =
- evas_common_convert_func_get(0, h, w, depth,
- RED_MASK, GREEN_MASK, BLUE_MASK,
- PAL_MODE_NONE, ob->rotation);
- }
-
- /* make sure we have a valid convert function */
- if (!func) return;
-
- /* based on rotation, set rectangle position */
- if (ob->rotation == 0)
- {
- rect.x = x;
- rect.y = y;
- }
- else if (ob->rotation == 90)
- {
- rect.x = y;
- rect.y = (ob->w - x - w);
- }
- else if (ob->rotation == 180)
- {
- rect.x = (ob->w - x - w);
- rect.y = (ob->h - y - h);
- }
- else if (ob->rotation == 270)
- {
- rect.x = (ob->h - y - h);
- rect.y = x;
- }
+ evas_buffer_info *ebuf_info = ob->priv.ebuf_info;
- /* based on rotation, set rectangle size */
- if ((ob->rotation == 0) || (ob->rotation == 180))
- {
- rect.w = w;
- rect.h = h;
- }
- else if ((ob->rotation == 90) || (ob->rotation == 270))
- {
- rect.w = h;
- rect.h = w;
- }
-
- /* check for valid update image data */
- if (!(src = update->image.data)) return;
-
- bpp = depth / 8;
- if (bpp <= 0) return;
-
- /* check for valid desination data */
- if (sym_tbm_surface_queue_can_dequeue(ob->tbm_queue, 1))
- {
- sym_tbm_surface_queue_dequeue(ob->tbm_queue, &ob->surface);
- sym_tbm_surface_map(ob->surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
- dst = info.planes[0].ptr;
- if (!dst)
- {
- ERR("Could not get surface data");
- return;
- }
- }
- else {
- ERR("sym_tbm_surface_queue_can_dequeue fail");
- return;
- }
-
-
- bpl = (ww * sizeof(int));
-
- if (ob->rotation == 0)
- {
- RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh);
- dst += (bpl * rect.y) + (rect.x * bpp);
- w -= rx;
- }
- else if (ob->rotation == 180)
- {
- pr = rect;
- RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh);
- rx = pr.w - rect.w;
- ry = pr.h - rect.h;
- src += (update->cache_entry.w * ry) + rx;
- w -= rx;
- }
- else if (ob->rotation == 90)
- {
- pr = rect;
- RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh);
- rx = pr.w - rect.w; ry = pr.h - rect.h;
- src += ry;
- w -= ry;
- }
- else if (ob->rotation == 270)
- {
- pr = rect;
- RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, 0, 0, ww, hh);
- rx = pr.w - rect.w; ry = pr.h - rect.h;
- src += (update->cache_entry.w * rx);
- w -= ry;
- }
-
- if ((rect.w <= 0) || (rect.h <= 0)) return;
-
- wid = bpl / bpp;
+ ob->priv.frame_age++;
+ ebuf_info->age = ob->priv.frame_age;
+ ob->priv.ebuf_info = NULL;
- dst += (bpl * rect.y) + (rect.x * bpp);
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng flush frm_age:%d buf_age:%d tbm_surf:%p\n",
+ ob->priv.frame_age, ebuf_info->age, ebuf_info->tbm_surface);
+#endif
- func(src, dst, (update->cache_entry.w - w), (wid - rect.w),
- rect.w, rect.h, x + rx, y + ry, NULL);
+ tbm_surface_unmap(ebuf_info->tbm_surface);
+ tbm_surface_queue_enqueue(ob->priv.tbm_queue, ebuf_info->tbm_surface);
+ tbm_surface_internal_unref(ebuf_info->tbm_surface);
}
void
-_evas_software_tbm_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
+evas_output_idle_flush(Outbuf *ob EINA_UNUSED)
+{
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng idle_flush\n");
+#endif
+}
+
+int
+evas_outbuf_rot_get(Outbuf *ob)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+#ifdef ENG_DEBUG
+ fprintf(stderr,"[evas:sw_tbm] eng rot_get: %d\n", ob->rotation);
+#endif
+
+ return ob->rotation;
}