forked from enlightenment/efl
ecore-buffer: Add ecore_buffer library to EFL.
Summary: Ecore_Buffer is abstraction of graphic buffer. it supports backend of shm, x11_dri2 and x11_dri3 for now, and this library also provides method to share buffers between processes. Ecore_Buffer_Provider and Ecore_Buffer_Consumer is for this, sharing buffer. provider draws something in to Ecore_Buffer, and consumer receives and displays it. the binary, bq_mgr is a connection maker for buffer provider and consumer. it can be included Enlightenment as a deamon later. @feature Test Plan: 1. Configure with --enable-ecore-buffer and --enable-always-build-examples to build examples. 2. Run bq_mgr, it connects consumer and provider. 3. Run ecore_buffer_provider_example and ecore_buffer_consumer_example Reviewers: lsj119, gwanglim, cedric, zmike, jpeg, raster, devilhorns Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D2197
This commit is contained in:
parent
3671506ad3
commit
8b62177561
|
@ -140,6 +140,7 @@ pc/ecore-imf.pc \
|
|||
pc/ecore-imf-evas.pc \
|
||||
pc/ecore-evas.pc \
|
||||
pc/ecore-avahi.pc \
|
||||
pc/ecore-buffer.pc \
|
||||
pc/ector.pc \
|
||||
pc/embryo.pc \
|
||||
pc/eio.pc \
|
||||
|
|
72
configure.ac
72
configure.ac
|
@ -1705,6 +1705,17 @@ AC_ARG_ENABLE([tile-rotate],
|
|||
],
|
||||
[have_tile_rotate="no"])
|
||||
|
||||
# Ecore Buffer
|
||||
AC_ARG_ENABLE([ecore-buffer],
|
||||
[AS_HELP_STRING([--enable-ecore-buffer],[enable ecore-buffer. @<:@default=disabled@:>@])],
|
||||
[
|
||||
if test "x${enableval}" = "xyes" ; then
|
||||
want_ecore_buffer="yes"
|
||||
else
|
||||
want_ecore_buffer="no"
|
||||
fi
|
||||
],
|
||||
[want_ecore_buffer="no"])
|
||||
|
||||
# Image Loaders
|
||||
|
||||
|
@ -4587,6 +4598,65 @@ AC_ARG_ENABLE([i-really-know-what-i-am-doing-and-that-this-will-probably-break-t
|
|||
],
|
||||
[ BARF_OK="xno" ])
|
||||
|
||||
#### Ecore_Buffer
|
||||
build_ecore_buffer_x11_dri2="no"
|
||||
build_ecore_buffer_x11_dri3="no"
|
||||
EFL_LIB_START_OPTIONAL([Ecore_Buffer], [test "${want_ecore_buffer}" = "yes"])
|
||||
### Checks for libraries
|
||||
EFL_INTERNAL_DEPEND_PKG([ECORE_BUFFER], [eina])
|
||||
EFL_INTERNAL_DEPEND_PKG([ECORE_BUFFER], [eo])
|
||||
EFL_INTERNAL_DEPEND_PKG([ECORE_BUFFER], [ecore])
|
||||
EFL_DEPEND_PKG([ECORE_BUFFER], [WAYLAND],
|
||||
[wayland-server >= 1.5.0 wayland-client >= 1.5.0])
|
||||
|
||||
PKG_CHECK_MODULES([X11_DRI_COMMON],
|
||||
[
|
||||
libtbm >= 1.1.0,
|
||||
libdrm >= 2.4.35,
|
||||
],
|
||||
[have_x11_dri_common_pkgs="yes"],
|
||||
[have_x11_dri_common_pkgs="no"]
|
||||
)
|
||||
|
||||
if test "x$have_x11_dri_common_pkgs" = "xyes" ; then
|
||||
EFL_INTERNAL_DEPEND_PKG([ECORE_BUFFER], [ecore_x])
|
||||
|
||||
PKG_CHECK_MODULES([X11_DRI2], [libdri2],
|
||||
[have_x11_dri2_pkgs="yes"],
|
||||
[have_x11_dri2_pkgs="no"])
|
||||
PKG_CHECK_MODULES([X11_DRI3],
|
||||
[
|
||||
xshmfence,
|
||||
xcb,
|
||||
x11-xcb,
|
||||
xcb-sync,
|
||||
xcb-dri3
|
||||
],
|
||||
[have_x11_dri3_pkgs="yes"],
|
||||
[have_x11_dri3_pkgs="no"])
|
||||
fi
|
||||
|
||||
if test "x${have_x11_dri2_pkgs}" = "xyes" ; then
|
||||
build_ecore_buffer_x11_dri2="yes"
|
||||
AC_DEFINE(BUILD_ECORE_BUFFER_X11_DRI2, 1, [Support for X11_DRI2 Backend in Ecore_Buffer])
|
||||
fi
|
||||
|
||||
if test "x${have_x11_dri3_pkgs}" = "xyes" ; then
|
||||
build_ecore_buffer_x11_dri3="yes"
|
||||
AC_DEFINE(BUILD_ECORE_BUFFER_X11_DRI3, 1, [Support for X11_DRI3 Backend in Ecore_Buffer])
|
||||
fi
|
||||
EFL_EVAL_PKGS([ECORE_BUFFER])
|
||||
|
||||
EFL_ADD_FEATURE([ECORE_BUFFER], [shm], ["yes"])
|
||||
EFL_ADD_FEATURE([ECORE_BUFFER], [x11_dri2], [${build_ecore_buffer_x11_dri2}])
|
||||
EFL_ADD_FEATURE([ECORE_BUFFER], [x11_dri3], [${build_ecore_buffer_x11_dri3}])
|
||||
|
||||
EFL_LIB_END_OPTIONAL([Ecore_Buffer])
|
||||
|
||||
AM_CONDITIONAL([BUILD_ECORE_BUFFER_X11_DRI2], [test "${build_ecore_buffer_x11_dri2}" = "xyes"])
|
||||
AM_CONDITIONAL([BUILD_ECORE_BUFFER_X11_DRI3], [test "${build_ecore_buffer_x11_dri3}" = "xyes"])
|
||||
|
||||
#### End of Ecore_Buffer
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
|
@ -4667,6 +4737,7 @@ pc/ecore-imf-evas.pc
|
|||
pc/ecore-audio.pc
|
||||
pc/ecore-audio-cxx.pc
|
||||
pc/ecore-avahi.pc
|
||||
pc/ecore-buffer.pc
|
||||
pc/ector.pc
|
||||
pc/embryo.pc
|
||||
pc/eio.pc
|
||||
|
@ -4827,6 +4898,7 @@ echo "Ecore_X.........: ${with_x11} (${features_ecore_x})"
|
|||
echo "Ecore_SDL.......: $want_sdl"
|
||||
echo "Ecore_Wayland...: $want_wayland"
|
||||
echo "IVI-Shell.......: $want_wayland_ivi_shell"
|
||||
echo "Ecore_Buffer....: $want_ecore_buffer (${features_ecore_buffer})"
|
||||
if test "${have_linux}" = "yes"; then
|
||||
echo "Ecore_FB........: $want_fb (${features_ecore_fb})"
|
||||
elif test "${have_ps3}" = "yes"; then
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
/ecore-win32.pc
|
||||
/ecore-x.pc
|
||||
/ecore.pc
|
||||
/ecore-buffer.pc
|
||||
/ector.pc
|
||||
/edje.pc
|
||||
/eet.pc
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: ecore-buffer
|
||||
Description: E core library, graphic buffer module
|
||||
Requires.private: @requirements_pc_ecore_buffer@
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lecore_buffer
|
||||
Libs.private: @requirements_libs_ecore_buffer@
|
||||
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/ecore-buffer-@VMAJ@
|
|
@ -54,6 +54,7 @@ include Makefile_Ecore_Avahi.am
|
|||
include Makefile_Embryo.am
|
||||
include Makefile_Eio.am
|
||||
include Makefile_Efreet.am
|
||||
include Makefile_Ecore_Buffer.am
|
||||
include Makefile_EPhysics.am
|
||||
include Makefile_Edje.am
|
||||
include Makefile_Emotion.am
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
if HAVE_ECORE_BUFFER
|
||||
|
||||
### Library
|
||||
|
||||
lib_LTLIBRARIES += lib/ecore_buffer/libecore_buffer.la
|
||||
|
||||
installed_ecorebuffermainheadersdir = $(includedir)/ecore-buffer-@VMAJ@
|
||||
dist_installed_ecorebuffermainheaders_DATA = \
|
||||
lib/ecore_buffer/Ecore_Buffer.h \
|
||||
lib/ecore_buffer/Ecore_Buffer_Queue.h
|
||||
|
||||
lib_ecore_buffer_libecore_buffer_la_SOURCES = \
|
||||
lib/ecore_buffer/bq_mgr_protocol.c \
|
||||
lib/ecore_buffer/buffer_queue.c \
|
||||
lib/ecore_buffer/shared_buffer.c \
|
||||
lib/ecore_buffer/ecore_buffer.c \
|
||||
lib/ecore_buffer/ecore_buffer_queue_main.c \
|
||||
lib/ecore_buffer/ecore_buffer_con.c \
|
||||
lib/ecore_buffer/ecore_buffer_provider.c \
|
||||
lib/ecore_buffer/ecore_buffer_consumer.c
|
||||
|
||||
lib_ecore_buffer_libecore_buffer_la_CPPFLAGS = \
|
||||
-I$(top_builddir)/src/lib/efl \
|
||||
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)\" \
|
||||
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
|
||||
@ECORE_BUFFER_CFLAGS@
|
||||
|
||||
lib_ecore_buffer_libecore_buffer_la_LIBADD = @ECORE_BUFFER_LIBS@
|
||||
lib_ecore_buffer_libecore_buffer_la_DEPENDENCIES = @ECORE_BUFFER_INTERNAL_LIBS@
|
||||
lib_ecore_buffer_libecore_buffer_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
|
||||
|
||||
### Binary
|
||||
bqmgr_bindir=$(libdir)/ecore_buffer/bin/$(MODULE_ARCH)
|
||||
bqmgr_bin_PROGRAMS = bin/ecore_buffer/bq_mgr
|
||||
|
||||
bin_ecore_buffer_bq_mgr_SOURCES = \
|
||||
bin/ecore_buffer/bq_mgr_protocol.c \
|
||||
bin/ecore_buffer/bq_mgr.c
|
||||
|
||||
bin_ecore_buffer_bq_mgr_CPPFLAGS = \
|
||||
-I$(top_builddir)/src/lib/efl \
|
||||
@ECORE_BUFFER_CFLAGS@
|
||||
bin_ecore_buffer_bq_mgr_LDADD = @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_BUFFER_LIBS@
|
||||
bin_ecore_buffer_bq_mgr_DEPENDENCIES = @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_BUFFER_INTERNAL_LIBS@
|
||||
|
||||
### Backends
|
||||
|
||||
ecorebuffershmdir = $(libdir)/ecore_buffer/modules/shm/$(MODULE_ARCH)
|
||||
ecorebuffershm_LTLIBRARIES = modules/ecore_buffer/shm/module.la
|
||||
|
||||
modules_ecore_buffer_shm_module_la_SOURCES = \
|
||||
modules/ecore_buffer/shm/ecore_buffer_shm.c
|
||||
modules_ecore_buffer_shm_module_la_CPPFLAGS = \
|
||||
-I$(top_builddir)/src/lib/efl \
|
||||
@ECORE_BUFFER_CFLAGS@ \
|
||||
-I$(top_srcdir)/src/modules/ecore_buffer/shm
|
||||
modules_ecore_buffer_shm_module_la_LIBADD = \
|
||||
@ECORE_BUFFER_LIBS@ \
|
||||
@USE_ECORE_BUFFER_INTERNAL_LIBS@
|
||||
modules_ecore_buffer_shm_module_la_DEPENDENCIES = \
|
||||
@USE_ECORE_BUFFER_INTERNAL_LIBS@
|
||||
modules_ecore_buffer_shm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
modules_ecore_buffer_shm_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
if BUILD_ECORE_BUFFER_X11_DRI2
|
||||
ecorebufferx11dri2dir = $(libdir)/ecore_buffer/modules/x11_dri2/$(MODULE_ARCH)
|
||||
ecorebufferx11dri2_LTLIBRARIES = modules/ecore_buffer/x11_dri2/module.la
|
||||
|
||||
modules_ecore_buffer_x11_dri2_module_la_SOURCES = \
|
||||
modules/ecore_buffer/x11_dri2/ecore_buffer_x11_dri2.c
|
||||
modules_ecore_buffer_x11_dri2_module_la_CPPFLAGS = \
|
||||
-I$(top_builddir)/src/lib/efl \
|
||||
@ECORE_BUFFER_CFLAGS@ \
|
||||
@X11_DRI_COMMON_CFLAGS@ \
|
||||
@X11_DRI2_CFLAGS@ \
|
||||
-I$(top_srcdir)/src/modules/ecore_buffer/x11_dri2
|
||||
modules_ecore_buffer_x11_dri2_module_la_LIBADD = \
|
||||
@ECORE_BUFFER_LIBS@ \
|
||||
@USE_ECORE_BUFFER_INTERNAL_LIBS@ \
|
||||
@X11_DRI_COMMON_LIBS@ \
|
||||
@X11_DRI2_LIBS@
|
||||
modules_ecore_buffer_x11_dri2_module_la_DEPENDENCIES = \
|
||||
@USE_ECORE_X_INTERNAL_LIBS@ \
|
||||
@USE_ECORE_BUFFER_INTERNAL_LIBS@
|
||||
modules_ecore_buffer_x11_dri2_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
modules_ecore_buffer_x11_dri2_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
if BUILD_ECORE_BUFFER_X11_DRI3
|
||||
ecorebufferx11dri3dir = $(libdir)/ecore_buffer/modules/x11_dri3/$(MODULE_ARCH)
|
||||
ecorebufferx11dri3_LTLIBRARIES = modules/ecore_buffer/x11_dri3/module.la
|
||||
|
||||
modules_ecore_buffer_x11_dri3_module_la_SOURCES = \
|
||||
modules/ecore_buffer/x11_dri3/ecore_buffer_x11_dri3.c
|
||||
modules_ecore_buffer_x11_dri3_module_la_CPPFLAGS = \
|
||||
-I$(top_builddir)/src/lib/efl \
|
||||
@ECORE_BUFFER_CFLAGS@ \
|
||||
@X11_DRI_COMMON_CFLAGS@ \
|
||||
@X11_DRI3_CFLAGS@ \
|
||||
-I$(top_srcdir)/src/modules/ecore_buffer/x11_dri3
|
||||
modules_ecore_buffer_x11_dri3_module_la_LIBADD = \
|
||||
@ECORE_BUFFER_LIBS@ \
|
||||
@USE_ECORE_BUFFER_INTERNAL_LIBS@ \
|
||||
@X11_DRI_COMMON_LIBS@ \
|
||||
@X11_DRI3_LIBS@
|
||||
modules_ecore_buffer_x11_dri3_module_la_DEPENDENCIES = \
|
||||
@USE_ECORE_X_INTERNAL_LIBS@ \
|
||||
@USE_ECORE_BUFFER_INTERNAL_LIBS@
|
||||
modules_ecore_buffer_x11_dri3_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
modules_ecore_buffer_x11_dri3_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
endif
|
|
@ -0,0 +1 @@
|
|||
/bq_mgr
|
|
@ -0,0 +1,899 @@
|
|||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/xattr.h>
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Ecore_Getopt.h>
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include "bq_mgr_protocol.h"
|
||||
|
||||
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
||||
|
||||
#define BQ_LOG(f, x...) printf("[ES|%30.30s|%04d] " f "\n", __func__, __LINE__, ##x)
|
||||
#define BQ_DEBUG(f, x...) if (debug) printf("[ES|%30.30s|%04d] " f "\n", __func__, __LINE__, ##x)
|
||||
#define BQ_OBJECT_NEW(x, f) bq_object_new(sizeof(x), ((Bq_Object_Free_Func)(f)))
|
||||
#define BQ_OBJECT(x) ((Bq_Object *)(x))
|
||||
#define BQ_OBJECT_RESOURCE(x) (((Bq_Object *)(x))->resource)
|
||||
|
||||
typedef void (*Bq_Object_Free_Func) (void *obj);
|
||||
|
||||
typedef struct _Bq_Object Bq_Object;
|
||||
typedef struct _Bq_Mgr Bq_Mgr;
|
||||
typedef struct _Bq_Buffer_Queue Bq_Buffer_Queue;
|
||||
typedef struct _Bq_Buffer_Consumer Bq_Buffer_Consumer;
|
||||
typedef struct _Bq_Buffer_Provider Bq_Buffer_Provider;
|
||||
typedef struct _Bq_Buffer Bq_Buffer;
|
||||
typedef enum _Bq_Buffer_Type Bq_Buffer_Type;
|
||||
|
||||
struct _Bq_Object
|
||||
{
|
||||
int ref;
|
||||
Bq_Object_Free_Func free_fn;
|
||||
Eina_Bool deleted;
|
||||
struct wl_resource *resource;
|
||||
};
|
||||
|
||||
struct _Bq_Mgr
|
||||
{
|
||||
Bq_Object bq_obj;
|
||||
|
||||
struct wl_display *wdpy;
|
||||
struct wl_event_source *signals[3];
|
||||
|
||||
/*BufferQueue manager*/
|
||||
struct wl_global *bq_mgr;
|
||||
Eina_Hash *buffer_queues;
|
||||
};
|
||||
|
||||
|
||||
struct _Bq_Buffer_Queue
|
||||
{
|
||||
Bq_Object bq_obj;
|
||||
Eina_Hash *link;
|
||||
|
||||
char *name;
|
||||
struct wl_signal connect;
|
||||
|
||||
Bq_Buffer_Consumer *consumer;
|
||||
Bq_Buffer_Provider *provider;
|
||||
Eina_Inlist *buffers;
|
||||
};
|
||||
|
||||
struct _Bq_Buffer_Consumer
|
||||
{
|
||||
Bq_Object bq_obj;
|
||||
Bq_Buffer_Queue *buffer_queue;
|
||||
|
||||
int32_t queue_size;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
};
|
||||
|
||||
struct _Bq_Buffer_Provider
|
||||
{
|
||||
Bq_Object bq_obj;
|
||||
Bq_Buffer_Queue *buffer_queue;
|
||||
};
|
||||
|
||||
enum _Bq_Buffer_Type
|
||||
{
|
||||
bq_BUFFER_TYPE_ID,
|
||||
bq_BUFFER_TYPE_FD,
|
||||
};
|
||||
|
||||
struct _Bq_Buffer
|
||||
{
|
||||
Bq_Object bq_obj; /*Dont use wl_resource in bq_obj*/
|
||||
EINA_INLIST;
|
||||
|
||||
struct wl_resource *consumer;
|
||||
struct wl_resource *provider;
|
||||
uint32_t serial;
|
||||
|
||||
char *engine;
|
||||
Bq_Buffer_Type type;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t format;
|
||||
uint32_t flags;
|
||||
|
||||
int32_t id;
|
||||
int32_t offset0;
|
||||
int32_t stride0;
|
||||
int32_t offset1;
|
||||
int32_t stride1;
|
||||
int32_t offset2;
|
||||
int32_t stride2;
|
||||
};
|
||||
|
||||
static Eina_Bool debug;
|
||||
|
||||
static void *
|
||||
bq_object_new(size_t size, Bq_Object_Free_Func fn)
|
||||
{
|
||||
Bq_Object *o = calloc(1, size);
|
||||
|
||||
if ((!o)) return NULL;
|
||||
|
||||
o->ref = 1;
|
||||
o->free_fn = fn;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
static int
|
||||
bq_object_ref(Bq_Object *o)
|
||||
{
|
||||
o->ref++;
|
||||
|
||||
return o->ref;
|
||||
}
|
||||
|
||||
static int
|
||||
bq_object_unref(Bq_Object *o)
|
||||
{
|
||||
o->ref--;
|
||||
|
||||
if (o->ref <= 0 || o->deleted)
|
||||
{
|
||||
if (o->free_fn)
|
||||
o->free_fn(o);
|
||||
|
||||
free(o);
|
||||
}
|
||||
|
||||
return o->ref;
|
||||
}
|
||||
|
||||
static int
|
||||
bq_object_free(Bq_Object *o)
|
||||
{
|
||||
if (!o) return 0;
|
||||
if (o->deleted) return 0;
|
||||
|
||||
o->deleted = EINA_TRUE;
|
||||
|
||||
return bq_object_unref(o);
|
||||
}
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_queue_free(Bq_Buffer_Queue *bq)
|
||||
{
|
||||
Bq_Buffer *buf;
|
||||
|
||||
if (!bq) return;
|
||||
|
||||
BQ_DEBUG("destroy buffer queue : %s\n", bq->name);
|
||||
|
||||
if (bq->consumer)
|
||||
{
|
||||
wl_resource_destroy(BQ_OBJECT_RESOURCE(bq->consumer));
|
||||
bq->consumer = NULL;
|
||||
}
|
||||
|
||||
if (bq->provider)
|
||||
{
|
||||
wl_resource_destroy(BQ_OBJECT_RESOURCE(bq->provider));
|
||||
bq->provider = NULL;
|
||||
}
|
||||
|
||||
while (bq->buffers)
|
||||
{
|
||||
buf = EINA_INLIST_CONTAINER_GET(bq->buffers,Bq_Buffer);
|
||||
bq->buffers = eina_inlist_remove(bq->buffers, bq->buffers);
|
||||
if (buf->consumer)
|
||||
{
|
||||
wl_resource_destroy(buf->consumer);
|
||||
buf->consumer = NULL;
|
||||
}
|
||||
|
||||
if (buf->provider)
|
||||
{
|
||||
wl_resource_destroy(buf->provider);
|
||||
buf->provider = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (bq->link)
|
||||
{
|
||||
eina_hash_del(bq->link, bq->name, bq);
|
||||
bq->link = NULL;
|
||||
}
|
||||
if (bq->name)
|
||||
{
|
||||
free(bq->name);
|
||||
bq->name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static Bq_Buffer_Queue*
|
||||
bq_mgr_buffer_queue_new(Bq_Mgr *bq_mgr, const char *name)
|
||||
{
|
||||
Bq_Buffer_Queue *bq;
|
||||
|
||||
bq = eina_hash_find(bq_mgr->buffer_queues, name);
|
||||
if (bq)
|
||||
{
|
||||
bq_object_ref(BQ_OBJECT(bq));
|
||||
return bq;
|
||||
}
|
||||
|
||||
bq = BQ_OBJECT_NEW(Bq_Buffer_Queue, bq_mgr_buffer_queue_free);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(bq, NULL);
|
||||
|
||||
bq->link = bq_mgr->buffer_queues;
|
||||
bq->name = strdup(name);
|
||||
if (!eina_hash_add(bq->link,bq->name,bq))
|
||||
{
|
||||
bq_object_free(BQ_OBJECT(bq));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wl_signal_init(&bq->connect);
|
||||
bq->buffers = NULL;
|
||||
return bq;
|
||||
}
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_consumer_release_buffer(struct wl_client *client EINA_UNUSED,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *buffer)
|
||||
{
|
||||
Bq_Buffer_Queue *bq;
|
||||
Bq_Buffer_Consumer *bq_consumer;
|
||||
Bq_Buffer_Provider *bq_provider;
|
||||
Bq_Buffer *bq_buffer;
|
||||
|
||||
bq_consumer = (Bq_Buffer_Consumer*)wl_resource_get_user_data(resource);
|
||||
bq_buffer = (Bq_Buffer*)wl_resource_get_user_data(buffer);
|
||||
bq = bq_consumer->buffer_queue;
|
||||
bq_provider = bq->provider;
|
||||
|
||||
if (bq_provider && bq_buffer->provider)
|
||||
{
|
||||
bq_provider_send_add_buffer(BQ_OBJECT_RESOURCE(bq_provider),
|
||||
bq_buffer->provider, bq_buffer->serial);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct bq_consumer_interface _bq_consumer_interface = {
|
||||
bq_mgr_buffer_consumer_release_buffer
|
||||
};
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_consumer_destroy(struct wl_resource *resource)
|
||||
{
|
||||
Bq_Buffer_Consumer *bq_consumer = wl_resource_get_user_data(resource);
|
||||
Bq_Buffer_Provider *bq_provider;
|
||||
Bq_Buffer_Queue *bq;
|
||||
Bq_Buffer *buf;
|
||||
|
||||
if (!bq_consumer) return;
|
||||
|
||||
BQ_DEBUG("destroy buffer consumer : %s\n", bq_consumer->buffer_queue->name);
|
||||
|
||||
bq = bq_consumer->buffer_queue;
|
||||
bq_provider = bq->provider;
|
||||
|
||||
bq->consumer = NULL;
|
||||
BQ_OBJECT_RESOURCE(bq_consumer) = NULL;
|
||||
|
||||
if (bq_provider)
|
||||
{
|
||||
bq_provider_send_disconnected(BQ_OBJECT_RESOURCE(bq_provider));
|
||||
}
|
||||
|
||||
while (bq->buffers)
|
||||
{
|
||||
buf = EINA_INLIST_CONTAINER_GET(bq->buffers,Bq_Buffer);
|
||||
bq->buffers = eina_inlist_remove(bq->buffers,bq->buffers);
|
||||
|
||||
BQ_DEBUG("destroy BUFFER : %d\n", buf->type);
|
||||
if (buf->consumer)
|
||||
{
|
||||
wl_resource_destroy(buf->consumer);
|
||||
buf->consumer = NULL;
|
||||
bq_object_unref(BQ_OBJECT(buf));
|
||||
}
|
||||
|
||||
if (buf->provider)
|
||||
{
|
||||
wl_resource_destroy(buf->provider);
|
||||
buf->provider = NULL;
|
||||
bq_object_unref(BQ_OBJECT(buf));
|
||||
}
|
||||
}
|
||||
|
||||
bq_object_unref(BQ_OBJECT(bq_consumer));
|
||||
bq_object_unref(BQ_OBJECT(bq));
|
||||
}
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_destroy(struct wl_resource *resource)
|
||||
{
|
||||
Bq_Buffer *buf = wl_resource_get_user_data(resource);
|
||||
|
||||
if (resource == buf->consumer)
|
||||
{
|
||||
BQ_DEBUG("destroy buffer : consumer\n");
|
||||
}
|
||||
else if (resource == buf->provider)
|
||||
{
|
||||
BQ_DEBUG("destroy buffer : provider\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bq_buffer_create_consumer_side(Bq_Buffer_Consumer *bq_consumer, Bq_Buffer *bq_buffer)
|
||||
{
|
||||
if (!bq_consumer) return;
|
||||
|
||||
bq_buffer->consumer = wl_resource_create(wl_resource_get_client(BQ_OBJECT_RESOURCE(bq_consumer)),
|
||||
&bq_buffer_interface, 1, 0);
|
||||
wl_resource_set_implementation(bq_buffer->consumer, NULL, bq_buffer, bq_mgr_buffer_destroy);
|
||||
bq_object_ref(BQ_OBJECT(bq_buffer));
|
||||
|
||||
bq_consumer_send_buffer_attached(BQ_OBJECT_RESOURCE(bq_consumer),
|
||||
bq_buffer->consumer,
|
||||
bq_buffer->engine,
|
||||
bq_buffer->width,
|
||||
bq_buffer->height,
|
||||
bq_buffer->format,
|
||||
bq_buffer->flags);
|
||||
}
|
||||
|
||||
static void
|
||||
bq_buffer_set_consumer_side(Bq_Buffer_Consumer *bq_consumer, Bq_Buffer *bq_buffer)
|
||||
{
|
||||
if (!bq_consumer) return;
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_buffer);
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_buffer->consumer);
|
||||
|
||||
if (bq_buffer->type == bq_BUFFER_TYPE_ID)
|
||||
bq_consumer_send_set_buffer_id(BQ_OBJECT_RESOURCE(bq_consumer),
|
||||
bq_buffer->consumer,
|
||||
bq_buffer->id,
|
||||
bq_buffer->offset0,
|
||||
bq_buffer->stride0,
|
||||
bq_buffer->offset1,
|
||||
bq_buffer->stride1,
|
||||
bq_buffer->offset2,
|
||||
bq_buffer->stride2);
|
||||
else
|
||||
{
|
||||
bq_consumer_send_set_buffer_fd(BQ_OBJECT_RESOURCE(bq_consumer),
|
||||
bq_buffer->consumer,
|
||||
bq_buffer->id,
|
||||
bq_buffer->offset0,
|
||||
bq_buffer->stride0,
|
||||
bq_buffer->offset1,
|
||||
bq_buffer->stride1,
|
||||
bq_buffer->offset2,
|
||||
bq_buffer->stride2);
|
||||
close(bq_buffer->id);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_queue_create_consumer(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
const char *name,
|
||||
int32_t queue_size,
|
||||
int32_t width,
|
||||
int32_t height)
|
||||
{
|
||||
Bq_Mgr *bq_mgr = (Bq_Mgr*)wl_resource_get_user_data(resource);
|
||||
Bq_Buffer_Queue *bq;
|
||||
Bq_Buffer_Consumer *bq_consumer;
|
||||
Bq_Buffer_Provider *bq_provider;
|
||||
Bq_Buffer *buf;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_mgr);
|
||||
|
||||
bq = bq_mgr_buffer_queue_new(bq_mgr,name);
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq);
|
||||
|
||||
if (bq->consumer)
|
||||
{
|
||||
bq_object_unref(BQ_OBJECT(bq));
|
||||
wl_resource_post_error(resource,
|
||||
BQ_MGR_ERROR_ALREADY_USED,
|
||||
"%s consumer already used",name);
|
||||
return;
|
||||
}
|
||||
|
||||
bq_consumer = BQ_OBJECT_NEW(Bq_Buffer_Consumer, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_consumer);
|
||||
BQ_OBJECT_RESOURCE(bq_consumer) = wl_resource_create(client,
|
||||
&bq_consumer_interface,
|
||||
1, id);
|
||||
if (!BQ_OBJECT_RESOURCE(bq_consumer))
|
||||
{
|
||||
bq_object_unref(BQ_OBJECT(bq_consumer));
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation(BQ_OBJECT_RESOURCE(bq_consumer),
|
||||
&_bq_consumer_interface,
|
||||
bq_consumer,
|
||||
bq_mgr_buffer_consumer_destroy);
|
||||
|
||||
bq_consumer->buffer_queue = bq;
|
||||
bq_consumer->queue_size = queue_size;
|
||||
bq_consumer->width = width;
|
||||
bq_consumer->height = height;
|
||||
|
||||
bq_provider = bq->provider;
|
||||
bq->consumer = bq_consumer;
|
||||
if (bq_provider)
|
||||
{
|
||||
bq_provider_send_connected(BQ_OBJECT_RESOURCE(bq_provider),
|
||||
queue_size, width, height);
|
||||
bq_consumer_send_connected(BQ_OBJECT_RESOURCE(bq_consumer));
|
||||
}
|
||||
|
||||
EINA_INLIST_FOREACH(bq->buffers,buf)
|
||||
{
|
||||
bq_buffer_create_consumer_side(bq_consumer, buf);
|
||||
bq_buffer_set_consumer_side(bq_consumer, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bq_buffer_free(Bq_Buffer *buf)
|
||||
{
|
||||
if (buf->engine)
|
||||
free(buf->engine);
|
||||
}
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_provider_attatch_buffer(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t buffer,
|
||||
const char *engine,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t format,
|
||||
uint32_t flags)
|
||||
{
|
||||
Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
|
||||
Bq_Buffer_Consumer *bq_consumer;
|
||||
Bq_Buffer_Queue *bq;
|
||||
Bq_Buffer *bq_buffer;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_provider);
|
||||
bq = bq_provider->buffer_queue;
|
||||
bq_consumer = bq->consumer;
|
||||
|
||||
bq_buffer = BQ_OBJECT_NEW(Bq_Buffer, bq_buffer_free);
|
||||
bq_buffer->provider = wl_resource_create(client, &bq_buffer_interface, 1, buffer);
|
||||
wl_resource_set_implementation(bq_buffer->provider, NULL, bq_buffer, bq_mgr_buffer_destroy);
|
||||
|
||||
if (!bq_buffer->provider)
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
bq_object_unref(BQ_OBJECT(bq_buffer));
|
||||
return;
|
||||
}
|
||||
|
||||
bq_buffer->engine = strdup(engine);
|
||||
bq_buffer->width = width;
|
||||
bq_buffer->height = height;
|
||||
bq_buffer->format = format;
|
||||
bq_buffer->flags = flags;
|
||||
|
||||
bq->buffers = eina_inlist_append(bq->buffers,EINA_INLIST_GET(bq_buffer));
|
||||
BQ_DEBUG("add BUFFER : %d\n", bq_buffer->type);
|
||||
|
||||
bq_buffer_create_consumer_side(bq_consumer, bq_buffer);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_provider_set_buffer_id(struct wl_client *client EINA_UNUSED,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *buffer,
|
||||
int32_t id,
|
||||
int32_t offset0,
|
||||
int32_t stride0,
|
||||
int32_t offset1,
|
||||
int32_t stride1,
|
||||
int32_t offset2,
|
||||
int32_t stride2)
|
||||
{
|
||||
Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
|
||||
Bq_Buffer_Consumer *bq_consumer;
|
||||
Bq_Buffer_Queue *bq;
|
||||
Bq_Buffer *bq_buffer;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_provider);
|
||||
bq = bq_provider->buffer_queue;
|
||||
bq_consumer = bq->consumer;
|
||||
bq_buffer = wl_resource_get_user_data(buffer);
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_buffer);
|
||||
|
||||
bq_buffer->type = bq_BUFFER_TYPE_ID;
|
||||
bq_buffer->id = id;
|
||||
bq_buffer->offset0 = offset0;
|
||||
bq_buffer->stride0 = stride0;
|
||||
bq_buffer->offset1 = offset1;
|
||||
bq_buffer->stride1 = stride1;
|
||||
bq_buffer->offset2 = offset2;
|
||||
bq_buffer->stride2 = stride2;
|
||||
|
||||
bq_buffer_set_consumer_side(bq_consumer, bq_buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_provider_set_buffer_fd(struct wl_client *client EINA_UNUSED,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *buffer,
|
||||
int32_t fd,
|
||||
int32_t offset0,
|
||||
int32_t stride0,
|
||||
int32_t offset1,
|
||||
int32_t stride1,
|
||||
int32_t offset2,
|
||||
int32_t stride2)
|
||||
{
|
||||
Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
|
||||
Bq_Buffer_Consumer *bq_consumer;
|
||||
Bq_Buffer_Queue *bq;
|
||||
Bq_Buffer *bq_buffer;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_provider);
|
||||
bq = bq_provider->buffer_queue;
|
||||
bq_consumer = bq->consumer;
|
||||
bq_buffer = wl_resource_get_user_data(buffer);
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_buffer);
|
||||
|
||||
bq_buffer->type = bq_BUFFER_TYPE_FD;
|
||||
bq_buffer->id = fd;
|
||||
bq_buffer->offset0 = offset0;
|
||||
bq_buffer->stride0 = stride0;
|
||||
bq_buffer->offset1 = offset1;
|
||||
bq_buffer->stride1 = stride1;
|
||||
bq_buffer->offset2 = offset2;
|
||||
bq_buffer->stride2 = stride2;
|
||||
|
||||
bq_buffer_set_consumer_side(bq_consumer, bq_buffer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_provider_detach_buffer(struct wl_client *client EINA_UNUSED,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *buffer)
|
||||
{
|
||||
Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
|
||||
Bq_Buffer_Consumer *bq_consumer;
|
||||
Bq_Buffer_Queue *bq;
|
||||
Bq_Buffer *bq_buffer;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_provider);
|
||||
bq = bq_provider->buffer_queue;
|
||||
bq_consumer = bq->consumer;
|
||||
bq_buffer = wl_resource_get_user_data(buffer);
|
||||
|
||||
if (bq_consumer)
|
||||
{
|
||||
bq_consumer_send_buffer_detached(BQ_OBJECT_RESOURCE(bq_consumer),
|
||||
bq_buffer->consumer);
|
||||
wl_resource_destroy(bq_buffer->consumer);
|
||||
bq_object_unref(BQ_OBJECT(bq_buffer));
|
||||
}
|
||||
|
||||
wl_resource_destroy(bq_buffer->provider);
|
||||
bq->buffers = eina_inlist_remove(bq->buffers,EINA_INLIST_GET(bq_buffer));
|
||||
bq_object_unref(BQ_OBJECT(bq_buffer));
|
||||
}
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_provider_enqueue_buffer(struct wl_client *client EINA_UNUSED,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *buffer,
|
||||
uint32_t serial)
|
||||
{
|
||||
Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
|
||||
Bq_Buffer_Consumer *bq_consumer;
|
||||
Bq_Buffer_Queue *bq;
|
||||
Bq_Buffer *bq_buffer;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_provider);
|
||||
bq = bq_provider->buffer_queue;
|
||||
bq_consumer = bq->consumer;
|
||||
if (!bq_consumer)
|
||||
{
|
||||
wl_resource_post_error(BQ_OBJECT_RESOURCE(bq_consumer),
|
||||
BQ_PROVIDER_ERROR_CONNECTION,
|
||||
"Not connected:%s", bq->name);
|
||||
return;
|
||||
}
|
||||
|
||||
bq_buffer = wl_resource_get_user_data(buffer);
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_buffer);
|
||||
bq_buffer->serial = serial;
|
||||
|
||||
bq_consumer_send_add_buffer(BQ_OBJECT_RESOURCE(bq_consumer),
|
||||
bq_buffer->consumer,
|
||||
bq_buffer->serial);
|
||||
}
|
||||
|
||||
static const struct bq_provider_interface _bq_provider_interface = {
|
||||
bq_mgr_buffer_provider_attatch_buffer,
|
||||
bq_mgr_buffer_provider_set_buffer_id,
|
||||
bq_mgr_buffer_provider_set_buffer_fd,
|
||||
bq_mgr_buffer_provider_detach_buffer,
|
||||
bq_mgr_buffer_provider_enqueue_buffer
|
||||
};
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_provider_destroy(struct wl_resource *resource)
|
||||
{
|
||||
Bq_Buffer_Queue *bq;
|
||||
Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
|
||||
Bq_Buffer_Consumer *bq_consumer;
|
||||
Bq_Buffer *buf;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_provider);
|
||||
BQ_DEBUG("destroy buffer provider : %s\n", bq_provider->buffer_queue->name);
|
||||
bq = bq_provider->buffer_queue;
|
||||
bq_consumer = bq->consumer;
|
||||
|
||||
BQ_OBJECT_RESOURCE(bq_provider) = NULL;
|
||||
bq->provider = NULL;
|
||||
|
||||
while (bq->buffers)
|
||||
{
|
||||
buf = EINA_INLIST_CONTAINER_GET(bq->buffers, Bq_Buffer);
|
||||
bq->buffers = eina_inlist_remove(bq->buffers, bq->buffers);
|
||||
|
||||
if (buf->consumer)
|
||||
{
|
||||
bq_consumer_send_buffer_detached(BQ_OBJECT_RESOURCE(bq_consumer), buf->consumer);
|
||||
wl_resource_destroy(buf->consumer);
|
||||
buf->consumer = NULL;
|
||||
bq_object_unref(BQ_OBJECT(buf));
|
||||
}
|
||||
|
||||
if (buf->provider)
|
||||
{
|
||||
wl_resource_destroy(buf->provider);
|
||||
buf->provider = NULL;
|
||||
bq_object_unref(BQ_OBJECT(buf));
|
||||
}
|
||||
}
|
||||
|
||||
if (bq_consumer)
|
||||
{
|
||||
if (BQ_OBJECT_RESOURCE(bq_consumer))
|
||||
bq_consumer_send_disconnected(BQ_OBJECT_RESOURCE(bq_consumer));
|
||||
}
|
||||
|
||||
bq_object_unref(BQ_OBJECT(bq_provider));
|
||||
bq_object_unref(BQ_OBJECT(bq));
|
||||
}
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_queue_create_provider(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
const char *name)
|
||||
{
|
||||
Bq_Mgr *bq_mgr = (Bq_Mgr*)wl_resource_get_user_data(resource);
|
||||
Bq_Buffer_Queue *bq;
|
||||
Bq_Buffer_Provider *bq_provider;
|
||||
Bq_Buffer_Consumer *bq_consumer;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq_mgr);
|
||||
|
||||
bq = bq_mgr_buffer_queue_new(bq_mgr,name);
|
||||
EINA_SAFETY_ON_NULL_RETURN(bq);
|
||||
|
||||
if (bq->provider)
|
||||
{
|
||||
bq_object_unref(BQ_OBJECT(bq));
|
||||
wl_resource_post_error(resource,
|
||||
BQ_MGR_ERROR_ALREADY_USED,
|
||||
"%s rpovider already used",name);
|
||||
return;
|
||||
}
|
||||
|
||||
bq_provider = BQ_OBJECT_NEW(Bq_Buffer_Provider, NULL);
|
||||
EINA_SAFETY_ON_NULL_GOTO(bq_provider, on_error);
|
||||
|
||||
BQ_OBJECT_RESOURCE(bq_provider)= wl_resource_create(client,
|
||||
&bq_provider_interface,
|
||||
1, id);
|
||||
EINA_SAFETY_ON_NULL_GOTO(BQ_OBJECT_RESOURCE(bq_provider), on_error);
|
||||
|
||||
wl_resource_set_implementation(BQ_OBJECT_RESOURCE(bq_provider),
|
||||
&_bq_provider_interface,
|
||||
bq_provider,
|
||||
bq_mgr_buffer_provider_destroy);
|
||||
|
||||
bq_provider->buffer_queue = bq;
|
||||
bq->provider = bq_provider;
|
||||
bq_consumer = bq->consumer;
|
||||
if (bq_consumer)
|
||||
{
|
||||
/*Send connect*/
|
||||
bq_consumer_send_connected(BQ_OBJECT_RESOURCE(bq_consumer));
|
||||
bq_provider_send_connected(BQ_OBJECT_RESOURCE(bq_provider),
|
||||
bq_consumer->queue_size,
|
||||
bq_consumer->width, bq_consumer->height);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
on_error:
|
||||
if (bq) bq_object_unref(BQ_OBJECT(bq));
|
||||
if (bq_provider) bq_object_unref(BQ_OBJECT(bq_provider));
|
||||
wl_client_post_no_memory(client);
|
||||
}
|
||||
|
||||
static const struct bq_mgr_interface _bq_mgr_interface =
|
||||
{
|
||||
bq_mgr_buffer_queue_create_consumer,
|
||||
bq_mgr_buffer_queue_create_provider
|
||||
};
|
||||
|
||||
static void
|
||||
bq_mgr_buffer_queue_bind(struct wl_client *client, void *data,
|
||||
uint32_t version EINA_UNUSED, uint32_t id)
|
||||
{
|
||||
Bq_Mgr *bq_mgr = (Bq_Mgr*)data;
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create(client, &bq_mgr_interface,
|
||||
1, id);
|
||||
if (resource == NULL) {
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation(resource,
|
||||
&_bq_mgr_interface,
|
||||
bq_mgr, NULL);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
bq_mgr_buffer_queue_manager_init(Bq_Mgr *bq_mgr)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(bq_mgr,EINA_FALSE);
|
||||
bq_mgr->bq_mgr = wl_global_create(bq_mgr->wdpy
|
||||
,&bq_mgr_interface,1
|
||||
,bq_mgr
|
||||
,bq_mgr_buffer_queue_bind);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(bq_mgr->bq_mgr,EINA_FALSE);
|
||||
|
||||
bq_mgr->buffer_queues = eina_hash_string_superfast_new(NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(bq_mgr->buffer_queues,EINA_FALSE);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static const Ecore_Getopt optdesc =
|
||||
{
|
||||
"tbm_daemon",
|
||||
"%prog [options]",
|
||||
"0.1.0",
|
||||
"(C) Samsung",
|
||||
"BSD 2-Clause",
|
||||
"Tizen Buffer Manager Daemon",
|
||||
EINA_FALSE,
|
||||
{
|
||||
ECORE_GETOPT_STORE_STR('s', "socket_name",
|
||||
"socket name"),
|
||||
ECORE_GETOPT_STORE_BOOL('d',"debug","enable debug log"),
|
||||
ECORE_GETOPT_VERSION('v', "version"),
|
||||
ECORE_GETOPT_HELP('h', "help"),
|
||||
ECORE_GETOPT_SENTINEL
|
||||
}
|
||||
};
|
||||
|
||||
static int
|
||||
bq_mgr_on_term_signal(int signal_number, void *data)
|
||||
{
|
||||
Bq_Mgr *bq_mgr = data;
|
||||
|
||||
BQ_LOG("caught signal %d\n", signal_number);
|
||||
wl_display_terminate(bq_mgr->wdpy);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
bq_mgr_free(Bq_Mgr *bq_mgr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = ARRAY_LENGTH(bq_mgr->signals) - 1; i >= 0; i--)
|
||||
{
|
||||
if (bq_mgr->signals[i])
|
||||
wl_event_source_remove(bq_mgr->signals[i]);
|
||||
}
|
||||
|
||||
if (bq_mgr->wdpy)
|
||||
wl_display_destroy(bq_mgr->wdpy);
|
||||
}
|
||||
|
||||
static Bq_Mgr*
|
||||
bq_mgr_new(char *sock_name)
|
||||
{
|
||||
static char *default_sock_name = "bq_mgr_daemon";
|
||||
Bq_Mgr *bq_mgr = BQ_OBJECT_NEW(Bq_Mgr, bq_mgr_free);
|
||||
struct wl_event_loop *loop;
|
||||
|
||||
if (!bq_mgr) return NULL;
|
||||
|
||||
bq_mgr->wdpy = wl_display_create();
|
||||
loop = wl_display_get_event_loop(bq_mgr->wdpy);
|
||||
EINA_SAFETY_ON_NULL_GOTO(loop, on_err);
|
||||
|
||||
bq_mgr->signals[0] = wl_event_loop_add_signal(loop, SIGTERM, bq_mgr_on_term_signal, bq_mgr);
|
||||
bq_mgr->signals[1] = wl_event_loop_add_signal(loop, SIGINT, bq_mgr_on_term_signal, bq_mgr);
|
||||
bq_mgr->signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, bq_mgr_on_term_signal, bq_mgr);
|
||||
|
||||
if (!sock_name)
|
||||
sock_name = default_sock_name;
|
||||
wl_display_add_socket(bq_mgr->wdpy, sock_name);
|
||||
|
||||
return bq_mgr;
|
||||
|
||||
on_err:
|
||||
bq_object_free(BQ_OBJECT(bq_mgr));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Bq_Mgr *bq_mgr = NULL;
|
||||
int res, ret = EXIT_FAILURE;
|
||||
char *opt_path = NULL;
|
||||
Eina_Bool quit = EINA_FALSE;
|
||||
Ecore_Getopt_Value values[] =
|
||||
{
|
||||
ECORE_GETOPT_VALUE_STR(opt_path),
|
||||
ECORE_GETOPT_VALUE_BOOL(debug),
|
||||
ECORE_GETOPT_VALUE_BOOL(quit),
|
||||
ECORE_GETOPT_VALUE_BOOL(quit),
|
||||
ECORE_GETOPT_VALUE_NONE
|
||||
};
|
||||
|
||||
eina_init();
|
||||
|
||||
res = ecore_getopt_parse(&optdesc,
|
||||
values,
|
||||
argc, argv);
|
||||
|
||||
if ((res < 0) || (quit)) goto finish;
|
||||
|
||||
if (opt_path)
|
||||
BQ_LOG("socket_name : %s\n", opt_path);
|
||||
|
||||
bq_mgr = bq_mgr_new(opt_path);
|
||||
if (!bq_mgr) goto finish;
|
||||
|
||||
if (!bq_mgr_buffer_queue_manager_init(bq_mgr))
|
||||
{
|
||||
bq_mgr_free(bq_mgr);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
wl_display_run(bq_mgr->wdpy);
|
||||
|
||||
ret = EXIT_SUCCESS;
|
||||
finish:
|
||||
eina_shutdown();
|
||||
bq_object_free(BQ_OBJECT(bq_mgr));
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
extern const struct wl_interface bq_buffer_interface;
|
||||
extern const struct wl_interface bq_consumer_interface;
|
||||
extern const struct wl_interface bq_provider_interface;
|
||||
|
||||
static const struct wl_interface *types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_consumer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_provider_interface,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message bq_mgr_requests[] = {
|
||||
{ "create_consumer", "nsiii", types + 3 },
|
||||
{ "create_provider", "ns", types + 8 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface bq_mgr_interface = {
|
||||
"bq_mgr", 1,
|
||||
2, bq_mgr_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message bq_consumer_requests[] = {
|
||||
{ "release_buffer", "o", types + 10 },
|
||||
};
|
||||
|
||||
static const struct wl_message bq_consumer_events[] = {
|
||||
{ "connected", "", types + 0 },
|
||||
{ "disconnected", "", types + 0 },
|
||||
{ "buffer_attached", "nsiiiu", types + 11 },
|
||||
{ "set_buffer_id", "oiiiiiii", types + 17 },
|
||||
{ "set_buffer_fd", "ohiiiiii", types + 25 },
|
||||
{ "buffer_detached", "o", types + 33 },
|
||||
{ "add_buffer", "ou", types + 34 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface bq_consumer_interface = {
|
||||
"bq_consumer", 1,
|
||||
1, bq_consumer_requests,
|
||||
7, bq_consumer_events,
|
||||
};
|
||||
|
||||
static const struct wl_message bq_provider_requests[] = {
|
||||
{ "attach_buffer", "nsiiiu", types + 36 },
|
||||
{ "set_buffer_id", "oiiiiiii", types + 42 },
|
||||
{ "set_buffer_fd", "ohiiiiii", types + 50 },
|
||||
{ "detach_buffer", "o", types + 58 },
|
||||
{ "enqueue_buffer", "ou", types + 59 },
|
||||
};
|
||||
|
||||
static const struct wl_message bq_provider_events[] = {
|
||||
{ "connected", "iii", types + 0 },
|
||||
{ "disconnected", "", types + 0 },
|
||||
{ "add_buffer", "ou", types + 61 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface bq_provider_interface = {
|
||||
"bq_provider", 1,
|
||||
5, bq_provider_requests,
|
||||
3, bq_provider_events,
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface bq_buffer_interface = {
|
||||
"bq_buffer", 1,
|
||||
0, NULL,
|
||||
0, NULL,
|
||||
};
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
#ifndef BQ_MGR_SERVER_PROTOCOL_H
|
||||
#define BQ_MGR_SERVER_PROTOCOL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-server.h"
|
||||
|
||||
struct wl_client;
|
||||
struct wl_resource;
|
||||
|
||||
struct bq_mgr;
|
||||
struct bq_consumer;
|
||||
struct bq_provider;
|
||||
struct bq_buffer;
|
||||
|
||||
extern const struct wl_interface bq_mgr_interface;
|
||||
extern const struct wl_interface bq_consumer_interface;
|
||||
extern const struct wl_interface bq_provider_interface;
|
||||
extern const struct wl_interface bq_buffer_interface;
|
||||
|
||||
#ifndef BQ_MGR_ERROR_ENUM
|
||||
#define BQ_MGR_ERROR_ENUM
|
||||
enum bq_mgr_error {
|
||||
BQ_MGR_ERROR_INVALID_PERMISSION = 0,
|
||||
BQ_MGR_ERROR_INVALID_NAME = 1,
|
||||
BQ_MGR_ERROR_ALREADY_USED = 2,
|
||||
};
|
||||
#endif /* BQ_MGR_ERROR_ENUM */
|
||||
|
||||
struct bq_mgr_interface {
|
||||
/**
|
||||
* create_consumer - (none)
|
||||
* @id: (none)
|
||||
* @name: (none)
|
||||
* @queue_size: (none)
|
||||
* @width: (none)
|
||||
* @height: (none)
|
||||
*/
|
||||
void (*create_consumer)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
const char *name,
|
||||
int32_t queue_size,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
/**
|
||||
* create_provider - (none)
|
||||
* @id: (none)
|
||||
* @name: (none)
|
||||
*/
|
||||
void (*create_provider)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
const char *name);
|
||||
};
|
||||
|
||||
|
||||
struct bq_consumer_interface {
|
||||
/**
|
||||
* release_buffer - (none)
|
||||
* @buffer: (none)
|
||||
*/
|
||||
void (*release_buffer)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *buffer);
|
||||
};
|
||||
|
||||
#define BQ_CONSUMER_CONNECTED 0
|
||||
#define BQ_CONSUMER_DISCONNECTED 1
|
||||
#define BQ_CONSUMER_BUFFER_ATTACHED 2
|
||||
#define BQ_CONSUMER_SET_BUFFER_ID 3
|
||||
#define BQ_CONSUMER_SET_BUFFER_FD 4
|
||||
#define BQ_CONSUMER_BUFFER_DETACHED 5
|
||||
#define BQ_CONSUMER_ADD_BUFFER 6
|
||||
|
||||
#define BQ_CONSUMER_CONNECTED_SINCE_VERSION 1
|
||||
#define BQ_CONSUMER_DISCONNECTED_SINCE_VERSION 1
|
||||
#define BQ_CONSUMER_BUFFER_ATTACHED_SINCE_VERSION 1
|
||||
#define BQ_CONSUMER_SET_BUFFER_ID_SINCE_VERSION 1
|
||||
#define BQ_CONSUMER_SET_BUFFER_FD_SINCE_VERSION 1
|
||||
#define BQ_CONSUMER_BUFFER_DETACHED_SINCE_VERSION 1
|
||||
#define BQ_CONSUMER_ADD_BUFFER_SINCE_VERSION 1
|
||||
|
||||
static inline void
|
||||
bq_consumer_send_connected(struct wl_resource *resource_)
|
||||
{
|
||||
wl_resource_post_event(resource_, BQ_CONSUMER_CONNECTED);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_consumer_send_disconnected(struct wl_resource *resource_)
|
||||
{
|
||||
wl_resource_post_event(resource_, BQ_CONSUMER_DISCONNECTED);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_consumer_send_buffer_attached(struct wl_resource *resource_, struct wl_resource *buffer, const char *engine, int32_t width, int32_t height, int32_t format, uint32_t flags)
|
||||
{
|
||||
wl_resource_post_event(resource_, BQ_CONSUMER_BUFFER_ATTACHED, buffer, engine, width, height, format, flags);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_consumer_send_set_buffer_id(struct wl_resource *resource_, struct wl_resource *buffer, int32_t id, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
|
||||
{
|
||||
wl_resource_post_event(resource_, BQ_CONSUMER_SET_BUFFER_ID, buffer, id, offset0, stride0, offset1, stride1, offset2, stride2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_consumer_send_set_buffer_fd(struct wl_resource *resource_, struct wl_resource *buffer, int32_t fd, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
|
||||
{
|
||||
wl_resource_post_event(resource_, BQ_CONSUMER_SET_BUFFER_FD, buffer, fd, offset0, stride0, offset1, stride1, offset2, stride2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_consumer_send_buffer_detached(struct wl_resource *resource_, struct wl_resource *buffer)
|
||||
{
|
||||
wl_resource_post_event(resource_, BQ_CONSUMER_BUFFER_DETACHED, buffer);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_consumer_send_add_buffer(struct wl_resource *resource_, struct wl_resource *buffer, uint32_t serial)
|
||||
{
|
||||
wl_resource_post_event(resource_, BQ_CONSUMER_ADD_BUFFER, buffer, serial);
|
||||
}
|
||||
|
||||
#ifndef BQ_PROVIDER_ERROR_ENUM
|
||||
#define BQ_PROVIDER_ERROR_ENUM
|
||||
enum bq_provider_error {
|
||||
BQ_PROVIDER_ERROR_OVERFLOW_QUEUE_SIZE = 0,
|
||||
BQ_PROVIDER_ERROR_CONNECTION = 1,
|
||||
};
|
||||
#endif /* BQ_PROVIDER_ERROR_ENUM */
|
||||
|
||||
struct bq_provider_interface {
|
||||
/**
|
||||
* attach_buffer - (none)
|
||||
* @buffer: (none)
|
||||
* @engine: (none)
|
||||
* @width: (none)
|
||||
* @height: (none)
|
||||
* @format: (none)
|
||||
* @flags: (none)
|
||||
*/
|
||||
void (*attach_buffer)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t buffer,
|
||||
const char *engine,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t format,
|
||||
uint32_t flags);
|
||||
/**
|
||||
* set_buffer_id - (none)
|
||||
* @buffer: (none)
|
||||
* @id: (none)
|
||||
* @offset0: (none)
|
||||
* @stride0: (none)
|
||||
* @offset1: (none)
|
||||
* @stride1: (none)
|
||||
* @offset2: (none)
|
||||
* @stride2: (none)
|
||||
*/
|
||||
void (*set_buffer_id)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *buffer,
|
||||
int32_t id,
|
||||
int32_t offset0,
|
||||
int32_t stride0,
|
||||
int32_t offset1,
|
||||
int32_t stride1,
|
||||
int32_t offset2,
|
||||
int32_t stride2);
|
||||
/**
|
||||
* set_buffer_fd - (none)
|
||||
* @buffer: (none)
|
||||
* @fd: (none)
|
||||
* @offset0: (none)
|
||||
* @stride0: (none)
|
||||
* @offset1: (none)
|
||||
* @stride1: (none)
|
||||
* @offset2: (none)
|
||||
* @stride2: (none)
|
||||
*/
|
||||
void (*set_buffer_fd)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *buffer,
|
||||
int32_t fd,
|
||||
int32_t offset0,
|
||||
int32_t stride0,
|
||||
int32_t offset1,
|
||||
int32_t stride1,
|
||||
int32_t offset2,
|
||||
int32_t stride2);
|
||||
/**
|
||||
* detach_buffer - (none)
|
||||
* @buffer: (none)
|
||||
*/
|
||||
void (*detach_buffer)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *buffer);
|
||||
/**
|
||||
* enqueue_buffer - (none)
|
||||
* @buffer: (none)
|
||||
* @serial: (none)
|
||||
*/
|
||||
void (*enqueue_buffer)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *buffer,
|
||||
uint32_t serial);
|
||||
};
|
||||
|
||||
#define BQ_PROVIDER_CONNECTED 0
|
||||
#define BQ_PROVIDER_DISCONNECTED 1
|
||||
#define BQ_PROVIDER_ADD_BUFFER 2
|
||||
|
||||
#define BQ_PROVIDER_CONNECTED_SINCE_VERSION 1
|
||||
#define BQ_PROVIDER_DISCONNECTED_SINCE_VERSION 1
|
||||
#define BQ_PROVIDER_ADD_BUFFER_SINCE_VERSION 1
|
||||
|
||||
static inline void
|
||||
bq_provider_send_connected(struct wl_resource *resource_, int32_t queue_size, int32_t width, int32_t height)
|
||||
{
|
||||
wl_resource_post_event(resource_, BQ_PROVIDER_CONNECTED, queue_size, width, height);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_provider_send_disconnected(struct wl_resource *resource_)
|
||||
{
|
||||
wl_resource_post_event(resource_, BQ_PROVIDER_DISCONNECTED);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_provider_send_add_buffer(struct wl_resource *resource_, struct wl_resource *buffer, uint32_t serial)
|
||||
{
|
||||
wl_resource_post_event(resource_, BQ_PROVIDER_ADD_BUFFER, buffer, serial);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -43,3 +43,6 @@
|
|||
/ecore_thread_example
|
||||
/ecore_time_functions_example
|
||||
/ecore_timer_example
|
||||
/ecore_buffer_example
|
||||
/ecore_buffer_consumer_example
|
||||
/ecore_buffer_provider_example
|
||||
|
|
|
@ -8,6 +8,7 @@ AM_CPPFLAGS = \
|
|||
-I$(top_srcdir)/src/lib/eo \
|
||||
-I$(top_srcdir)/src/lib/evas \
|
||||
-I$(top_srcdir)/src/lib/ecore \
|
||||
-I$(top_srcdir)/src/lib/ecore_buffer \
|
||||
-I$(top_srcdir)/src/lib/ecore_input \
|
||||
-I$(top_srcdir)/src/lib/ecore_input_evas \
|
||||
-I$(top_srcdir)/src/lib/ecore_file \
|
||||
|
@ -35,6 +36,9 @@ AM_CPPFLAGS = \
|
|||
|
||||
EXTRA_PROGRAMS = \
|
||||
ecore_animator_example \
|
||||
ecore_buffer_example \
|
||||
ecore_buffer_consumer_example \
|
||||
ecore_buffer_provider_example \
|
||||
ecore_client_bench \
|
||||
ecore_compose_get_example \
|
||||
ecore_con_client_example \
|
||||
|
@ -112,6 +116,18 @@ $(ECORE_COMMON_LDADD)
|
|||
ecore_animator_example_SOURCES = ecore_animator_example.c
|
||||
ecore_animator_example_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
||||
|
||||
ecore_buffer_example_SOURCES = ecore_buffer_example.c
|
||||
ecore_buffer_example_LDADD = $(ECORE_EVAS_COMMON_LDADD) \
|
||||
$(top_builddir)/src/lib/ecore_buffer/libecore_buffer.la
|
||||
|
||||
ecore_buffer_consumer_example_SOURCES = ecore_buffer_consumer_example.c
|
||||
ecore_buffer_consumer_example_LDADD = $(ECORE_EVAS_COMMON_LDADD) \
|
||||
$(top_builddir)/src/lib/ecore_buffer/libecore_buffer.la
|
||||
|
||||
ecore_buffer_provider_example_SOURCES = ecore_buffer_provider_example.c
|
||||
ecore_buffer_provider_example_LDADD = $(ECORE_EVAS_COMMON_LDADD) \
|
||||
$(top_builddir)/src/lib/ecore_buffer/libecore_buffer.la
|
||||
|
||||
ecore_client_bench_SOURCES = ecore_client_bench.c
|
||||
ecore_client_bench_LDADD = $(ECORE_CON_COMMON_LDADD)
|
||||
|
||||
|
@ -249,6 +265,9 @@ ecore_con_eet_server_example_LDADD = $(ECORE_CON_COMMON_LDADD)
|
|||
|
||||
SRCS = \
|
||||
ecore_animator_example.c \
|
||||
ecore_buffer_example.c \
|
||||
ecore_buffer_consumer_example.c \
|
||||
ecore_buffer_provider_example.c \
|
||||
ecore_audio_custom.c \
|
||||
ecore_audio_playback.c \
|
||||
ecore_audio_to_ogg.c \
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
#include <stdio.h>
|
||||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Evas.h>
|
||||
#include <Ecore_Buffer.h>
|
||||
#include <Ecore_Buffer_Queue.h>
|
||||
#include <Evas.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOG(f, x...) printf("[CONSUMER|%30.30s|%04d] " f "\n", __func__, __LINE__, ##x)
|
||||
#else
|
||||
#define LOG(f, x...)
|
||||
#endif
|
||||
|
||||
#define WIDTH 720
|
||||
#define HEIGHT 960
|
||||
|
||||
typedef struct _Consumer_Data
|
||||
{
|
||||
Ecore_Buffer_Consumer *consumer;
|
||||
Ecore_Buffer *buffer;
|
||||
Ecore_Job *render_job;
|
||||
struct
|
||||
{
|
||||
Evas *e;
|
||||
Ecore_Evas *ee;
|
||||
Evas_Object *bg, *img;
|
||||
} win;
|
||||
} Consumer_Data;
|
||||
|
||||
const char *name = "ecore_buffer_queue_test";
|
||||
|
||||
static void
|
||||
shutdown_all(void)
|
||||
{
|
||||
ecore_buffer_queue_shutdown();
|
||||
ecore_buffer_shutdown();
|
||||
ecore_evas_shutdown();
|
||||
ecore_shutdown();
|
||||
eina_shutdown();
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
init_all(void)
|
||||
{
|
||||
if (!eina_init()) goto err;
|
||||
if (!ecore_init()) goto err;
|
||||
if (!ecore_evas_init()) goto err;
|
||||
if (!ecore_buffer_init()) goto err;
|
||||
if (!ecore_buffer_queue_init()) goto err;
|
||||
|
||||
return EINA_TRUE;
|
||||
err:
|
||||
shutdown_all();
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_render_post(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Consumer_Data *cd = (Consumer_Data *)data;
|
||||
|
||||
if (cd->buffer)
|
||||
{
|
||||
ecore_buffer_consumer_buffer_release(cd->consumer, cd->buffer);
|
||||
cd->buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_consumer_cb_render_job(void *data)
|
||||
{
|
||||
Consumer_Data *cd = (Consumer_Data *)data;
|
||||
void *pixel_data;
|
||||
unsigned int w, h;
|
||||
|
||||
LOG("Startup - Render");
|
||||
|
||||
if (!(cd->buffer = ecore_buffer_consumer_buffer_dequeue(cd->consumer)))
|
||||
{
|
||||
LOG("Failed to dequeue buffer");
|
||||
goto end;
|
||||
}
|
||||
|
||||
LOG("Success to get Compositable Buffer, "
|
||||
"Drawing it to Consumer's Canvas now... - buffer:%p", cd->buffer);
|
||||
// Get pixel data and set it to object.
|
||||
pixel_data = ecore_buffer_data_get(cd->buffer);
|
||||
ecore_buffer_size_get(cd->buffer, &w, &h);
|
||||
evas_object_image_data_set(cd->win.img, pixel_data);
|
||||
evas_object_image_data_update_add(cd->win.img, 0, 0, w, h);
|
||||
|
||||
ecore_job_del(cd->render_job);
|
||||
cd->render_job = NULL;
|
||||
|
||||
end:
|
||||
LOG("Done - Render");
|
||||
}
|
||||
|
||||
static void
|
||||
_consumer_render_queue(Consumer_Data *cd)
|
||||
{
|
||||
if (!cd) return;
|
||||
|
||||
LOG("Render Queue");
|
||||
|
||||
if (!cd->render_job)
|
||||
cd->render_job = ecore_job_add(_consumer_cb_render_job, cd);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_provider_add(Ecore_Buffer_Consumer *consumer EINA_UNUSED, void *data EINA_UNUSED)
|
||||
{
|
||||
LOG("Connected with Provider");
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_provider_del(Ecore_Buffer_Consumer *consumer EINA_UNUSED, void *data EINA_UNUSED)
|
||||
{
|
||||
LOG("Disconnected with Provider, Shutdown Consumer now.");
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_buffer_enqueued(Ecore_Buffer_Consumer *consumer EINA_UNUSED, void *data)
|
||||
{
|
||||
Consumer_Data *cd = (Consumer_Data *)data;
|
||||
|
||||
LOG("Buffer Enqueued");
|
||||
|
||||
_consumer_render_queue(cd);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
Consumer_Data *cd;
|
||||
Evas_Object *o;
|
||||
const int queue_size = 3;
|
||||
|
||||
if (!init_all())
|
||||
{
|
||||
LOG("Initializing failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cd = (Consumer_Data *)calloc(sizeof(Consumer_Data), 1);
|
||||
|
||||
if (!(cd->consumer = ecore_buffer_consumer_new(name, queue_size, WIDTH, HEIGHT)))
|
||||
{
|
||||
LOG("Failed to create consumer");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
ecore_buffer_consumer_provider_add_cb_set(cd->consumer, _cb_provider_add, cd);
|
||||
ecore_buffer_consumer_provider_del_cb_set(cd->consumer, _cb_provider_del, cd);
|
||||
ecore_buffer_consumer_buffer_enqueued_cb_set(cd->consumer, _cb_buffer_enqueued, cd);
|
||||
|
||||
cd->win.ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
|
||||
cd->win.e = ecore_evas_get(cd->win.ee);
|
||||
|
||||
o = evas_object_rectangle_add(cd->win.e);
|
||||
evas_object_move(o, 0, 0);
|
||||
evas_object_resize(o, WIDTH, HEIGHT);
|
||||
evas_object_color_set(o, 255, 0, 0, 255);
|
||||
evas_object_show(o);
|
||||
cd->win.bg = o;
|
||||
|
||||
o = evas_object_image_add(cd->win.e);
|
||||
evas_object_image_fill_set(o, 0, 0, WIDTH, HEIGHT);
|
||||
evas_object_image_size_set(o, WIDTH, HEIGHT);
|
||||
|
||||
evas_object_move(o, 0, 0);
|
||||
evas_object_resize(o, WIDTH, HEIGHT);
|
||||
evas_object_show(o);
|
||||
cd->win.img = o;
|
||||
|
||||
ecore_evas_show(cd->win.ee);
|
||||
|
||||
evas_event_callback_add(cd->win.e, EVAS_CALLBACK_RENDER_POST, _cb_render_post, cd);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
shutdown:
|
||||
if (cd->win.ee) ecore_evas_free(cd->win.ee);
|
||||
if (cd->buffer) ecore_buffer_consumer_buffer_release(cd->consumer, cd->buffer);
|
||||
if (cd->consumer) ecore_buffer_consumer_free(cd->consumer);
|
||||
if (cd) free(cd);
|
||||
|
||||
shutdown_all();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
#include <stdio.h>
|
||||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Evas.h>
|
||||
#include <Evas.h>
|
||||
#include <Ecore_Buffer.h>
|
||||
#include <Ecore_Buffer_Queue.h>
|
||||
|
||||
#define WIDTH 720
|
||||
#define HEIGHT 960
|
||||
|
||||
struct _Window
|
||||
{
|
||||
Evas *e;
|
||||
Ecore_Evas *ee;
|
||||
Evas_Object *bg, *img;
|
||||
Ecore_Buffer *buffer;
|
||||
};
|
||||
|
||||
struct _Window win;
|
||||
Eina_List *hdls;
|
||||
|
||||
static void
|
||||
paint_pixels(void *image, int padding, int width, int height, uint32_t time)
|
||||
{
|
||||
const int halfh = padding + (height - padding * 2) / 2;
|
||||
const int halfw = padding + (width - padding * 2) / 2;
|
||||
int ir, or;
|
||||
uint32_t *pixel = image;
|
||||
int y;
|
||||
|
||||
/* squared radii thresholds */
|
||||
or = (halfw < halfh ? halfw : halfh) - 8;
|
||||
ir = or - 32;
|
||||
or *= or;
|
||||
ir *= ir;
|
||||
|
||||
pixel += padding * width;
|
||||
for (y = padding; y < height - padding; y++) {
|
||||
int x;
|
||||
int y2 = (y - halfh) * (y - halfh);
|
||||
|
||||
pixel += padding;
|
||||
for (x = padding; x < width - padding; x++) {
|
||||
uint32_t v;
|
||||
|
||||
/* squared distance from center */
|
||||
int r2 = (x - halfw) * (x - halfw) + y2;
|
||||
|
||||
if (r2 < ir)
|
||||
v = (r2 / 32 + time / 64) * 0x0080401;
|
||||
else if (r2 < or)
|
||||
v = (y + time / 32) * 0x0080401;
|
||||
else
|
||||
v = (x + time / 16) * 0x0080401;
|
||||
v &= 0x00ffffff;
|
||||
v |= 0xff000000;
|
||||
|
||||
*pixel++ = v;
|
||||
}
|
||||
|
||||
pixel += padding;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_post_render(Ecore_Evas *ee EINA_UNUSED)
|
||||
{
|
||||
void *data;
|
||||
|
||||
// Get pixel data and update.
|
||||
data = ecore_buffer_data_get(win.buffer);
|
||||
paint_pixels(data, 0, WIDTH, HEIGHT, ecore_loop_time_get() * 1000);
|
||||
evas_object_image_data_set(win.img, data);
|
||||
evas_object_image_data_update_add(win.img, 0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
Evas_Object *o;
|
||||
void *data;
|
||||
|
||||
eina_init();
|
||||
ecore_init();
|
||||
ecore_evas_init();
|
||||
ecore_buffer_init();
|
||||
|
||||
win.ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
|
||||
win.e = ecore_evas_get(win.ee);
|
||||
|
||||
o = evas_object_rectangle_add(win.e);
|
||||
evas_object_move(o, 0, 0);
|
||||
evas_object_resize(o, WIDTH, HEIGHT);
|
||||
evas_object_color_set(o, 255, 0, 0, 255);
|
||||
evas_object_show(o);
|
||||
win.bg = o;
|
||||
|
||||
o = evas_object_image_add(win.e);
|
||||
evas_object_image_fill_set(o, 0, 0, WIDTH, HEIGHT);
|
||||
evas_object_image_size_set(o, WIDTH, HEIGHT);
|
||||
|
||||
evas_object_move(o, 0, 0);
|
||||
evas_object_resize(o, WIDTH, HEIGHT);
|
||||
evas_object_show(o);
|
||||
win.img = o;
|
||||
|
||||
// Create buffer and drawing.
|
||||
win.buffer = ecore_buffer_new("shm", WIDTH, HEIGHT, 0, 0);
|
||||
data = ecore_buffer_data_get(win.buffer);
|
||||
paint_pixels(data, 0, WIDTH, HEIGHT, 0);
|
||||
evas_object_image_data_set(win.img, data);
|
||||
evas_object_image_data_update_add(win.img, 0, 0, WIDTH, HEIGHT);
|
||||
|
||||
ecore_evas_show(win.ee);
|
||||
|
||||
ecore_evas_callback_post_render_set(win.ee, _cb_post_render);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
ecore_buffer_free(win.buffer);
|
||||
ecore_buffer_shutdown();
|
||||
ecore_evas_shutdown();
|
||||
ecore_shutdown();
|
||||
eina_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,274 @@
|
|||
#include <stdio.h>
|
||||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Evas.h>
|
||||
#include <Ecore_Buffer.h>
|
||||
#include <Ecore_Buffer_Queue.h>
|
||||
#include <Evas.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOG(f, x...) printf("[PROVIDER|%30.30s|%04d] " f "\n", __func__, __LINE__, ##x)
|
||||
#else
|
||||
#define LOG(f, x...)
|
||||
#endif
|
||||
|
||||
typedef struct _Provider_Data
|
||||
{
|
||||
Ecore_Buffer_Provider *provider;
|
||||
Ecore_Buffer *buffer;
|
||||
Eina_List *buffer_list;
|
||||
Ecore_Job *render_job;
|
||||
Ecore_Idle_Enterer *post_render;
|
||||
unsigned int w, h;
|
||||
} Provider_Data;
|
||||
|
||||
const char *name = "ecore_buffer_queue_test";
|
||||
|
||||
static void _provider_render_queue(Provider_Data *pd);
|
||||
|
||||
static void
|
||||
shutdown_all(void)
|
||||
{
|
||||
ecore_buffer_queue_shutdown();
|
||||
ecore_buffer_shutdown();
|
||||
ecore_evas_shutdown();
|
||||
ecore_shutdown();
|
||||
eina_shutdown();
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
init_all(void)
|
||||
{
|
||||
if (!eina_init()) goto err;
|
||||
if (!ecore_init()) goto err;
|
||||
if (!ecore_evas_init()) goto err;
|
||||
if (!ecore_buffer_init()) goto err;
|
||||
if (!ecore_buffer_queue_init()) goto err;
|
||||
|
||||
return EINA_TRUE;
|
||||
err:
|
||||
shutdown_all();
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
Ecore_Buffer *
|
||||
_provider_buffer_get(Provider_Data *pd, unsigned int w, unsigned int h, unsigned int format)
|
||||
{
|
||||
Ecore_Buffer *buffer = NULL;
|
||||
Ecore_Buffer_Return ret;
|
||||
unsigned int res_w, res_h, res_format;
|
||||
|
||||
LOG("Dequeue");
|
||||
ret = ecore_buffer_provider_buffer_acquire(pd->provider, &buffer);
|
||||
|
||||
if (ret == ECORE_BUFFER_RETURN_NEED_ALLOC)
|
||||
{
|
||||
buffer = ecore_buffer_new("shm", w, h, format, 0);
|
||||
pd->buffer_list = eina_list_append(pd->buffer_list, buffer);
|
||||
LOG("No buffer in Queue, Create Buffer");
|
||||
}
|
||||
else if (ret == ECORE_BUFFER_RETURN_SUCCESS)
|
||||
{
|
||||
ecore_buffer_size_get(buffer, &res_w, &res_h);
|
||||
res_format = ecore_buffer_format_get(buffer);
|
||||
if ((res_w != w) || (res_h != h) || (res_format != format))
|
||||
{
|
||||
LOG("Need to Reallocate Buffer, Free it First: %p", buffer);
|
||||
pd->buffer_list = eina_list_remove(pd->buffer_list, buffer);
|
||||
ecore_buffer_free(buffer);
|
||||
|
||||
buffer = ecore_buffer_new("shm", w, h, format, 0);
|
||||
pd->buffer_list = eina_list_append(pd->buffer_list, buffer);
|
||||
LOG("Create Buffer: %p", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
paint_pixels(void *image, int padding, int width, int height, uint32_t time)
|
||||
{
|
||||
const int halfh = padding + (height - padding * 2) / 2;
|
||||
const int halfw = padding + (width - padding * 2) / 2;
|
||||
int ir, or;
|
||||
uint32_t *pixel = image;
|
||||
int y;
|
||||
|
||||
/* squared radii thresholds */
|
||||
or = (halfw < halfh ? halfw : halfh) - 8;
|
||||
ir = or - 32;
|
||||
or *= or;
|
||||
ir *= ir;
|
||||
|
||||
pixel += padding * width;
|
||||
for (y = padding; y < height - padding; y++) {
|
||||
int x;
|
||||
int y2 = (y - halfh) * (y - halfh);
|
||||
|
||||
pixel += padding;
|
||||
for (x = padding; x < width - padding; x++) {
|
||||
uint32_t v;
|
||||
|
||||
/* squared distance from center */
|
||||
int r2 = (x - halfw) * (x - halfw) + y2;
|
||||
|
||||
if (r2 < ir)
|
||||
v = (r2 / 32 + time / 64) * 0x0080401;
|
||||
else if (r2 < or)
|
||||
v = (y + time / 32) * 0x0080401;
|
||||
else
|
||||
v = (x + time / 16) * 0x0080401;
|
||||
v &= 0x00ffffff;
|
||||
v |= 0xff000000;
|
||||
|
||||
*pixel++ = v;
|
||||
}
|
||||
|
||||
pixel += padding;
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_cb_render_post(void *data)
|
||||
{
|
||||
Provider_Data *pd = (Provider_Data *)data;
|
||||
Ecore_Buffer *next_buffer = NULL;
|
||||
|
||||
LOG("Startup - Post Render");
|
||||
|
||||
LOG("Submit Buffer - buffer: %p", pd->buffer);
|
||||
ecore_buffer_provider_buffer_enqueue(pd->provider, pd->buffer);
|
||||
pd->buffer = NULL;
|
||||
|
||||
next_buffer = _provider_buffer_get(pd, pd->w, pd->h, ECORE_BUFFER_FORMAT_XRGB8888);
|
||||
if (next_buffer)
|
||||
{
|
||||
LOG("Drawable Buffer is Existed, ADD Render job again - buffer:%p", next_buffer);
|
||||
pd->buffer = next_buffer;
|
||||
_provider_render_queue(pd);
|
||||
}
|
||||
|
||||
ecore_idle_enterer_del(pd->post_render);
|
||||
pd->post_render = NULL;
|
||||
|
||||
LOG("Done - Post Render");
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static void
|
||||
_provider_cb_render_job(void *data)
|
||||
{
|
||||
Provider_Data *pd = (Provider_Data *)data;
|
||||
|
||||
LOG("Startup - Render");
|
||||
|
||||
if (!pd->buffer)
|
||||
{
|
||||
pd->buffer = _provider_buffer_get(pd,
|
||||
pd->w, pd->h, ECORE_BUFFER_FORMAT_XRGB8888);
|
||||
}
|
||||
|
||||
if (pd->buffer)
|
||||
{
|
||||
void *data;
|
||||
|
||||
LOG("Success to get Drawable Buffer, Drawing now... - buffer:%p", pd->buffer);
|
||||
// Drawing...
|
||||
data = ecore_buffer_data_get(pd->buffer);
|
||||
paint_pixels(data, 0, pd->w, pd->h, ecore_loop_time_get() * 1000);
|
||||
|
||||
if (!pd->post_render)
|
||||
{
|
||||
pd->post_render =
|
||||
ecore_idle_enterer_before_add(_cb_render_post, pd);
|
||||
}
|
||||
}
|
||||
|
||||
ecore_job_del(pd->render_job);
|
||||
pd->render_job = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_provider_render_queue(Provider_Data *pd)
|
||||
{
|
||||
if (!pd) return;
|
||||
|
||||
LOG("Render Queue");
|
||||
|
||||
if (!pd->render_job)
|
||||
pd->render_job = ecore_job_add(_provider_cb_render_job, pd);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_consumer_add(Ecore_Buffer_Provider *provider EINA_UNUSED, int queue_size EINA_UNUSED, int w, int h, void *data)
|
||||
{
|
||||
Provider_Data *pd = (Provider_Data *)data;
|
||||
|
||||
LOG("Connected with Consumer, Now We can use Ecore_Buffer_Queue - queue_size:%d, geo(%dx%d)",
|
||||
queue_size, w, h);
|
||||
|
||||
pd->w = w;
|
||||
pd->h = h;
|
||||
|
||||
_provider_render_queue(pd);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_consumer_del(Ecore_Buffer_Provider *provider EINA_UNUSED, void *data EINA_UNUSED)
|
||||
{
|
||||
LOG("Disconnected with Consumer, Shutdown Provider now.");
|
||||
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_buffer_released(Ecore_Buffer_Provider *provider EINA_UNUSED, void *data)
|
||||
{
|
||||
Provider_Data *pd = (Provider_Data *)data;
|
||||
|
||||
LOG("Buffer Enqueued");
|
||||
|
||||
_provider_render_queue(pd);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
Provider_Data *pd;
|
||||
|
||||
if (!init_all())
|
||||
{
|
||||
LOG("Initializing failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pd = (Provider_Data *)calloc(sizeof(Provider_Data), 1);
|
||||
|
||||
if (!(pd->provider = ecore_buffer_provider_new(name)))
|
||||
{
|
||||
LOG("Failed to create provider");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
ecore_buffer_provider_consumer_add_cb_set(pd->provider, _cb_consumer_add, pd);
|
||||
ecore_buffer_provider_consumer_del_cb_set(pd->provider, _cb_consumer_del, pd);
|
||||
ecore_buffer_provider_buffer_released_cb_set(pd->provider, _cb_buffer_released, pd);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
shutdown:
|
||||
if (pd->buffer_list)
|
||||
{
|
||||
Ecore_Buffer *b;
|
||||
|
||||
EINA_LIST_FREE(pd->buffer_list, b)
|
||||
ecore_buffer_free(b);
|
||||
}
|
||||
if (pd->provider) ecore_buffer_provider_free(pd->provider);
|
||||
if (pd) free(pd);
|
||||
|
||||
shutdown_all();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,629 @@
|
|||
#ifndef _ECORE_BUFFER_H_
|
||||
# define _ECORE_BUFFER_H_
|
||||
|
||||
#ifdef EAPI
|
||||
# undef EAPI
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef EFL_ECORE_BUFFER_BUILD
|
||||
# ifdef DLL_EXPORT
|
||||
# define EAPI __declspec(dllexport)
|
||||
# else
|
||||
# define EAPI
|
||||
# endif /* ! DLL_EXPORT */
|
||||
# else
|
||||
# define EAPI __declspec(dllimport)
|
||||
# endif /* ! EFL_ECORE_BUFFER_BUILD */
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ >= 4
|
||||
# define EAPI __attribute__ ((visibility("default")))
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
#endif /* ! _WIN32 */
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Buffer_Group Ecore_Buffer - Graphics buffer functions
|
||||
* @ingroup Ecore
|
||||
*
|
||||
* The Ecore Buffer is an abstraction of graphic buffer.
|
||||
*
|
||||
* This library also provides simple mechanisms for sharing graphic buffer bet-
|
||||
* ween processes using wayland socket. Ecore Buffer Queue is for this
|
||||
* function, and it consists of two main object,
|
||||
* The Ecore_Buffer_Consumer and the Ecore_Buffer_Provider.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define __ecore_buffer_fourcc_code(a,b,c,d) ((unsigned int)(a) | ((unsigned int)(b) << 8) | \
|
||||
((unsigned int)(c) << 16) | ((unsigned int)(d) << 24))
|
||||
|
||||
/* color index */
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format C8 ([7:0] C).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_C8 __ecore_buffer_fourcc_code('C', '8', ' ', ' ')
|
||||
/* 8 bpp RGB */
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGB332 ([7:0] R:G:B 3:3:2).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGB332 __ecore_buffer_fourcc_code('R', 'G', 'B', '8')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGB233 ([7:0] B:G:R 2:3:3).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGR233 __ecore_buffer_fourcc_code('B', 'G', 'R', '8')
|
||||
/* 16 bpp RGB */
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format XRGB4444 ([15:0] x:R:G:B 4:4:4:4 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_XRGB4444 __ecore_buffer_fourcc_code('X', 'R', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format XBRG4444 ([15:0] x:B:G:R 4:4:4:4 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_XBGR4444 __ecore_buffer_fourcc_code('X', 'B', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGBX4444 ([15:0] R:G:B:x 4:4:4:4 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGBX4444 __ecore_buffer_fourcc_code('R', 'X', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format BGRX4444 ([15:0] B:G:R:x 4:4:4:4 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGRX4444 __ecore_buffer_fourcc_code('B', 'X', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format ARGB4444 ([15:0] A:R:G:B 4:4:4:4 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_ARGB4444 __ecore_buffer_fourcc_code('A', 'R', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format ABGR4444 ([15:0] A:B:G:R 4:4:4:4 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_ABGR4444 __ecore_buffer_fourcc_code('A', 'B', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGBA4444 ([15:0] R:G:B:A 4:4:4:4 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGBA4444 __ecore_buffer_fourcc_code('R', 'A', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format BGRA4444 ([15:0] B:G:R:A 4:4:4:4 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGRA4444 __ecore_buffer_fourcc_code('B', 'A', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format XRGB1555 ([15:0] x:R:G:B 1:5:5:5 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_XRGB1555 __ecore_buffer_fourcc_code('X', 'R', '1', '5')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format XBGR1555 ([15:0] x:B:G:R 1:5:5:5 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_XBGR1555 __ecore_buffer_fourcc_code('X', 'B', '1', '5')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGBX5551 ([15:0] R:G:B:x 5:5:5:1 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGBX5551 __ecore_buffer_fourcc_code('R', 'X', '1', '5')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format BGRX5551 ([15:0] B:G:R:x 5:5:5:1 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGRX5551 __ecore_buffer_fourcc_code('B', 'X', '1', '5')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format ARGB1555 ([15:0] A:R:G:B 1:5:5:5 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_ARGB1555 __ecore_buffer_fourcc_code('A', 'R', '1', '5')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format ABGR1555 ([15:0] A:B:G:R 1:5:5:5 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_ABGR1555 __ecore_buffer_fourcc_code('A', 'B', '1', '5')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGBA5551 ([15:0] R:G:B:A 5:5:5:1 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGBA5551 __ecore_buffer_fourcc_code('R', 'A', '1', '5')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format BGRA5551 ([15:0] B:G:R:A 5:5:5:1 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGRA5551 __ecore_buffer_fourcc_code('B', 'A', '1', '5')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGB565 ([15:0] R:G:B 5:6:5 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGB565 __ecore_buffer_fourcc_code('R', 'G', '1', '6')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format BGR565 ([15:0] B:G:R 5:6:5 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGR565 __ecore_buffer_fourcc_code('B', 'G', '1', '6')
|
||||
/* 24 bpp RGB */
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGB888 ([23:0] R:G:B little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGB888 __ecore_buffer_fourcc_code('R', 'G', '2', '4')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format BGR888 ([23:0] B:G:R little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGR888 __ecore_buffer_fourcc_code('B', 'G', '2', '4')
|
||||
/* 32 bpp RGB */
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format XRGB8888 ([31:0] x:R:G:B 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_XRGB8888 __ecore_buffer_fourcc_code('X', 'R', '2', '4')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format XBGR8888 ([31:0] x:B:G:R 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_XBGR8888 __ecore_buffer_fourcc_code('X', 'B', '2', '4')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGBX8888 ([31:0] R:G:B:x 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGBX8888 __ecore_buffer_fourcc_code('R', 'X', '2', '4')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format BGRX8888 ([31:0] B:G:R:x 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGRX8888 __ecore_buffer_fourcc_code('B', 'X', '2', '4')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format ARGB8888 ([31:0] A:R:G:B 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_ARGB8888 __ecore_buffer_fourcc_code('A', 'R', '2', '4')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format ABGR8888 ([31:0] [31:0] A:B:G:R 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_ABGR8888 __ecore_buffer_fourcc_code('A', 'B', '2', '4')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGBA8888 ([31:0] R:G:B:A 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGBA8888 __ecore_buffer_fourcc_code('R', 'A', '2', '4')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format BGRA8888 ([31:0] B:G:R:A 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGRA8888 __ecore_buffer_fourcc_code('B', 'A', '2', '4')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format XRGB2101010 ([31:0] x:R:G:B 2:10:10:10 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_XRGB2101010 __ecore_buffer_fourcc_code('X', 'R', '3', '0')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format XBGR2101010 ([31:0] x:B:G:R 2:10:10:10 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_XBGR2101010 __ecore_buffer_fourcc_code('X', 'B', '3', '0')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGBX1010102 ([31:0] R:G:B:x 10:10:10:2 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGBX1010102 __ecore_buffer_fourcc_code('R', 'X', '3', '0')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format BGRX1010102 ([31:0] B:G:R:x 10:10:10:2 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGRX1010102 __ecore_buffer_fourcc_code('B', 'X', '3', '0')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format ARGB2101010 ([31:0] A:R:G:B 2:10:10:10 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_ARGB2101010 __ecore_buffer_fourcc_code('A', 'R', '3', '0')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format ABGR2101010 ([31:0] A:B:G:R 2:10:10:10 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_ABGR2101010 __ecore_buffer_fourcc_code('A', 'B', '3', '0')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format RGBA1010102 ([31:0] R:G:B:A 10:10:10:2 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_RGBA1010102 __ecore_buffer_fourcc_code('R', 'A', '3', '0')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format BGRA1010102 ([31:0] B:G:R:A 10:10:10:2 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_BGRA1010102 __ecore_buffer_fourcc_code('B', 'A', '3', '0')
|
||||
/* packed YCbCr */
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YUYV ([31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YUYV __ecore_buffer_fourcc_code('Y', 'U', 'Y', 'V')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YVYU ([31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YVYU __ecore_buffer_fourcc_code('Y', 'V', 'Y', 'U')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format UYVY ([31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_UYVY __ecore_buffer_fourcc_code('U', 'Y', 'V', 'Y')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format VYUY ([31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_VYUY __ecore_buffer_fourcc_code('V', 'Y', 'U', 'Y')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format AYUV ([31:0] A:Y:Cb:Cr 8:8:8:8 little endian).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_AYUV __ecore_buffer_fourcc_code('A', 'Y', 'U', 'V')
|
||||
/*
|
||||
* 2 plane YCbCr
|
||||
* index 0 = Y plane, [7:0] Y
|
||||
* index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
|
||||
* or
|
||||
* index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
|
||||
*/
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format NV12 (2x2 subsampled Cr:Cb plane).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_NV12 __ecore_buffer_fourcc_code('N', 'V', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format NV21 (2x2 subsampled Cb:Cr plane).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_NV21 __ecore_buffer_fourcc_code('N', 'V', '2', '1')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format NV16 (2x1 subsampled Cr:Cb plane).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_NV16 __ecore_buffer_fourcc_code('N', 'V', '1', '6')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format NV61 (2x1 subsampled Cb:Cr plane).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_NV61 __ecore_buffer_fourcc_code('N', 'V', '6', '1')
|
||||
/*
|
||||
* 3 plane YCbCr
|
||||
* index 0: Y plane, [7:0] Y
|
||||
* index 1: Cb plane, [7:0] Cb
|
||||
* index 2: Cr plane, [7:0] Cr
|
||||
* or
|
||||
* index 1: Cr plane, [7:0] Cr
|
||||
* index 2: Cb plane, [7:0] Cb
|
||||
*/
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YUV410 (4x4 subsampled Cb (1) and Cr (2) planes).
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YUV410 __ecore_buffer_fourcc_code('Y', 'U', 'V', '9')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YVU410 (4x4 subsampled Cr (1) and Cb (2) planes).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YVU410 __ecore_buffer_fourcc_code('Y', 'V', 'U', '9')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YUV411 (4x1 subsampled Cb (1) and Cr (2) planes).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YUV411 __ecore_buffer_fourcc_code('Y', 'U', '1', '1')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YVU411 (4x1 subsampled Cr (1) and Cb (2) planes).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YVU411 __ecore_buffer_fourcc_code('Y', 'V', '1', '1')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YUV420 (2x2 subsampled Cb (1) and Cr (2) planes).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YUV420 __ecore_buffer_fourcc_code('Y', 'U', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YVU420 (2x2 subsampled Cr (1) and Cb (2) planes).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YVU420 __ecore_buffer_fourcc_code('Y', 'V', '1', '2')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YUV422 (2x1 subsampled Cb (1) and Cr (2) planes).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YUV422 __ecore_buffer_fourcc_code('Y', 'U', '1', '6')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YVU422 (2x1 subsampled Cr (1) and Cb (2) planes).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YVU422 __ecore_buffer_fourcc_code('Y', 'V', '1', '6')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YUV444 (non-subsampled Cb (1) and Cr (2) planes).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YUV444 __ecore_buffer_fourcc_code('Y', 'U', '2', '4')
|
||||
/**
|
||||
* @brief Definition for the Ecore_Buffer format YVU444 (non-subsampled Cr (1) and Cb (2) planes).
|
||||
* @since 1.15
|
||||
*/
|
||||
#define ECORE_BUFFER_FORMAT_YVU444 __ecore_buffer_fourcc_code('Y', 'V', '2', '4')
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Buffer_Lib_Group Ecore Buffer Library Functions
|
||||
* @ingroup Ecore_Buffer_Group
|
||||
*
|
||||
* Utility functions that set up and shut down the Ecore Buffer library.
|
||||
* This group of functions is applied to an Ecore_Buffer object.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef Ecore_Buffer
|
||||
* An object representing a graphic buffer.
|
||||
* @since 1.15
|
||||
*/
|
||||
typedef struct _Ecore_Buffer Ecore_Buffer;
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Backend
|
||||
* The interfaces for backend of buffer.
|
||||
* @since 1.15
|
||||
*/
|
||||
typedef struct _Ecore_Buffer_Backend Ecore_Buffer_Backend;
|
||||
/**
|
||||
* @typedef Ecore_Export_Type
|
||||
* Types for export buffer.
|
||||
* @since 1.15
|
||||
*/
|
||||
typedef enum _Ecore_Export_Type Ecore_Export_Type;
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Format
|
||||
* The format of Ecore_Buffer.
|
||||
* @since 1.15
|
||||
*/
|
||||
typedef unsigned int Ecore_Buffer_Format;
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Pixmap
|
||||
* An Id of Pixmap.
|
||||
* @since 1.15
|
||||
*/
|
||||
typedef unsigned long Ecore_Pixmap;
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Module_Data
|
||||
* The data of module.
|
||||
* @since 1.15
|
||||
*/
|
||||
typedef void* Ecore_Buffer_Module_Data;
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Data
|
||||
* The data of Ecore_Buffer.
|
||||
* @since 1.15
|
||||
*/
|
||||
typedef void* Ecore_Buffer_Data;
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Cb
|
||||
* Called whenever Ecore_Buffer is freed.
|
||||
* @since 1.15
|
||||
*/
|
||||
typedef void (*Ecore_Buffer_Cb)(Ecore_Buffer* buf, void* data);
|
||||
|
||||
/**
|
||||
* @enum _Ecore_Export_Type
|
||||
* Types for export buffer.
|
||||
* @since 1.15
|
||||
*/
|
||||
enum _Ecore_Export_Type
|
||||
{
|
||||
EXPORT_TYPE_INVALID,
|
||||
EXPORT_TYPE_ID,
|
||||
EXPORT_TYPE_FD
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct _Ecore_Buffer_Backend
|
||||
* @brief Structure used when initializing Ecore Buffer Backend. This structure
|
||||
* is mainly used by modules implementing the Ecore Buffer Backend interface.
|
||||
* @since 1.15
|
||||
*/
|
||||
struct _Ecore_Buffer_Backend
|
||||
{
|
||||
const char *name; /**< The name of backend */
|
||||
|
||||
Ecore_Buffer_Module_Data (*init)(const char *context, const char *options); /**< Initialize the backend */
|
||||
void (*shutdown)(Ecore_Buffer_Module_Data bmdata); /**< Shut down the backend */
|
||||
Ecore_Buffer_Data (*buffer_alloc)(Ecore_Buffer_Module_Data bmdata,
|
||||
int width, int height,
|
||||
Ecore_Buffer_Format format,
|
||||
unsigned int flags); /**< Newly allocate memory for buffer */
|
||||
void (*buffer_free)(Ecore_Buffer_Module_Data bmdata,
|
||||
Ecore_Buffer_Data bdata); /**< Free allocated memory */
|
||||
Ecore_Export_Type (*buffer_export)(Ecore_Buffer_Module_Data bmdata,
|
||||
Ecore_Buffer_Data bdata, int *id); /**< Get the id or fd of Ecore_Buffer for exporting it */
|
||||
Ecore_Buffer_Data (*buffer_import)(Ecore_Buffer_Module_Data bmdata,
|
||||
int w, int h,
|
||||
Ecore_Buffer_Format format,
|
||||
Ecore_Export_Type type,
|
||||
int export_id,
|
||||
unsigned int flags); /**< Import and create Ecore_Buffer from id or fd */
|
||||
void *(*data_get)(Ecore_Buffer_Module_Data bmdata,
|
||||
Ecore_Buffer_Data bdata);
|
||||
Ecore_Pixmap (*pixmap_get)(Ecore_Buffer_Module_Data bmdata,
|
||||
Ecore_Buffer_Data bdata); /**< Get the pixmap handle */
|
||||
void *(*tbm_surface_get)(Ecore_Buffer_Module_Data bmdata,
|
||||
Ecore_Buffer_Data bdata); /**< Get the tbm_surface_h handle */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialize the Ecore_Buffer system.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
|
||||
*
|
||||
* @see ecore_buffer_shutdown()
|
||||
*/
|
||||
EAPI Eina_Bool ecore_buffer_init(void);
|
||||
/**
|
||||
* @brief Shut down the Ecore_Buffer system.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
|
||||
*
|
||||
* @see ecore_buffer_init()
|
||||
*/
|
||||
EAPI Eina_Bool ecore_buffer_shutdown(void);
|
||||
/**
|
||||
* @brief Registers the given buffer backend.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] be The backend
|
||||
*
|
||||
* @return @c EINA_TRUE if backend has been correctly registered, @c EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI Eina_Bool ecore_buffer_register(Ecore_Buffer_Backend *be);
|
||||
/**
|
||||
* @brief Unregisters the given buffer backend.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] be The backend
|
||||
*/
|
||||
EAPI void ecore_buffer_unregister(Ecore_Buffer_Backend *be);
|
||||
/**
|
||||
* @brief Creates a new Ecore_Buffer given type
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] engine the name of backend
|
||||
* @param[in] width width for Ecore_Buffer
|
||||
* @param[in] height height for Ecore_Buffer
|
||||
* @param[in] format format for Ecore_Buffer
|
||||
* @param[in] flags flags for Ecore_Buffer
|
||||
*
|
||||
* @return Newly allocated Ecore_Buffer instance, NULL otherwise.
|
||||
*/
|
||||
EAPI Ecore_Buffer *ecore_buffer_new(const char *engine, unsigned int width, unsigned int height, Ecore_Buffer_Format format, unsigned int flags);
|
||||
/**
|
||||
* @brief Free the given Ecore_Buffer.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] buf The Ecore_Buffer to free
|
||||
*/
|
||||
EAPI void ecore_buffer_free(Ecore_Buffer *buf);
|
||||
/**
|
||||
* @brief Set a callback for Ecore_Buffer free events.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] buf The Ecore_Buffer to set callbacks on
|
||||
* @param[in] func The function to call
|
||||
* @param[in] data A pointer to the user data to store.
|
||||
*
|
||||
* A call to this function will set a callback on an Ecore_Buffer, causing
|
||||
* @p func to be called whenever @p buf is freed.
|
||||
*
|
||||
* @see ecore_buffer_free_callback_remove()
|
||||
*/
|
||||
EAPI void ecore_buffer_free_callback_add(Ecore_Buffer *buf, Ecore_Buffer_Cb func, void *data);
|
||||
/**
|
||||
* @brief Remove a callback for Ecore_Buffer free events.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] buf The Ecore_Buffer to remove callbacks on
|
||||
* @param[in] func The function to remove
|
||||
* @param[in] data A pointer to the user data to remove
|
||||
*
|
||||
* @see ecore_buffer_free_callback_add()
|
||||
*/
|
||||
EAPI void ecore_buffer_free_callback_remove(Ecore_Buffer *buf, Ecore_Buffer_Cb func, void *data);
|
||||
/**
|
||||
* @brief Get a pointer to the raw data of the given Ecore_Buffer.
|
||||
*
|
||||
* @param[in] buf The Ecore_Buffer.
|
||||
*
|
||||
* @return The pointer of raw data.
|
||||
*/
|
||||
EAPI void *ecore_buffer_data_get(Ecore_Buffer *buf);
|
||||
/**
|
||||
* @brief Return the Pixmap of given Ecore_Buffer.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] buf The Ecore_Buffer
|
||||
*
|
||||
* @return The Pixmap instance, 0 otherwise.
|
||||
*/
|
||||
EAPI Ecore_Pixmap ecore_buffer_pixmap_get(Ecore_Buffer *buf);
|
||||
/**
|
||||
* @brief Return the tbm surface handle of given Ecore_Buffer.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] buf The Ecore_Buffer
|
||||
*
|
||||
* @return The tbm surface handle, NULL otherwise.
|
||||
*
|
||||
* The tbm surface handle will be used for the API of libtbm.
|
||||
* The API is described in tbm_surface.h in libtbm.
|
||||
*/
|
||||
EAPI void *ecore_buffer_tbm_surface_get(Ecore_Buffer *buf);
|
||||
/**
|
||||
* @brief Return size of given Ecore_Buffer.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] buf The Ecore_Buffer
|
||||
* @param[out] width where to return the width value. May be @c NULL.
|
||||
* @param[out] height where to return the height value. May be @c NULL.
|
||||
*
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI Eina_Bool ecore_buffer_size_get(Ecore_Buffer *buf, unsigned int *width, unsigned int *height);
|
||||
/**
|
||||
* @brief Return format of given Ecore_Buffer.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] buf The Ecore_Buffer
|
||||
*
|
||||
* @return The format of given Ecore_Buffer.
|
||||
*
|
||||
* return value can be one of those pre-defined value such as ECORE_BUFFER_FORMAT_XRGB8888.
|
||||
*/
|
||||
EAPI Ecore_Buffer_Format ecore_buffer_format_get(Ecore_Buffer *buf);
|
||||
/**
|
||||
* @brief Return flags of given Ecore_Buffer.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] buf The Ecore_Buffer
|
||||
*
|
||||
* @return The flags of given Ecore_Buffer.
|
||||
*
|
||||
* NOTE: Not Defined yet.
|
||||
*/
|
||||
EAPI unsigned int ecore_buffer_flags_get(Ecore_Buffer *buf);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,449 @@
|
|||
#ifndef _ECORE_BUFFER_QUEUE_H_
|
||||
#define _ECORE_BUFFER_QUEUE_H_
|
||||
|
||||
#ifdef EAPI
|
||||
# undef EAPI
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef EFL_ECORE_BUFFER_BUILD
|
||||
# ifdef DLL_EXPORT
|
||||
# define EAPI __declspec(dllexport)
|
||||
# else
|
||||
# define EAPI
|
||||
# endif /* ! DLL_EXPORT */
|
||||
# else
|
||||
# define EAPI __declspec(dllimport)
|
||||
# endif /* ! EFL_ECORE_BUFFER_BUILD */
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ >= 4
|
||||
# define EAPI __attribute__ ((visibility("default")))
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
#endif /* ! _WIN32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <Eina.h>
|
||||
#include "Ecore_Buffer.h"
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Buffer_Queue_Group Ecore Buffer Queue functions
|
||||
* @ingroup Ecore_Buffer_Group
|
||||
*
|
||||
* Ecore Buffer Queue is a queue which conntects processes for sharing
|
||||
* Ecore_Buffer.
|
||||
* one process (related object is Ecore_Buffer_Provider) has rear terminal
|
||||
* position of Ecore_Buffer Queue which can enqueue the Ecore_Buffer,
|
||||
* and the other process (related object is Ecore_Buffer_Consumer) has front
|
||||
* terminal position of Ecore_Buffer_Queue which can dequeue the Ecore_Buffer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Buffer_Provider_Group Ecore Buffer Provider functions
|
||||
* @ingroup Ecore_Buffer_Queue_Group
|
||||
*
|
||||
* This group of functions is applied to an Ecore_Buffer_Provider object.
|
||||
* Ecore_Buffer_Provider provides Ecore_Buffer to Ecore_Buffer_Consumer(usally
|
||||
* different process or thread from Ecore_Buffer_Provider).
|
||||
* Ecore_Buffer_Provider should creates Ecore_Buffer as a provider.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Buffer_Consumer_Group Ecore Buffer Consumer functions
|
||||
* @ingroup Ecore_Buffer_Queue_Group
|
||||
*
|
||||
* This group of functions is applied to an Ecore_Buffer_Consumer object.
|
||||
* Ecore_Buffer_Consumer receives Ecore_Buffer enqueued by Ecore_Buffer_Provider.
|
||||
* Consumer must release Ecore_Buffer when it's no longer used.
|
||||
* Thus, the Ecore_Buffer_Provider is now free to re-use or destroy Ecore_Buffer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Return
|
||||
* @enum _Ecore_Buffer_Return
|
||||
* types for an buffer queue state on provider side.
|
||||
* @ingroup Ecore_Buffer_Provider_Group
|
||||
* @see ecore_buffer_provider_buffer_acquire()
|
||||
* @see ecore_buffer_provider_buffer_acquirable_check()
|
||||
*/
|
||||
typedef enum _Ecore_Buffer_Return
|
||||
{
|
||||
ECORE_BUFFER_RETURN_ERROR, /**< on error @since 1.15 */
|
||||
ECORE_BUFFER_RETURN_SUCCESS, /**< success to dequeue a buffer @since 1.15 */
|
||||
ECORE_BUFFER_RETURN_EMPTY, /**< Empty queue @since 1.15 */
|
||||
ECORE_BUFFER_RETURN_NOT_EMPTY, /**< Not empty queue @since 1.15 */
|
||||
ECORE_BUFFER_RETURN_NEED_ALLOC, /**< need to create Ecore_Buffer @since 1.15 */
|
||||
} Ecore_Buffer_Return;
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Consumer
|
||||
* An object representing a consumer of Ecore_Buffer.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @ingroup Ecore_Buffer_Consumer_Group
|
||||
*/
|
||||
typedef struct _Ecore_Buffer_Consumer Ecore_Buffer_Consumer;
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Provider
|
||||
* An object representing a provider of Ecore_Buffer.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @ingroup Ecore_Buffer_Provider_Group
|
||||
*/
|
||||
typedef struct _Ecore_Buffer_Provider Ecore_Buffer_Provider;
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Consumer_Provider_Add_Cb
|
||||
*
|
||||
* @brief Called whenever a Ecore_Buffer_Provider connected.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @see ecore_buffer_consumer_provider_add_cb_set()
|
||||
* @ingroup Ecore_Buffer_Consumer_Group
|
||||
*/
|
||||
typedef void (*Ecore_Buffer_Consumer_Provider_Add_Cb) (Ecore_Buffer_Consumer *consumer, void *data);
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Consumer_Provider_Del_Cb
|
||||
*
|
||||
* @brief Called whenever a Ecore_Buffer_Provider disonnected.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @see ecore_buffer_consumer_provider_del_cb_set()
|
||||
* @ingroup Ecore_Buffer_Consumer_Group
|
||||
*/
|
||||
typedef void (*Ecore_Buffer_Consumer_Provider_Del_Cb) (Ecore_Buffer_Consumer *consumer, void *data);
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Consumer_Enqueue_Cb
|
||||
*
|
||||
* @brief Called whenever a Ecore_Buffer enqueued in buffer queue.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @see ecore_buffer_consumer_buffer_enqueued_cb_set()
|
||||
* @ingroup Ecore_Buffer_Consumer_Group
|
||||
*/
|
||||
typedef void (*Ecore_Buffer_Consumer_Enqueue_Cb) (Ecore_Buffer_Consumer *consumer, void *data);
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Provider_Consumer_Add_Cb
|
||||
*
|
||||
* @brief Called whenever a Ecore_Buffer_Consumer connected.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @see ecore_buffer_provider_consumer_add_cb_set()
|
||||
* @ingroup Ecore_Buffer_Provider_Group
|
||||
*/
|
||||
typedef void (*Ecore_Buffer_Provider_Consumer_Add_Cb) (Ecore_Buffer_Provider *provider, int queue_size, int w, int h, void *data);
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Provider_Consumer_Del_Cb
|
||||
*
|
||||
* @brief Called whenever a Ecore_Buffer_Consumer disconnected.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @see ecore_buffer_provider_consumer_del_cb_set()
|
||||
* @ingroup Ecore_Buffer_Provider_Group
|
||||
*/
|
||||
typedef void (*Ecore_Buffer_Provider_Consumer_Del_Cb) (Ecore_Buffer_Provider *provider, void *data);
|
||||
/**
|
||||
* @typedef Ecore_Buffer_Provider_Enqueue_Cb
|
||||
*
|
||||
* @brief Called whenever a Ecore_Buffer is released.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @see ecore_buffer_provider_buffer_released_cb_set()
|
||||
* @ingroup Ecore_Buffer_Provider_Group
|
||||
*/
|
||||
typedef void (*Ecore_Buffer_Provider_Enqueue_Cb) (Ecore_Buffer_Provider *provider, void *data);
|
||||
|
||||
/**
|
||||
* @addtogroup Ecore_Buffer_Queue_Group
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Init the Ecore_Buffer_Queue system.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @return How many times the lib has been initialized, 0 indicates failure.
|
||||
*
|
||||
* Set up the connection of Buffer Queue deamon, and Init Ecore_Buffer_Queue libraries.
|
||||
*
|
||||
* @see ecore_buffer_queue_shutdown()
|
||||
*/
|
||||
EAPI int ecore_buffer_queue_init(void);
|
||||
/**
|
||||
* @brief Shut down the Ecore_Buffer_Queue system.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* this closes the connection of Buffer Queue deamon, and Shut down Ecore_Buffer_Queue libraries.
|
||||
*
|
||||
* @see ecore_buffer_queue_init()
|
||||
*/
|
||||
EAPI int ecore_buffer_queue_shutdown(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup Ecore_Buffer_Consumer_Group
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Creates a new Buffer Consumer based on name and common parameters.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] name the name of Buffer_Queue, this is needed by Consumer and Provider to connect each other.
|
||||
* @param[in] queue_size size of Queue (If you pass this 0, then default size two(2) is appied)
|
||||
* @param[in] w width of buffer recommeneded to provider.
|
||||
* @param[in] h height of buffer recommended to provider.
|
||||
*
|
||||
* @return Ecore_Buffer_Consumer instance or @c NULL if creation failed.
|
||||
*/
|
||||
EAPI Ecore_Buffer_Consumer *ecore_buffer_consumer_new(const char *name, int32_t queue_size, int32_t w, int32_t h);
|
||||
/**
|
||||
* @brief Free an Ecore_Buffer_Consumer
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] consumer The Ecore_Buffer_Consumer to free
|
||||
*
|
||||
* This frees up any memory used by the Ecore_Buffer_Consumer.
|
||||
*/
|
||||
EAPI void ecore_buffer_consumer_free(Ecore_Buffer_Consumer *consumer);
|
||||
/**
|
||||
* @brief Return the latest Ecore_Buffer submitted by provider.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] consumer The Ecore_Buffer_Consumer to request for buffer
|
||||
*
|
||||
* @return Ecore_Buffer handle or NULL if acquirement failed.
|
||||
*
|
||||
* @see ecore_buffer_consumer_buffer_release()
|
||||
*
|
||||
* Consumer can store Ecore_Buffer submitted by Provider as much as size of queue
|
||||
* which is passed as a argument of ecore_buffer_consumer_new().
|
||||
*/
|
||||
EAPI Ecore_Buffer *ecore_buffer_consumer_buffer_dequeue(Ecore_Buffer_Consumer *consumer);
|
||||
/**
|
||||
* @brief Release the acquired Ecore_Buffer.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] consumer The Ecore_Buffer_Consumer to request release buffer
|
||||
* @param[in] buffer The Ecore_Buffer to release
|
||||
*
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
|
||||
*
|
||||
* @see ecore_buffer_consumer_buffer_dequeue()
|
||||
*
|
||||
* Consumer should release the Ecore_Buffer after acquiring and using it.
|
||||
* By doing release, Ecore_Buffer will be used by provider again,
|
||||
* or freed internally if Ecore_Buffer is not necessary anymore.
|
||||
* If not, the resource of Ecore_Buffer is continually owned by consumer until released.
|
||||
*/
|
||||
EAPI Eina_Bool ecore_buffer_consumer_buffer_release(Ecore_Buffer_Consumer *consumer, Ecore_Buffer *buffer);
|
||||
/**
|
||||
* @brief Check if Queue of Ecore_Buffer is empty.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] consumer The Ecore_Buffer_Consumer to query
|
||||
*
|
||||
* @return @c EINA_TRUE means queue is empty, @c EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI Eina_Bool ecore_buffer_consumer_queue_is_empty(Ecore_Buffer_Consumer *consumer);
|
||||
/**
|
||||
* @brief Set a callback for provider connection events.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] consumer The Ecore_Buffer_Consumer to set callbacks on
|
||||
* @param[in] func The function to call
|
||||
* @param[in] data A pointer to the user data to store.
|
||||
*
|
||||
* A call to this function will set a callback on an Ecore_Buffer_Consumer, causing
|
||||
* @p func to be called whenever @p consumer is connected with provider.
|
||||
*/
|
||||
EAPI void ecore_buffer_consumer_provider_add_cb_set(Ecore_Buffer_Consumer *consumer, Ecore_Buffer_Consumer_Provider_Add_Cb func, void *data);
|
||||
/**
|
||||
* @brief Set a callback for provider disconnection events.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] consumer The Ecore_Buffer_Consumer to set callbacks on
|
||||
* @param[in] func The function to call
|
||||
* @param[in] data A pointer to the user data to store.
|
||||
*
|
||||
* A call to this function will set a callback on an Ecore_Buffer_Consumer, causing
|
||||
* @p func to be called whenever @p consumer is disconnected with provider.
|
||||
*/
|
||||
EAPI void ecore_buffer_consumer_provider_del_cb_set(Ecore_Buffer_Consumer *consumer, Ecore_Buffer_Consumer_Provider_Del_Cb func, void *data);
|
||||
/**
|
||||
* @brief Set a callback for enqueued buffer events.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] consumer The Ecore_Buffer_Consumer to set callbacks on
|
||||
* @param[in] func The function to call
|
||||
* @param[in] data A pointer to the user data to store.
|
||||
*
|
||||
* A call to this function will set a callback on an Ecore_Buffer_Consumer, causing
|
||||
* @p func to be called whenever @p consumer has received buffer submitted from provider.
|
||||
*
|
||||
* You may success acuiqre Ecore_Buffer after this callback called.
|
||||
*/
|
||||
EAPI void ecore_buffer_consumer_buffer_enqueued_cb_set(Ecore_Buffer_Consumer *consumer, Ecore_Buffer_Consumer_Enqueue_Cb func, void *data);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup Ecore_Buffer_Provider_Group
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Creates a new Buffer Provider based on name.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] name the name of Buffer_Queue.
|
||||
*
|
||||
* @return Ecore_Buffer_Provider instance or @c NULL if creation failed.
|
||||
*/
|
||||
EAPI Ecore_Buffer_Provider *ecore_buffer_provider_new(const char *name);
|
||||
/**
|
||||
* @brief Free an Ecore_Buffer_Provider
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] provider The Ecore_Buffer_Provider to free
|
||||
*
|
||||
* This frees up any memory used by the Ecore_Buffer_Provider.
|
||||
*/
|
||||
EAPI void ecore_buffer_provider_free(Ecore_Buffer_Provider *provider);
|
||||
/**
|
||||
* @brief Return the Ecore_Buffer released by consumer or State of Queue.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] provider The Ecore_Buffer_Provider to request for buffer
|
||||
* @param[out] ret_buf A Pointer to the Ecore_Buffer
|
||||
*
|
||||
* @return The enumeration of Ecore_Buffer_Return to indicate result of Dequeueing.
|
||||
*
|
||||
* This function gives you drawable buffer and inform you the state of Queue.
|
||||
* Each return value of enumeration has meaning as below.
|
||||
* @li ECORE_BUFFER_RETURN_ERROR, means error occured.
|
||||
* @li ECORE_BUFFER_RETURN_SUCCESS, means success to dequeue, therefore ret_buf is valid.
|
||||
* @li ECORE_BUFFER_RETURN_EMPTY, means queue is empty, not available slot in Queue.
|
||||
* in other words, there is no free drawable buffer in Queue.
|
||||
* @li ECORE_BUFFER_RETURN_NEED_ALLOC, means that there is available slot, but not allocated.
|
||||
* so, You may create new Ecore_Buffer, and then just enqueue the Ecore_Buffer.
|
||||
*
|
||||
* @see ecore_buffer_new(), ecore_buffer_provider_buffer_enqueue()
|
||||
*/
|
||||
EAPI Ecore_Buffer_Return ecore_buffer_provider_buffer_acquire(Ecore_Buffer_Provider *provider, Ecore_Buffer **ret_buf);
|
||||
/**
|
||||
* @brief Submit the Ecore_Buffer to Consumer to request compositing.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] provider The Ecore_Buffer_Provider connected with consumer.
|
||||
* @param[in] buffer The Ecore_Buffer to submit
|
||||
*
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
|
||||
*
|
||||
* This function allow you to submit the Ecore_Buffer to consumer to request compositing.
|
||||
* And this will be success, in case only you submit dequeued Ecore_Buffer,
|
||||
* and new Ecore_Buffer after received return value of ECORE_BUFFER_RETURN_NEED_ALLOC by ecore_buffer_provider_buffer_acquire().
|
||||
*
|
||||
* @see ecore_buffer_new(), ecore_buffer_provider_buffer_dequeue()
|
||||
*/
|
||||
EAPI Eina_Bool ecore_buffer_provider_buffer_enqueue(Ecore_Buffer_Provider *provider, Ecore_Buffer *buffer);
|
||||
/**
|
||||
* @brief Check if state of queue.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] provider The Ecore_Buffer_Provider to query
|
||||
*
|
||||
* @li ECORE_BUFFER_RETURN_NOT_EMPTY, means there is a dequeueable Ecore_Buffer at least one.
|
||||
* @li ECORE_BUFFER_RETURN_EMPTY, means queue is empty, not available slot in Queue.
|
||||
* in other words, there is no free drawable buffer in Queue.
|
||||
* @li ECORE_BUFFER_RETURN_NEED_ALLOC, means that there is available slot, but not allocated.
|
||||
* so, You may create new Ecore_Buffer, and then just enqueue the Ecore_Buffer.
|
||||
*
|
||||
* @return @c EINA_TRUE means queue is empty, @c EINA_FALSE otherwise.
|
||||
*/
|
||||
EAPI Ecore_Buffer_Return ecore_buffer_provider_buffer_acquirable_check(Ecore_Buffer_Provider *provider);
|
||||
/**
|
||||
* @brief Set a callback for consumer connection events.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] provider The Ecore_Buffer_Provider to set callbacks on
|
||||
* @param[in] func The function to call
|
||||
* @param[in] data A pointer to the user data to store.
|
||||
*
|
||||
* A call to this function will set a callback on an Ecore_Buffer_Provider, causing
|
||||
* @p func to be called whenever @p provider is connected with consumer.
|
||||
*/
|
||||
EAPI void ecore_buffer_provider_consumer_add_cb_set(Ecore_Buffer_Provider *provider, Ecore_Buffer_Provider_Consumer_Add_Cb func, void *data);
|
||||
/**
|
||||
* @brief Set a callback for consumer disconnection events.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] provider The Ecore_Buffer_Provider to set callbacks on
|
||||
* @param[in] func The function to call
|
||||
* @param[in] data A pointer to the user data to store.
|
||||
*
|
||||
* A call to this function will set a callback on an Ecore_Buffer_Provider, causing
|
||||
* @p func to be called whenever @p provider is disconnected with consumer.
|
||||
*/
|
||||
EAPI void ecore_buffer_provider_consumer_del_cb_set(Ecore_Buffer_Provider *provider, Ecore_Buffer_Provider_Consumer_Del_Cb func, void *data);
|
||||
/**
|
||||
* @brief Set a callback for released buffer events.
|
||||
*
|
||||
* @since 1.15
|
||||
*
|
||||
* @param[in] provider The Ecore_Buffer_Provider to set callbacks on
|
||||
* @param[in] func The function to call
|
||||
* @param[in] data A pointer to the user data to store.
|
||||
*
|
||||
* A call to this function will set a callback on an Ecore_Buffer_Provider, causing
|
||||
* @p func to be called whenever @p provider has received Ecore_Buffer released from provider.
|
||||
*
|
||||
* You may success dequeue the Ecore_Buffer after this callback called.
|
||||
*/
|
||||
EAPI void ecore_buffer_provider_buffer_released_cb_set(Ecore_Buffer_Provider *provider, Ecore_Buffer_Provider_Enqueue_Cb func, void *data);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ECORE_BUFFER_QUEUE_H_ */
|
|
@ -0,0 +1,131 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
extern const struct wl_interface bq_buffer_interface;
|
||||
extern const struct wl_interface bq_consumer_interface;
|
||||
extern const struct wl_interface bq_provider_interface;
|
||||
|
||||
static const struct wl_interface *types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_consumer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_provider_interface,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
&bq_buffer_interface,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message bq_mgr_requests[] = {
|
||||
{ "create_consumer", "nsiii", types + 3 },
|
||||
{ "create_provider", "ns", types + 8 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface bq_mgr_interface = {
|
||||
"bq_mgr", 1,
|
||||
2, bq_mgr_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message bq_consumer_requests[] = {
|
||||
{ "release_buffer", "o", types + 10 },
|
||||
};
|
||||
|
||||
static const struct wl_message bq_consumer_events[] = {
|
||||
{ "connected", "", types + 0 },
|
||||
{ "disconnected", "", types + 0 },
|
||||
{ "buffer_attached", "nsiiiu", types + 11 },
|
||||
{ "set_buffer_id", "oiiiiiii", types + 17 },
|
||||
{ "set_buffer_fd", "ohiiiiii", types + 25 },
|
||||
{ "buffer_detached", "o", types + 33 },
|
||||
{ "add_buffer", "ou", types + 34 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface bq_consumer_interface = {
|
||||
"bq_consumer", 1,
|
||||
1, bq_consumer_requests,
|
||||
7, bq_consumer_events,
|
||||
};
|
||||
|
||||
static const struct wl_message bq_provider_requests[] = {
|
||||
{ "attach_buffer", "nsiiiu", types + 36 },
|
||||
{ "set_buffer_id", "oiiiiiii", types + 42 },
|
||||
{ "set_buffer_fd", "ohiiiiii", types + 50 },
|
||||
{ "detach_buffer", "o", types + 58 },
|
||||
{ "enqueue_buffer", "ou", types + 59 },
|
||||
};
|
||||
|
||||
static const struct wl_message bq_provider_events[] = {
|
||||
{ "connected", "iii", types + 0 },
|
||||
{ "disconnected", "", types + 0 },
|
||||
{ "add_buffer", "ou", types + 61 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface bq_provider_interface = {
|
||||
"bq_provider", 1,
|
||||
5, bq_provider_requests,
|
||||
3, bq_provider_events,
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface bq_buffer_interface = {
|
||||
"bq_buffer", 1,
|
||||
0, NULL,
|
||||
0, NULL,
|
||||
};
|
||||
|
|
@ -0,0 +1,329 @@
|
|||
#ifndef BQ_MGR_CLIENT_PROTOCOL_H
|
||||
#define BQ_MGR_CLIENT_PROTOCOL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-client.h"
|
||||
|
||||
struct wl_client;
|
||||
struct wl_resource;
|
||||
|
||||
struct bq_mgr;
|
||||
struct bq_consumer;
|
||||
struct bq_provider;
|
||||
struct bq_buffer;
|
||||
|
||||
extern const struct wl_interface bq_mgr_interface;
|
||||
extern const struct wl_interface bq_consumer_interface;
|
||||
extern const struct wl_interface bq_provider_interface;
|
||||
extern const struct wl_interface bq_buffer_interface;
|
||||
|
||||
#ifndef BQ_MGR_ERROR_ENUM
|
||||
#define BQ_MGR_ERROR_ENUM
|
||||
enum bq_mgr_error {
|
||||
BQ_MGR_ERROR_INVALID_PERMISSION = 0,
|
||||
BQ_MGR_ERROR_INVALID_NAME = 1,
|
||||
BQ_MGR_ERROR_ALREADY_USED = 2,
|
||||
};
|
||||
#endif /* BQ_MGR_ERROR_ENUM */
|
||||
|
||||
#define BQ_MGR_CREATE_CONSUMER 0
|
||||
#define BQ_MGR_CREATE_PROVIDER 1
|
||||
|
||||
static inline void
|
||||
bq_mgr_set_user_data(struct bq_mgr *bq_mgr, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) bq_mgr, user_data);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
bq_mgr_get_user_data(struct bq_mgr *bq_mgr)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) bq_mgr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_mgr_destroy(struct bq_mgr *bq_mgr)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) bq_mgr);
|
||||
}
|
||||
|
||||
static inline struct bq_consumer *
|
||||
bq_mgr_create_consumer(struct bq_mgr *bq_mgr, const char *name, int32_t queue_size, int32_t width, int32_t height)
|
||||
{
|
||||
struct wl_proxy *id;
|
||||
|
||||
id = wl_proxy_marshal_constructor((struct wl_proxy *) bq_mgr,
|
||||
BQ_MGR_CREATE_CONSUMER, &bq_consumer_interface, NULL, name, queue_size, width, height);
|
||||
|
||||
return (struct bq_consumer *) id;
|
||||
}
|
||||
|
||||
static inline struct bq_provider *
|
||||
bq_mgr_create_provider(struct bq_mgr *bq_mgr, const char *name)
|
||||
{
|
||||
struct wl_proxy *id;
|
||||
|
||||
id = wl_proxy_marshal_constructor((struct wl_proxy *) bq_mgr,
|
||||
BQ_MGR_CREATE_PROVIDER, &bq_provider_interface, NULL, name);
|
||||
|
||||
return (struct bq_provider *) id;
|
||||
}
|
||||
|
||||
struct bq_consumer_listener {
|
||||
/**
|
||||
* connected - (none)
|
||||
*/
|
||||
void (*connected)(void *data,
|
||||
struct bq_consumer *bq_consumer);
|
||||
/**
|
||||
* disconnected - (none)
|
||||
*/
|
||||
void (*disconnected)(void *data,
|
||||
struct bq_consumer *bq_consumer);
|
||||
/**
|
||||
* buffer_attached - (none)
|
||||
* @buffer: (none)
|
||||
* @engine: (none)
|
||||
* @width: (none)
|
||||
* @height: (none)
|
||||
* @format: (none)
|
||||
* @flags: (none)
|
||||
*/
|
||||
void (*buffer_attached)(void *data,
|
||||
struct bq_consumer *bq_consumer,
|
||||
struct bq_buffer *buffer,
|
||||
const char *engine,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t format,
|
||||
uint32_t flags);
|
||||
/**
|
||||
* set_buffer_id - (none)
|
||||
* @buffer: (none)
|
||||
* @id: (none)
|
||||
* @offset0: (none)
|
||||
* @stride0: (none)
|
||||
* @offset1: (none)
|
||||
* @stride1: (none)
|
||||
* @offset2: (none)
|
||||
* @stride2: (none)
|
||||
*/
|
||||
void (*set_buffer_id)(void *data,
|
||||
struct bq_consumer *bq_consumer,
|
||||
struct bq_buffer *buffer,
|
||||
int32_t id,
|
||||
int32_t offset0,
|
||||
int32_t stride0,
|
||||
int32_t offset1,
|
||||
int32_t stride1,
|
||||
int32_t offset2,
|
||||
int32_t stride2);
|
||||
/**
|
||||
* set_buffer_fd - (none)
|
||||
* @buffer: (none)
|
||||
* @fd: (none)
|
||||
* @offset0: (none)
|
||||
* @stride0: (none)
|
||||
* @offset1: (none)
|
||||
* @stride1: (none)
|
||||
* @offset2: (none)
|
||||
* @stride2: (none)
|
||||
*/
|
||||
void (*set_buffer_fd)(void *data,
|
||||
struct bq_consumer *bq_consumer,
|
||||
struct bq_buffer *buffer,
|
||||
int32_t fd,
|
||||
int32_t offset0,
|
||||
int32_t stride0,
|
||||
int32_t offset1,
|
||||
int32_t stride1,
|
||||
int32_t offset2,
|
||||
int32_t stride2);
|
||||
/**
|
||||
* buffer_detached - (none)
|
||||
* @buffer: (none)
|
||||
*/
|
||||
void (*buffer_detached)(void *data,
|
||||
struct bq_consumer *bq_consumer,
|
||||
struct bq_buffer *buffer);
|
||||
/**
|
||||
* add_buffer - (none)
|
||||
* @buffer: (none)
|
||||
* @serial: (none)
|
||||
*/
|
||||
void (*add_buffer)(void *data,
|
||||
struct bq_consumer *bq_consumer,
|
||||
struct bq_buffer *buffer,
|
||||
uint32_t serial);
|
||||
};
|
||||
|
||||
static inline int
|
||||
bq_consumer_add_listener(struct bq_consumer *bq_consumer,
|
||||
const struct bq_consumer_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) bq_consumer,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define BQ_CONSUMER_RELEASE_BUFFER 0
|
||||
|
||||
static inline void
|
||||
bq_consumer_set_user_data(struct bq_consumer *bq_consumer, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) bq_consumer, user_data);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
bq_consumer_get_user_data(struct bq_consumer *bq_consumer)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) bq_consumer);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_consumer_destroy(struct bq_consumer *bq_consumer)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) bq_consumer);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_consumer_release_buffer(struct bq_consumer *bq_consumer, struct bq_buffer *buffer)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) bq_consumer,
|
||||
BQ_CONSUMER_RELEASE_BUFFER, buffer);
|
||||
}
|
||||
|
||||
#ifndef BQ_PROVIDER_ERROR_ENUM
|
||||
#define BQ_PROVIDER_ERROR_ENUM
|
||||
enum bq_provider_error {
|
||||
BQ_PROVIDER_ERROR_OVERFLOW_QUEUE_SIZE = 0,
|
||||
BQ_PROVIDER_ERROR_CONNECTION = 1,
|
||||
};
|
||||
#endif /* BQ_PROVIDER_ERROR_ENUM */
|
||||
|
||||
struct bq_provider_listener {
|
||||
/**
|
||||
* connected - (none)
|
||||
* @queue_size: (none)
|
||||
* @width: (none)
|
||||
* @height: (none)
|
||||
*/
|
||||
void (*connected)(void *data,
|
||||
struct bq_provider *bq_provider,
|
||||
int32_t queue_size,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
/**
|
||||
* disconnected - (none)
|
||||
*/
|
||||
void (*disconnected)(void *data,
|
||||
struct bq_provider *bq_provider);
|
||||
/**
|
||||
* add_buffer - (none)
|
||||
* @buffer: (none)
|
||||
* @serial: (none)
|
||||
*/
|
||||
void (*add_buffer)(void *data,
|
||||
struct bq_provider *bq_provider,
|
||||
struct bq_buffer *buffer,
|
||||
uint32_t serial);
|
||||
};
|
||||
|
||||
static inline int
|
||||
bq_provider_add_listener(struct bq_provider *bq_provider,
|
||||
const struct bq_provider_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) bq_provider,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define BQ_PROVIDER_ATTACH_BUFFER 0
|
||||
#define BQ_PROVIDER_SET_BUFFER_ID 1
|
||||
#define BQ_PROVIDER_SET_BUFFER_FD 2
|
||||
#define BQ_PROVIDER_DETACH_BUFFER 3
|
||||
#define BQ_PROVIDER_ENQUEUE_BUFFER 4
|
||||
|
||||
static inline void
|
||||
bq_provider_set_user_data(struct bq_provider *bq_provider, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) bq_provider, user_data);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
bq_provider_get_user_data(struct bq_provider *bq_provider)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) bq_provider);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_provider_destroy(struct bq_provider *bq_provider)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) bq_provider);
|
||||
}
|
||||
|
||||
static inline struct bq_buffer *
|
||||
bq_provider_attach_buffer(struct bq_provider *bq_provider, const char *engine, int32_t width, int32_t height, int32_t format, uint32_t flags)
|
||||
{
|
||||
struct wl_proxy *buffer;
|
||||
|
||||
buffer = wl_proxy_marshal_constructor((struct wl_proxy *) bq_provider,
|
||||
BQ_PROVIDER_ATTACH_BUFFER, &bq_buffer_interface, NULL, engine, width, height, format, flags);
|
||||
|
||||
return (struct bq_buffer *) buffer;
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_provider_set_buffer_id(struct bq_provider *bq_provider, struct bq_buffer *buffer, int32_t id, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) bq_provider,
|
||||
BQ_PROVIDER_SET_BUFFER_ID, buffer, id, offset0, stride0, offset1, stride1, offset2, stride2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_provider_set_buffer_fd(struct bq_provider *bq_provider, struct bq_buffer *buffer, int32_t fd, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) bq_provider,
|
||||
BQ_PROVIDER_SET_BUFFER_FD, buffer, fd, offset0, stride0, offset1, stride1, offset2, stride2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_provider_detach_buffer(struct bq_provider *bq_provider, struct bq_buffer *buffer)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) bq_provider,
|
||||
BQ_PROVIDER_DETACH_BUFFER, buffer);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_provider_enqueue_buffer(struct bq_provider *bq_provider, struct bq_buffer *buffer, uint32_t serial)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) bq_provider,
|
||||
BQ_PROVIDER_ENQUEUE_BUFFER, buffer, serial);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_buffer_set_user_data(struct bq_buffer *bq_buffer, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) bq_buffer, user_data);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
bq_buffer_get_user_data(struct bq_buffer *bq_buffer)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) bq_buffer);
|
||||
}
|
||||
|
||||
static inline void
|
||||
bq_buffer_destroy(struct bq_buffer *bq_buffer)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) bq_buffer);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,153 @@
|
|||
#include "buffer_queue.h"
|
||||
|
||||
struct _Ecore_Buffer_Queue
|
||||
{
|
||||
int w, h;
|
||||
Eina_List *shared_buffers;
|
||||
Eina_Bool connected;
|
||||
struct
|
||||
{
|
||||
unsigned int capacity;
|
||||
Eina_List *list;
|
||||
} queue;
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
_queue_is_full(Ecore_Buffer_Queue *ebq)
|
||||
{
|
||||
return (eina_list_count(ebq->queue.list) == ebq->queue.capacity);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_queue_is_empty(Ecore_Buffer_Queue *ebq)
|
||||
{
|
||||
return (eina_list_count(ebq->queue.list) == 0);
|
||||
}
|
||||
|
||||
Ecore_Buffer_Queue *
|
||||
_ecore_buffer_queue_new(int w, int h, int queue_size)
|
||||
{
|
||||
Ecore_Buffer_Queue *ebq;
|
||||
|
||||
if (queue_size < 1) return NULL;
|
||||
|
||||
ebq = calloc(1, sizeof(Ecore_Buffer_Queue));
|
||||
if (!ebq)
|
||||
return NULL;
|
||||
|
||||
ebq->w = w;
|
||||
ebq->h = h;
|
||||
ebq->queue.capacity = queue_size;
|
||||
|
||||
return ebq;
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_buffer_queue_free(Ecore_Buffer_Queue *ebq)
|
||||
{
|
||||
if (!ebq) return;
|
||||
|
||||
if (ebq->shared_buffers) eina_list_free(ebq->shared_buffers);
|
||||
if (ebq->queue.list) eina_list_free(ebq->queue.list);
|
||||
free(ebq);
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_buffer_queue_enqueue(Ecore_Buffer_Queue *ebq, Shared_Buffer *sb)
|
||||
{
|
||||
if (!ebq) return;
|
||||
if (_queue_is_full(ebq)) return;
|
||||
|
||||
if (!eina_list_data_find(ebq->shared_buffers, sb))
|
||||
{
|
||||
WARN("Couldn't enqueue not shared buffer.");
|
||||
return;
|
||||
}
|
||||
|
||||
ebq->queue.list = eina_list_prepend(ebq->queue.list, sb);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_ecore_buffer_queue_dequeue(Ecore_Buffer_Queue *ebq, Shared_Buffer **ret_sb)
|
||||
{
|
||||
Eina_List *last;
|
||||
Shared_Buffer *sb;
|
||||
|
||||
if (!ebq) return EINA_FALSE;
|
||||
if (_queue_is_empty(ebq)) return EINA_FALSE;
|
||||
|
||||
sb = eina_list_last_data_get(ebq->queue.list);
|
||||
last = eina_list_last(ebq->queue.list);
|
||||
ebq->queue.list = eina_list_remove_list(ebq->queue.list, last);
|
||||
|
||||
if (ret_sb) *ret_sb = sb;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_ecore_buffer_queue_is_empty(Ecore_Buffer_Queue *ebq)
|
||||
{
|
||||
if (!ebq) return EINA_FALSE;
|
||||
|
||||
return _queue_is_empty(ebq);
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_buffer_queue_shared_buffer_add(Ecore_Buffer_Queue *ebq, Shared_Buffer *sb)
|
||||
{
|
||||
if (!ebq) return;
|
||||
|
||||
ebq->shared_buffers = eina_list_append(ebq->shared_buffers, sb);
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_buffer_queue_shared_buffer_remove(Ecore_Buffer_Queue *ebq, Shared_Buffer *sb)
|
||||
{
|
||||
if (!ebq) return;
|
||||
|
||||
ebq->shared_buffers = eina_list_remove(ebq->shared_buffers, sb);
|
||||
while (eina_list_data_find(ebq->queue.list, sb) != NULL)
|
||||
ebq->queue.list = eina_list_remove(ebq->queue.list, sb);
|
||||
}
|
||||
|
||||
Shared_Buffer *
|
||||
_ecore_buffer_queue_shared_buffer_find(Ecore_Buffer_Queue *ebq, Ecore_Buffer *buffer)
|
||||
{
|
||||
Eina_List *l;
|
||||
Shared_Buffer *sb;
|
||||
|
||||
if (!ebq) return NULL;
|
||||
|
||||
EINA_LIST_FOREACH(ebq->shared_buffers, l, sb)
|
||||
{
|
||||
if (_shared_buffer_buffer_get(sb) == buffer)
|
||||
return sb;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Eina_List *
|
||||
_ecore_buffer_queue_shared_buffer_list_get(Ecore_Buffer_Queue *ebq)
|
||||
{
|
||||
if (!ebq) return NULL;
|
||||
|
||||
return ebq->shared_buffers;
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_buffer_queue_connection_state_set(Ecore_Buffer_Queue *ebq, Eina_Bool connect)
|
||||
{
|
||||
if (!ebq) return;
|
||||
|
||||
ebq->connected = connect;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_ecore_buffer_queue_connection_state_get(Ecore_Buffer_Queue *ebq)
|
||||
{
|
||||
if (!ebq) return EINA_FALSE;
|
||||
|
||||
return ebq->connected;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _BUFFER_QUEUE_H_
|
||||
#define _BUFFER_QUEUE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Eina.h>
|
||||
|
||||
#include "shared_buffer.h"
|
||||
|
||||
typedef struct _Ecore_Buffer_Queue Ecore_Buffer_Queue;
|
||||
|
||||
Ecore_Buffer_Queue *_ecore_buffer_queue_new(int w, int h, int queue_size);
|
||||
void _ecore_buffer_queue_free(Ecore_Buffer_Queue *ebq);
|
||||
void _ecore_buffer_queue_enqueue(Ecore_Buffer_Queue *ebq, Shared_Buffer *sb);
|
||||
Eina_Bool _ecore_buffer_queue_dequeue(Ecore_Buffer_Queue *ebq, Shared_Buffer **ret_sb);
|
||||
Eina_Bool _ecore_buffer_queue_is_empty(Ecore_Buffer_Queue *ebq);
|
||||
void _ecore_buffer_queue_shared_buffer_add(Ecore_Buffer_Queue *ebq, Shared_Buffer *sb);
|
||||
void _ecore_buffer_queue_shared_buffer_remove(Ecore_Buffer_Queue *ebq, Shared_Buffer *sb);
|
||||
Shared_Buffer *_ecore_buffer_queue_shared_buffer_find(Ecore_Buffer_Queue *ebq, Ecore_Buffer *buffer);
|
||||
Eina_List *_ecore_buffer_queue_shared_buffer_list_get(Ecore_Buffer_Queue *ebq);
|
||||
void _ecore_buffer_queue_connection_state_set(Ecore_Buffer_Queue *ebq, Eina_Bool connect);
|
||||
Eina_Bool _ecore_buffer_queue_connection_state_get(Ecore_Buffer_Queue *ebq);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,491 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Eina.h"
|
||||
#include "Ecore.h"
|
||||
|
||||
#include "Ecore_Buffer.h"
|
||||
#include "ecore_buffer_private.h"
|
||||
|
||||
typedef struct _Ecore_Buffer_Module Ecore_Buffer_Module;
|
||||
typedef struct _Ecore_Buffer_Cb_Data Ecore_Buffer_Cb_Data;
|
||||
|
||||
struct _Ecore_Buffer_Module
|
||||
{
|
||||
Ecore_Buffer_Backend *be;
|
||||
Ecore_Buffer_Module_Data data;
|
||||
};
|
||||
|
||||
struct _Ecore_Buffer
|
||||
{
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
int format;
|
||||
unsigned int flags;
|
||||
|
||||
Ecore_Buffer_Data buffer_data;
|
||||
Ecore_Buffer_Module *bm;
|
||||
|
||||
Eina_Hash *data;
|
||||
Eina_Inlist *free_callbacks;
|
||||
};
|
||||
|
||||
struct _Ecore_Buffer_Cb_Data
|
||||
{
|
||||
EINA_INLIST;
|
||||
Ecore_Buffer_Cb cb;
|
||||
void *data;
|
||||
};
|
||||
|
||||
static Eina_Hash *_backends;
|
||||
static Eina_Array *_modules;
|
||||
static int _ecore_buffer_init_count = 0;
|
||||
static int _ecore_buffer_log_dom = -1;
|
||||
|
||||
#ifdef ERR
|
||||
#undef ERR
|
||||
#endif
|
||||
#define ERR(...) EINA_LOG_DOM_ERR(_ecore_buffer_log_dom, __VA_ARGS__)
|
||||
|
||||
#ifdef DBG
|
||||
#undef DBG
|
||||
#endif
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_ecore_buffer_log_dom, __VA_ARGS__)
|
||||
|
||||
#ifndef PACKAGE_LIB_DIR
|
||||
#define PACKAGE_LIB_DIR ""
|
||||
#endif
|
||||
#ifndef MODULE_ARCH
|
||||
#define MODULE_ARCH ""
|
||||
#endif
|
||||
|
||||
static Ecore_Buffer_Module *
|
||||
_ecore_buffer_get_backend(const char *name)
|
||||
{
|
||||
Ecore_Buffer_Module *bm = NULL;
|
||||
Eina_Iterator *backend_name_itr;
|
||||
const char *backend_name = NULL;
|
||||
|
||||
backend_name = name;
|
||||
|
||||
if (backend_name == NULL)
|
||||
{
|
||||
backend_name = (const char*)getenv("ECORE_BUFFER_ENGINE");
|
||||
if (!backend_name)
|
||||
{
|
||||
backend_name_itr = eina_hash_iterator_data_new(_backends);
|
||||
while((!bm) &&
|
||||
(eina_iterator_next(backend_name_itr, (void **)&bm)));
|
||||
eina_iterator_free(backend_name_itr);
|
||||
}
|
||||
}
|
||||
else
|
||||
bm = eina_hash_find(_backends, backend_name);
|
||||
|
||||
if ((!bm) || (!bm->be))
|
||||
return NULL;
|
||||
|
||||
if (bm->be->init)
|
||||
bm->data = bm->be->init(NULL, NULL);
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_buffer_backends_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Module *bm = data;
|
||||
|
||||
if (!bm)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (bm->data)
|
||||
bm->be->shutdown(bm->data);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_buffer_register(Ecore_Buffer_Backend *be)
|
||||
{
|
||||
Ecore_Buffer_Module *bm;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(be, 0);
|
||||
|
||||
bm = calloc(1, sizeof(Ecore_Buffer_Module));
|
||||
if (!bm)
|
||||
return EINA_FALSE;
|
||||
|
||||
bm->be = be;
|
||||
bm->data = NULL;
|
||||
|
||||
return eina_hash_add(_backends, be->name, bm);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_unregister(Ecore_Buffer_Backend *be)
|
||||
{
|
||||
Ecore_Buffer_Module *bm;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(be);
|
||||
|
||||
bm = eina_hash_find(_backends, be->name);
|
||||
if (!bm)
|
||||
return;
|
||||
|
||||
eina_hash_del(_backends, be->name, bm);
|
||||
free(bm);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_buffer_init(void)
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (++_ecore_buffer_init_count > 1)
|
||||
return EINA_TRUE;
|
||||
|
||||
_ecore_buffer_log_dom = eina_log_domain_register("ecore_buffer", EINA_COLOR_BLUE);
|
||||
if (_ecore_buffer_log_dom < 0)
|
||||
{
|
||||
EINA_LOG_ERR("Could not register log domain: ecore_buffer");
|
||||
goto err;
|
||||
}
|
||||
|
||||
_backends = eina_hash_string_superfast_new(NULL);
|
||||
|
||||
/* dynamic backends */
|
||||
_modules = eina_module_arch_list_get(NULL,
|
||||
PACKAGE_LIB_DIR "/ecore_buffer/modules",
|
||||
MODULE_ARCH);
|
||||
|
||||
path = eina_module_symbol_path_get((const void *)ecore_buffer_init,
|
||||
"/ecore_buffer/modules");
|
||||
|
||||
_modules = eina_module_arch_list_get(_modules, path, MODULE_ARCH);
|
||||
if (path)
|
||||
free(path);
|
||||
|
||||
/* fallback using module where in build directory */
|
||||
if ((!_modules) ||
|
||||
(eina_array_count(_modules) == 0))
|
||||
{
|
||||
ERR("No available module in library directy: %s",
|
||||
PACKAGE_LIB_DIR "/ecore_buffer/modules");
|
||||
ERR("Fallback to load module where in build directory :%s",
|
||||
PACKAGE_BUILD_DIR "/src/modules/");
|
||||
_modules = eina_module_list_get(NULL,
|
||||
PACKAGE_BUILD_DIR "/src/modules/",
|
||||
EINA_TRUE, NULL, NULL);
|
||||
}
|
||||
|
||||
if ((!_modules) ||
|
||||
(eina_array_count(_modules) == 0))
|
||||
{
|
||||
ERR("no ecore_buffer modules able to be loaded.");
|
||||
eina_hash_free(_backends);
|
||||
eina_log_domain_unregister(_ecore_buffer_log_dom);
|
||||
_ecore_buffer_log_dom = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
// XXX: MODFIX: do not list ALL modules and load them ALL! this is
|
||||
// wrong. load the module we need WHEN we need it (by name etc. etc.
|
||||
// from api).
|
||||
eina_module_list_load(_modules);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
err:
|
||||
_ecore_buffer_init_count--;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_buffer_shutdown(void)
|
||||
{
|
||||
if (_ecore_buffer_init_count < 1)
|
||||
{
|
||||
WARN("Ecore_Buffer shut down called without init");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (--_ecore_buffer_init_count != 0)
|
||||
return EINA_FALSE;
|
||||
|
||||
/* dynamic backends */
|
||||
eina_hash_foreach(_backends, _ecore_buffer_backends_free, NULL);
|
||||
|
||||
eina_module_list_free(_modules);
|
||||
if (_modules)
|
||||
eina_array_free(_modules);
|
||||
|
||||
if (_backends)
|
||||
eina_hash_free(_backends);
|
||||
|
||||
eina_log_domain_unregister(_ecore_buffer_log_dom);
|
||||
_ecore_buffer_log_dom = -1;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI Ecore_Buffer*
|
||||
ecore_buffer_new(const char *engine, unsigned int width, unsigned int height, Ecore_Buffer_Format format, unsigned int flags)
|
||||
{
|
||||
Ecore_Buffer_Module *bm;
|
||||
Ecore_Buffer *bo;
|
||||
void *bo_data;
|
||||
|
||||
bm = _ecore_buffer_get_backend(engine);
|
||||
if (!bm)
|
||||
{
|
||||
ERR("Failed to get backend: %s", engine);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(bm->be, NULL);
|
||||
|
||||
if (!bm->be->buffer_alloc)
|
||||
{
|
||||
ERR("Not supported create buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bo = calloc(1, sizeof(Ecore_Buffer));
|
||||
if (!bo)
|
||||
return NULL;
|
||||
|
||||
bo_data = bm->be->buffer_alloc(bm->data, width, height, format, flags);
|
||||
if (!bo_data)
|
||||
{
|
||||
free(bo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bo->bm = bm;
|
||||
bo->width = width;
|
||||
bo->height = height;
|
||||
bo->format = format;
|
||||
bo->flags = flags;
|
||||
bo->buffer_data = bo_data;
|
||||
|
||||
return bo;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_free(Ecore_Buffer *buf)
|
||||
{
|
||||
Ecore_Buffer_Cb_Data *free_cb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(buf);
|
||||
|
||||
//Call free_cb
|
||||
while (buf->free_callbacks)
|
||||
{
|
||||
free_cb = EINA_INLIST_CONTAINER_GET(buf->free_callbacks, Ecore_Buffer_Cb_Data);
|
||||
buf->free_callbacks = eina_inlist_remove(buf->free_callbacks, buf->free_callbacks);
|
||||
|
||||
free_cb->cb(buf, free_cb->data);
|
||||
free(free_cb);
|
||||
}
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(buf->bm);
|
||||
EINA_SAFETY_ON_NULL_RETURN(buf->bm->be);
|
||||
EINA_SAFETY_ON_NULL_RETURN(buf->bm->be->buffer_free);
|
||||
|
||||
buf->bm->be->buffer_free(buf->bm->data, buf->buffer_data);
|
||||
|
||||
//Free User Data
|
||||
if (buf->data)
|
||||
eina_hash_free(buf->data);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
ecore_buffer_data_get(Ecore_Buffer *buf)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm->be, NULL);
|
||||
|
||||
if (!buf->bm->be->data_get)
|
||||
return NULL;
|
||||
|
||||
return buf->bm->be->data_get(buf->bm->data, buf->buffer_data);
|
||||
}
|
||||
|
||||
EAPI Ecore_Pixmap
|
||||
ecore_buffer_pixmap_get(Ecore_Buffer *buf)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm, 0);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm->be, 0);
|
||||
|
||||
if (!buf->bm->be->pixmap_get)
|
||||
return 0;
|
||||
|
||||
return buf->bm->be->pixmap_get(buf->bm->data, buf->buffer_data);
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
ecore_buffer_tbm_surface_get(Ecore_Buffer *buf)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm, NULL);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm->be, NULL);
|
||||
|
||||
if (!buf->bm->be->tbm_surface_get)
|
||||
{
|
||||
ERR("TBM is not supported\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buf->bm->be->tbm_surface_get(buf->bm->data, buf->buffer_data);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_buffer_size_get(Ecore_Buffer *buf, unsigned int *width, unsigned int *height)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, EINA_FALSE);
|
||||
|
||||
if (width) *width = buf->width;
|
||||
if (height) *height = buf->height;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI unsigned int
|
||||
ecore_buffer_format_get(Ecore_Buffer *buf)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
|
||||
|
||||
return buf->format;
|
||||
}
|
||||
|
||||
EAPI unsigned int
|
||||
ecore_buffer_flags_get(Ecore_Buffer *buf)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
|
||||
|
||||
return buf->flags;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_free_callback_add(Ecore_Buffer *buf, Ecore_Buffer_Cb func, void *data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(buf);
|
||||
EINA_SAFETY_ON_NULL_RETURN(func);
|
||||
|
||||
Ecore_Buffer_Cb_Data *free_cb;
|
||||
|
||||
free_cb = calloc(1, sizeof(Ecore_Buffer_Cb_Data));
|
||||
if (!free_cb)
|
||||
return;
|
||||
|
||||
free_cb->cb = func;
|
||||
free_cb->data = data;
|
||||
buf->free_callbacks = eina_inlist_append(buf->free_callbacks, EINA_INLIST_GET(free_cb));
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_free_callback_remove(Ecore_Buffer *buf, Ecore_Buffer_Cb func, void *data)
|
||||
{
|
||||
Ecore_Buffer_Cb_Data *free_cb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(buf);
|
||||
EINA_SAFETY_ON_NULL_RETURN(func);
|
||||
|
||||
if (buf->free_callbacks)
|
||||
{
|
||||
Eina_Inlist *itrn;
|
||||
EINA_INLIST_FOREACH_SAFE(buf->free_callbacks, itrn, free_cb)
|
||||
{
|
||||
if (free_cb->cb == func && free_cb->data == data)
|
||||
{
|
||||
buf->free_callbacks =
|
||||
eina_inlist_remove(buf->free_callbacks,
|
||||
EINA_INLIST_GET(free_cb));
|
||||
free(free_cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
_ecore_buffer_engine_name_get(Ecore_Buffer *buf)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm, 0);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm->be, 0);
|
||||
|
||||
return buf->bm->be->name;
|
||||
}
|
||||
|
||||
Ecore_Export_Type
|
||||
_ecore_buffer_export(Ecore_Buffer *buf, int *id)
|
||||
{
|
||||
Ecore_Export_Type type = EXPORT_TYPE_INVALID;
|
||||
int ret_id;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, type);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm, type);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm->be, type);
|
||||
|
||||
if (!buf->bm->be->buffer_export)
|
||||
return type;
|
||||
|
||||
type = buf->bm->be->buffer_export(buf->bm->data, buf->buffer_data, &ret_id);
|
||||
|
||||
if (id) *id = ret_id;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
Ecore_Buffer *
|
||||
_ecore_buffer_import(const char *engine, int width, int height, Ecore_Buffer_Format format, Ecore_Export_Type type, int export_id, unsigned int flags)
|
||||
{
|
||||
Ecore_Buffer_Module *bm;
|
||||
Ecore_Buffer *bo;
|
||||
void *bo_data;
|
||||
|
||||
bm = _ecore_buffer_get_backend(engine);
|
||||
if (!bm)
|
||||
{
|
||||
ERR("Filed to get Backend: %s", engine);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(bm->be, NULL);
|
||||
|
||||
if (!bm->be->buffer_import)
|
||||
{
|
||||
ERR("Not supported import buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bo = calloc(1, sizeof(Ecore_Buffer));
|
||||
if (!bo)
|
||||
return NULL;
|
||||
|
||||
bo_data = bm->be->buffer_import(bm->data, width, height, format, type, export_id, flags);
|
||||
if (!bo_data)
|
||||
{
|
||||
free(bo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bo->bm = bm;
|
||||
bo->width = width;
|
||||
bo->height = height;
|
||||
bo->format = format;
|
||||
bo->flags = flags;
|
||||
bo->buffer_data = bo_data;
|
||||
|
||||
return bo;
|
||||
}
|
|
@ -0,0 +1,253 @@
|
|||
#include "ecore_buffer_con.h"
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
typedef struct _Ecore_Buffer_Con Ecore_Buffer_Con;
|
||||
|
||||
struct _Ecore_Buffer_Con
|
||||
{
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
struct bq_mgr *bq_mgr;
|
||||
Ecore_Fd_Handler *fd_hdl;
|
||||
Ecore_Idle_Enterer *idle_enterer;
|
||||
int fd;
|
||||
Eina_Bool init_done;
|
||||
};
|
||||
|
||||
static Eina_Bool _connection_fatal_error = EINA_FALSE;
|
||||
Ecore_Buffer_Con *_connection = NULL;
|
||||
|
||||
static void
|
||||
_ecore_buffer_con_cb_registry_global(void *data, struct wl_registry *wl_registry, uint32_t id, const char *interface, uint32_t version)
|
||||
{
|
||||
Ecore_Buffer_Con *conn = data;
|
||||
|
||||
DBG("Added Wl Global Registry - name %d interface %s version %d",
|
||||
id, interface, version);
|
||||
|
||||
if (!strncmp(interface, "bq_mgr", strlen("bq_mgr")))
|
||||
{
|
||||
conn->bq_mgr =
|
||||
wl_registry_bind(wl_registry, id, &bq_mgr_interface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_con_cb_registry_global_remove(void *data EINA_UNUSED, struct wl_registry *wl_registry EINA_UNUSED, uint32_t name EINA_UNUSED)
|
||||
{
|
||||
DBG("Removed Wl Global Registry - name %d", name);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_con_signal_exit_free(void *data EINA_UNUSED, void *event)
|
||||
{
|
||||
free(event);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_con_signal_exit(void)
|
||||
{
|
||||
Ecore_Event_Signal_Exit *ev;
|
||||
|
||||
if (!(ev = calloc(1, sizeof(Ecore_Event_Signal_Exit))))
|
||||
return;
|
||||
|
||||
ev->quit = 1;
|
||||
ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, ev,
|
||||
_ecore_buffer_con_signal_exit_free, NULL);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_buffer_con_cb_idle_enterer(void *data)
|
||||
{
|
||||
Ecore_Buffer_Con *conn;
|
||||
int ret = 0;
|
||||
|
||||
if (_connection_fatal_error) return ECORE_CALLBACK_CANCEL;
|
||||
|
||||
if (!(conn = data)) return ECORE_CALLBACK_RENEW;
|
||||
|
||||
ret = wl_display_get_error(conn->display);
|
||||
if (ret < 0) goto err;
|
||||
|
||||
ret = wl_display_flush(conn->display);
|
||||
if ((ret < 0) && (errno == EAGAIN))
|
||||
ecore_main_fd_handler_active_set(conn->fd_hdl,
|
||||
(ECORE_FD_READ | ECORE_FD_WRITE));
|
||||
|
||||
ret = wl_display_dispatch_pending(conn->display);
|
||||
if (ret < 0) goto err;
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
|
||||
err:
|
||||
if ((ret < 0) && ((errno != EAGAIN) && (errno != EINVAL)))
|
||||
{
|
||||
_connection_fatal_error = EINA_TRUE;
|
||||
|
||||
/* raise exit signal */
|
||||
_ecore_buffer_con_signal_exit();
|
||||
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_buffer_con_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl)
|
||||
{
|
||||
Ecore_Buffer_Con *conn = data;
|
||||
int ret = 0;
|
||||
|
||||
if (_connection_fatal_error) return ECORE_CALLBACK_CANCEL;
|
||||
if (!conn) return ECORE_CALLBACK_RENEW;
|
||||
|
||||
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_ERROR))
|
||||
{
|
||||
ERR("Received error on wayland display fd");
|
||||
_connection_fatal_error = EINA_TRUE;
|
||||
_ecore_buffer_con_signal_exit();
|
||||
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
|
||||
ret = wl_display_dispatch(conn->display);
|
||||
else if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
|
||||
{
|
||||
ret = wl_display_flush(conn->display);
|
||||
if (ret == 0)
|
||||
ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
|
||||
}
|
||||
|
||||
if ((ret < 0) && ((errno != EAGAIN) && (errno != EINVAL)))
|
||||
{
|
||||
_connection_fatal_error = EINA_TRUE;
|
||||
|
||||
/* raise exit signal */
|
||||
_ecore_buffer_con_signal_exit();
|
||||
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_con_init_callback(void *data, struct wl_callback *callback, uint32_t serial EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Con *conn = data;
|
||||
|
||||
DBG("Queue Server Connected");
|
||||
|
||||
if (!conn)
|
||||
return;
|
||||
|
||||
wl_callback_destroy(callback);
|
||||
conn->init_done = EINA_TRUE;
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener _ecore_buffer_con_init_sync_listener =
|
||||
{
|
||||
_ecore_buffer_con_init_callback
|
||||
};
|
||||
|
||||
struct wl_registry_listener _ecore_buffer_registry_listener =
|
||||
{
|
||||
_ecore_buffer_con_cb_registry_global,
|
||||
_ecore_buffer_con_cb_registry_global_remove
|
||||
};
|
||||
|
||||
Eina_Bool
|
||||
_ecore_buffer_con_init(void)
|
||||
{
|
||||
struct wl_callback *callback;
|
||||
const char *name = "bq_mgr_daemon";
|
||||
|
||||
DBG("Ecore_Buffer_Con Init - name %s", name);
|
||||
|
||||
_connection = calloc(1, sizeof(Ecore_Buffer_Con));
|
||||
if (!_connection)
|
||||
{
|
||||
ERR("Failed to allocation");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!(_connection->display = wl_display_connect(name)))
|
||||
{
|
||||
ERR("Failed to connect to Queue Server");
|
||||
goto err_connect;
|
||||
}
|
||||
|
||||
_connection->fd = wl_display_get_fd(_connection->display);
|
||||
_connection->fd_hdl =
|
||||
ecore_main_fd_handler_add(_connection->fd,
|
||||
ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ERROR,
|
||||
_ecore_buffer_con_cb_fd_handle,
|
||||
_connection, NULL, NULL);
|
||||
|
||||
_connection->idle_enterer =
|
||||
ecore_idle_enterer_add(_ecore_buffer_con_cb_idle_enterer, _connection);
|
||||
|
||||
if (!(_connection->registry = wl_display_get_registry(_connection->display)))
|
||||
goto err_get_registry;
|
||||
|
||||
wl_registry_add_listener(_connection->registry,
|
||||
&_ecore_buffer_registry_listener, _connection);
|
||||
|
||||
_connection->init_done = EINA_FALSE;
|
||||
callback = wl_display_sync(_connection->display);
|
||||
wl_callback_add_listener(callback, &_ecore_buffer_con_init_sync_listener,
|
||||
_connection);
|
||||
|
||||
return EINA_TRUE;;
|
||||
err_get_registry:
|
||||
wl_display_disconnect(_connection->display);
|
||||
err_connect:
|
||||
free(_connection);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_buffer_con_shutdown(void)
|
||||
{
|
||||
if (!_connection) return;
|
||||
|
||||
DBG("Ecore_Buffer_Con Shutdown");
|
||||
|
||||
if (_connection->fd_hdl)
|
||||
ecore_main_fd_handler_del(_connection->fd_hdl);
|
||||
|
||||
if (_connection->idle_enterer)
|
||||
ecore_idle_enterer_del(_connection->idle_enterer);
|
||||
|
||||
if (_connection->bq_mgr)
|
||||
bq_mgr_destroy(_connection->bq_mgr);
|
||||
|
||||
if (_connection->display)
|
||||
wl_display_disconnect(_connection->display);
|
||||
|
||||
free(_connection);
|
||||
_connection = NULL;
|
||||
}
|
||||
|
||||
struct bq_provider *
|
||||
_ecore_buffer_con_provider_create(const char *name)
|
||||
{
|
||||
return bq_mgr_create_provider(_connection->bq_mgr, name);
|
||||
}
|
||||
|
||||
struct bq_consumer *
|
||||
_ecore_buffer_con_consumer_create(const char *name, int queue_size, int w, int h)
|
||||
{
|
||||
return bq_mgr_create_consumer(_connection->bq_mgr, name, queue_size, w, h);
|
||||
}
|
||||
|
||||
void
|
||||
_ecore_buffer_con_init_wait(void)
|
||||
{
|
||||
while (!_connection->init_done)
|
||||
wl_display_dispatch(_connection->display);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef _ECORE_BUFFER_con_H_
|
||||
#define _ECORE_BUFFER_con_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Buffer.h>
|
||||
|
||||
#include "bq_mgr_protocol.h"
|
||||
#include "ecore_buffer_private.h"
|
||||
|
||||
Eina_Bool _ecore_buffer_con_init(void);
|
||||
void _ecore_buffer_con_shutdown(void);
|
||||
void _ecore_buffer_con_init_wait(void);
|
||||
struct bq_provider *_ecore_buffer_con_provider_create(const char *name);
|
||||
struct bq_consumer *_ecore_buffer_con_consumer_create(const char *name, int queue_size, int w, int h);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,417 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Ecore_Buffer.h>
|
||||
#include <Ecore_Buffer_Queue.h>
|
||||
|
||||
#include "bq_mgr_protocol.h"
|
||||
#include "shared_buffer.h"
|
||||
#include "buffer_queue.h"
|
||||
#include "ecore_buffer_private.h"
|
||||
#include "ecore_buffer_con.h"
|
||||
|
||||
struct _Ecore_Buffer_Consumer
|
||||
{
|
||||
struct bq_consumer *resource;
|
||||
Ecore_Buffer_Queue *ebq;
|
||||
struct
|
||||
{
|
||||
void (*provider_add) (Ecore_Buffer_Consumer *consumer, void *data);
|
||||
void (*provider_del) (Ecore_Buffer_Consumer *consumer, void *data);
|
||||
void (*enqueue) (Ecore_Buffer_Consumer *consumer, void *data);
|
||||
void *data;
|
||||
} cb;
|
||||
};
|
||||
|
||||
static void _ecore_buffer_consumer_cb_provider_connected(void *data, struct bq_consumer *bq_consumer);
|
||||
static void _ecore_buffer_consumer_cb_provider_disconnected(void *data, struct bq_consumer *bq_consumer);
|
||||
static void _ecore_buffer_consumer_cb_buffer_attached(void *data, struct bq_consumer *bq_consumer, struct bq_buffer *id, const char *engine, int32_t width, int32_t height, int32_t format, uint32_t flags);
|
||||
static void _ecore_buffer_consumer_cb_buffer_id_set(void *data, struct bq_consumer *bq_consumer, struct bq_buffer *buffer, int32_t id, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2);
|
||||
static void _ecore_buffer_consumer_cb_buffer_fd_set(void *data, struct bq_consumer *bq_consumer, struct bq_buffer *buffer, int32_t fd, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2);
|
||||
static void _ecore_buffer_consumer_cb_buffer_detached(void *data, struct bq_consumer *bq_consumer, struct bq_buffer *id);
|
||||
static void _ecore_buffer_consumer_cb_add_buffer(void *data, struct bq_consumer *bq_consumer, struct bq_buffer *buffer, uint32_t serial);
|
||||
static void _ecore_buffer_consumer_cb_buffer_free(Ecore_Buffer *buf, void *data);
|
||||
static Eina_Bool _ecore_buffer_consumer_buffer_import(Ecore_Buffer_Consumer *consumer, Shared_Buffer *sb, int32_t seed, Ecore_Export_Type export_type);
|
||||
|
||||
struct bq_consumer_listener _ecore_buffer_consumer_listener =
|
||||
{
|
||||
_ecore_buffer_consumer_cb_provider_connected,
|
||||
_ecore_buffer_consumer_cb_provider_disconnected,
|
||||
_ecore_buffer_consumer_cb_buffer_attached,
|
||||
_ecore_buffer_consumer_cb_buffer_id_set,
|
||||
_ecore_buffer_consumer_cb_buffer_fd_set,
|
||||
_ecore_buffer_consumer_cb_buffer_detached,
|
||||
_ecore_buffer_consumer_cb_add_buffer
|
||||
};
|
||||
|
||||
EAPI Ecore_Buffer_Consumer *
|
||||
ecore_buffer_consumer_new(const char *name, int32_t queue_size, int32_t w, int32_t h)
|
||||
{
|
||||
Ecore_Buffer_Consumer *consumer;
|
||||
const int default_queue_size = 2;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
DBG("Consumer New - name %s, queue size %d, size (%dx%d)",
|
||||
name, queue_size, w, h);
|
||||
|
||||
if ((w < 1) || (h < 1))
|
||||
return NULL;
|
||||
|
||||
if (queue_size < default_queue_size)
|
||||
queue_size = default_queue_size;
|
||||
|
||||
_ecore_buffer_con_init_wait();
|
||||
|
||||
consumer = calloc(1, sizeof(Ecore_Buffer_Consumer));
|
||||
if (!consumer)
|
||||
return NULL;
|
||||
|
||||
consumer->ebq = _ecore_buffer_queue_new(w, h, queue_size);
|
||||
if (!consumer->ebq)
|
||||
{
|
||||
free(consumer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
consumer->resource = _ecore_buffer_con_consumer_create(name, queue_size, w, h);
|
||||
if (!consumer->resource)
|
||||
{
|
||||
_ecore_buffer_queue_free(consumer->ebq);
|
||||
free(consumer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bq_consumer_add_listener(consumer->resource,
|
||||
&_ecore_buffer_consumer_listener,
|
||||
consumer);
|
||||
|
||||
return consumer;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_consumer_free(Ecore_Buffer_Consumer *consumer)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
|
||||
DBG("Consumer Free");
|
||||
|
||||
if (consumer->ebq)
|
||||
_ecore_buffer_queue_free(consumer->ebq);
|
||||
|
||||
if (consumer->resource)
|
||||
bq_consumer_destroy(consumer->resource);
|
||||
|
||||
free(consumer);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_buffer_consumer_buffer_release(Ecore_Buffer_Consumer *consumer, Ecore_Buffer *buffer)
|
||||
{
|
||||
Shared_Buffer *sb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(consumer, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buffer, EINA_FALSE);
|
||||
|
||||
DBG("Buffer Release");
|
||||
|
||||
if (!_ecore_buffer_queue_connection_state_get(consumer->ebq))
|
||||
{
|
||||
WARN("NOT Connected with provider yet");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!(sb = _ecore_buffer_queue_shared_buffer_find(consumer->ebq, buffer)))
|
||||
{
|
||||
WARN("NOT shared - buffer %p", buffer);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
// already detached buffer, free buffer by deputy.
|
||||
if (_shared_buffer_state_get(sb) == SHARED_BUFFER_STATE_DETACH)
|
||||
{
|
||||
DBG("Free buffer - buffer %p", sb);
|
||||
ecore_buffer_free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_shared_buffer_state_get(sb) != SHARED_BUFFER_STATE_DEQUEUE)
|
||||
{
|
||||
WARN("Failed to Release Buffer -"
|
||||
"DO NOT Release buffer which is not Dequeued: buffer %p state %s",
|
||||
sb, _shared_buffer_state_string_get(sb));
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
_shared_buffer_state_set(sb, SHARED_BUFFER_STATE_RELEASE);
|
||||
bq_consumer_release_buffer(consumer->resource, _shared_buffer_resource_get(sb));
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI Ecore_Buffer *
|
||||
ecore_buffer_consumer_buffer_dequeue(Ecore_Buffer_Consumer *consumer)
|
||||
{
|
||||
Shared_Buffer *sb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(consumer, EINA_FALSE);
|
||||
|
||||
DBG("Buffer Acquire");
|
||||
|
||||
if (!_ecore_buffer_queue_dequeue(consumer->ebq, &sb))
|
||||
{
|
||||
DBG("No Available Buffer in Queue");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This should not happen.
|
||||
if (_shared_buffer_state_get(sb) != SHARED_BUFFER_STATE_ENQUEUE)
|
||||
{
|
||||
ERR("Unknown error occured - Not on Enqueued State: buffer %p, state %s",
|
||||
sb, _shared_buffer_state_string_get(sb));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_shared_buffer_state_set(sb, SHARED_BUFFER_STATE_DEQUEUE);
|
||||
|
||||
return _shared_buffer_buffer_get(sb);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_buffer_consumer_queue_is_empty(Ecore_Buffer_Consumer *consumer)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(consumer, EINA_FALSE);
|
||||
|
||||
return _ecore_buffer_queue_is_empty(consumer->ebq);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_consumer_provider_add_cb_set(Ecore_Buffer_Consumer *consumer, Ecore_Buffer_Consumer_Provider_Add_Cb func, void *data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
|
||||
consumer->cb.provider_add = func;
|
||||
consumer->cb.data = data;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_consumer_provider_del_cb_set(Ecore_Buffer_Consumer *consumer, Ecore_Buffer_Consumer_Provider_Del_Cb func, void *data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
|
||||
consumer->cb.provider_del = func;
|
||||
consumer->cb.data = data;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_consumer_buffer_enqueued_cb_set(Ecore_Buffer_Consumer *consumer, Ecore_Buffer_Consumer_Enqueue_Cb func, void *data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
|
||||
consumer->cb.enqueue = func;
|
||||
consumer->cb.data = data;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_consumer_cb_provider_connected(void *data, struct bq_consumer *bq_consumer EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Consumer *consumer = data;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
|
||||
DBG("Provider Connected");
|
||||
|
||||
_ecore_buffer_queue_connection_state_set(consumer->ebq, EINA_TRUE);
|
||||
|
||||
CALLBACK_CALL(consumer, provider_add);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_consumer_cb_provider_disconnected(void *data, struct bq_consumer *bq_consumer EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Consumer *consumer = data;
|
||||
Eina_List *clone, *shared_buffers, *l;
|
||||
Shared_Buffer *sb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
|
||||
DBG("Provider Disconnected");
|
||||
|
||||
_ecore_buffer_queue_connection_state_set(consumer->ebq, EINA_FALSE);
|
||||
|
||||
CALLBACK_CALL(consumer, provider_del);
|
||||
|
||||
shared_buffers = _ecore_buffer_queue_shared_buffer_list_get(consumer->ebq);
|
||||
clone = eina_list_clone(shared_buffers);
|
||||
|
||||
EINA_LIST_FOREACH(clone, l, sb)
|
||||
ecore_buffer_free(_shared_buffer_buffer_get(sb));
|
||||
|
||||
eina_list_free(clone);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_consumer_cb_buffer_attached(void *data, struct bq_consumer *bq_consumer EINA_UNUSED, struct bq_buffer *id, const char *engine, int32_t width, int32_t height, int32_t format, uint32_t flags)
|
||||
{
|
||||
Ecore_Buffer_Consumer *consumer = data;
|
||||
Shared_Buffer *sb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer->ebq);
|
||||
|
||||
DBG("Buffer Attached - engine %s, size (%dx%d), format %d, flags %d",
|
||||
engine, width, height, format, flags);
|
||||
|
||||
sb = _shared_buffer_new(engine, id, width, height, format, flags);
|
||||
_shared_buffer_state_set(sb, SHARED_BUFFER_STATE_ATTACH);
|
||||
_ecore_buffer_queue_shared_buffer_add(consumer->ebq, sb);
|
||||
bq_buffer_set_user_data(id, sb);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_consumer_cb_buffer_free(Ecore_Buffer *buf, void *data)
|
||||
{
|
||||
Ecore_Buffer_Consumer *consumer = data;
|
||||
Shared_Buffer *sb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(buf);
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
|
||||
sb = _ecore_buffer_queue_shared_buffer_find(consumer->ebq, buf);
|
||||
if (!sb)
|
||||
return;
|
||||
|
||||
_ecore_buffer_queue_shared_buffer_remove(consumer->ebq, sb);
|
||||
bq_buffer_destroy(_shared_buffer_resource_get(sb));
|
||||
_shared_buffer_free(sb);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_consumer_cb_buffer_id_set(void *data, struct bq_consumer *bq_consumer EINA_UNUSED, struct bq_buffer *buffer, int32_t id, int32_t offset0 EINA_UNUSED, int32_t stride0 EINA_UNUSED, int32_t offset1 EINA_UNUSED, int32_t stride1 EINA_UNUSED, int32_t offset2 EINA_UNUSED, int32_t stride2 EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Consumer *consumer = data;
|
||||
Shared_Buffer *sb = bq_buffer_get_user_data(buffer);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
EINA_SAFETY_ON_NULL_RETURN(sb);
|
||||
|
||||
if (_ecore_buffer_consumer_buffer_import(consumer, sb, id, EXPORT_TYPE_ID))
|
||||
bq_buffer_set_user_data(buffer, sb);
|
||||
else
|
||||
ERR("Failed to import buffer - buffer resource %p", buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_consumer_cb_buffer_fd_set(void *data, struct bq_consumer *bq_consumer EINA_UNUSED, struct bq_buffer *buffer, int32_t fd, int32_t offset0 EINA_UNUSED, int32_t stride0 EINA_UNUSED, int32_t offset1 EINA_UNUSED, int32_t stride1 EINA_UNUSED, int32_t offset2 EINA_UNUSED, int32_t stride2 EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Consumer *consumer = data;
|
||||
Shared_Buffer *sb = bq_buffer_get_user_data(buffer);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
EINA_SAFETY_ON_NULL_RETURN(sb);
|
||||
|
||||
if (_ecore_buffer_consumer_buffer_import(consumer, sb, fd, EXPORT_TYPE_FD))
|
||||
bq_buffer_set_user_data(buffer, sb);
|
||||
else
|
||||
ERR("Failed to import buffer - buffer resource %p", buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_consumer_cb_buffer_detached(void *data, struct bq_consumer *bq_consumer EINA_UNUSED, struct bq_buffer *id)
|
||||
{
|
||||
Ecore_Buffer_Consumer *consumer = data;
|
||||
Shared_Buffer *sb = bq_buffer_get_user_data(id);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
EINA_SAFETY_ON_NULL_RETURN(sb);
|
||||
|
||||
DBG("Buffer Detached");
|
||||
|
||||
// buffer is owned by consumer. free right now.
|
||||
if (_shared_buffer_state_get(sb) != SHARED_BUFFER_STATE_DEQUEUE)
|
||||
{
|
||||
DBG("Free buffer - buffer %p, state %s",
|
||||
sb, _shared_buffer_state_string_get(sb));
|
||||
ecore_buffer_free(_shared_buffer_buffer_get(sb));
|
||||
return;
|
||||
}
|
||||
|
||||
// mark it as a detached buffer, and then free on buffer release time.
|
||||
DBG("Just mark this buffer to free it when released - buffer %p, state %s",
|
||||
sb, "SHARED_BUFFER_STATE_DEQUEUE");
|
||||
_shared_buffer_state_set(sb, SHARED_BUFFER_STATE_DETACH);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_consumer_cb_add_buffer(void *data, struct bq_consumer *bq_consumer EINA_UNUSED, struct bq_buffer *buffer, uint32_t serial EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Consumer *consumer = data;
|
||||
Shared_Buffer *sb = bq_buffer_get_user_data(buffer);
|
||||
Shared_Buffer_State state;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(consumer);
|
||||
|
||||
DBG("Buffer Enqueued");
|
||||
|
||||
if (!sb)
|
||||
{
|
||||
ERR("Unknown Error occured - maybe this buffer is not shared yet");
|
||||
return;
|
||||
}
|
||||
|
||||
state = _shared_buffer_state_get(sb);
|
||||
if ((state != SHARED_BUFFER_STATE_IMPORT) &&
|
||||
(state != SHARED_BUFFER_STATE_RELEASE))
|
||||
{
|
||||
ERR("Unknown Error occured - Could not enqueued this state of buffer: buffer %p, state %s",
|
||||
sb, _shared_buffer_state_string_get(sb));
|
||||
return;
|
||||
}
|
||||
|
||||
_ecore_buffer_queue_enqueue(consumer->ebq, sb);
|
||||
_shared_buffer_state_set(sb, SHARED_BUFFER_STATE_ENQUEUE);
|
||||
|
||||
CALLBACK_CALL(consumer, enqueue);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_buffer_consumer_buffer_import(Ecore_Buffer_Consumer *consumer, Shared_Buffer *sb, int32_t seed, Ecore_Export_Type export_type)
|
||||
{
|
||||
Ecore_Buffer *buffer;
|
||||
const char *engine = NULL;
|
||||
int w, h, format;
|
||||
unsigned int flags;
|
||||
|
||||
if ((!sb) ||
|
||||
(!_shared_buffer_info_get(sb, &engine, &w, &h, &format, &flags)))
|
||||
{
|
||||
ERR("Failed to Get Shared Buffer");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (_shared_buffer_state_get(sb) != SHARED_BUFFER_STATE_ATTACH)
|
||||
{
|
||||
ERR("Not Attached Buffer - buffer %p state %s",
|
||||
sb, _shared_buffer_state_string_get(sb));
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!(buffer = _ecore_buffer_import(engine, w, h, format, export_type, seed, flags)))
|
||||
{
|
||||
ERR("Failed to Import Buffer - size (%dx%d), foramt %d, seed %d, export_type %d",
|
||||
w, h, format, seed, export_type);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (export_type == EXPORT_TYPE_FD)
|
||||
close(seed);
|
||||
|
||||
_shared_buffer_buffer_set(sb, buffer);
|
||||
_shared_buffer_state_set(sb, SHARED_BUFFER_STATE_IMPORT);
|
||||
|
||||
ecore_buffer_free_callback_add(buffer, _ecore_buffer_consumer_cb_buffer_free, consumer);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef _ECORE_BUFFER_PRIVATE_H_
|
||||
# define _ECORE_BUFFER_PRIVATE_H_
|
||||
|
||||
#ifdef ERR
|
||||
#undef ERR
|
||||
#endif
|
||||
#ifdef WARN
|
||||
#undef WARN
|
||||
#endif
|
||||
#ifdef DBG
|
||||
#undef DBG
|
||||
#endif
|
||||
|
||||
#define ERR(...) EINA_LOG_DOM_ERR(_ecore_buffer_queue_log_dom, __VA_ARGS__)
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_ecore_buffer_queue_log_dom, __VA_ARGS__)
|
||||
#define WARN(...) EINA_LOG_DOM_WARN(_ecore_buffer_queue_log_dom, __VA_ARGS__)
|
||||
|
||||
#define CALLBACK_CALL(obj, cbname) \
|
||||
do { \
|
||||
if (obj->cb.cbname) \
|
||||
obj->cb.cbname(obj, obj->cb.data); \
|
||||
} while(0)
|
||||
|
||||
extern int _ecore_buffer_queue_log_dom;
|
||||
|
||||
const char *_ecore_buffer_engine_name_get(Ecore_Buffer *buf);
|
||||
/* NOTE: if Ecore_Export_Type as a return value is EXPORT_TYPE_FD,
|
||||
* then caller should close the fd after using it. */
|
||||
Ecore_Export_Type _ecore_buffer_export(Ecore_Buffer *buf, int *id);
|
||||
Ecore_Buffer *_ecore_buffer_import(const char *engine, int width, int height, Ecore_Buffer_Format format, Ecore_Export_Type type, int export_id, unsigned int flags);
|
||||
#endif /* _ECORE_BUFFER_PRIVATE_H_ */
|
|
@ -0,0 +1,391 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Ecore_Buffer.h>
|
||||
#include <Ecore_Buffer_Queue.h>
|
||||
|
||||
#include "bq_mgr_protocol.h"
|
||||
#include "shared_buffer.h"
|
||||
#include "buffer_queue.h"
|
||||
#include "ecore_buffer_private.h"
|
||||
#include "ecore_buffer_con.h"
|
||||
|
||||
struct _Ecore_Buffer_Provider
|
||||
{
|
||||
struct bq_provider *resource;
|
||||
Ecore_Buffer_Queue *ebq;
|
||||
int free_slot;
|
||||
struct
|
||||
{
|
||||
void (*consumer_add) (Ecore_Buffer_Provider *provider, int queue_size, int w, int h, void *data);
|
||||
void (*consumer_del) (Ecore_Buffer_Provider *provider, void *data);
|
||||
void (*enqueue) (Ecore_Buffer_Provider *provider, void *data);
|
||||
void *data;
|
||||
} cb;
|
||||
};
|
||||
|
||||
static void _ecore_buffer_provider_cb_consumer_connected(void *data, struct bq_provider *bq_provider, int32_t queue_size, int32_t width, int32_t height);
|
||||
static void _ecore_buffer_provider_cb_consumer_disconnected(void *data, struct bq_provider *bq_provider);
|
||||
static void _ecore_buffer_provider_cb_add_buffer(void *data, struct bq_provider *bq_provider, struct bq_buffer *buffer, uint32_t serial);
|
||||
static Shared_Buffer *_ecore_buffer_provider_shared_buffer_new(Ecore_Buffer_Provider *provider, Ecore_Buffer *buffer);
|
||||
static void _ecore_buffer_provider_shared_buffer_free(Ecore_Buffer_Provider *provider, Shared_Buffer *sb);
|
||||
static void _ecore_buffer_provider_cb_buffer_free(Ecore_Buffer *buf, void *data);
|
||||
|
||||
struct bq_provider_listener _ecore_buffer_provider_listener =
|
||||
{
|
||||
_ecore_buffer_provider_cb_consumer_connected,
|
||||
_ecore_buffer_provider_cb_consumer_disconnected,
|
||||
_ecore_buffer_provider_cb_add_buffer
|
||||
};
|
||||
|
||||
EAPI Ecore_Buffer_Provider *
|
||||
ecore_buffer_provider_new(const char *name)
|
||||
{
|
||||
Ecore_Buffer_Provider *provider;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
||||
|
||||
DBG("Provider New - name %s", name);
|
||||
|
||||
_ecore_buffer_con_init_wait();
|
||||
|
||||
provider = calloc(1, sizeof(Ecore_Buffer_Provider));
|
||||
if (!provider)
|
||||
{
|
||||
ERR("Failed to allocate Ecore_Buffer_Provider");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
provider->resource = _ecore_buffer_con_provider_create(name);
|
||||
if (!provider->resource)
|
||||
{
|
||||
ERR("Failed to get provider connection");
|
||||
free(provider);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bq_provider_add_listener(provider->resource, &_ecore_buffer_provider_listener, provider);
|
||||
bq_provider_set_user_data(provider->resource, provider);
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_provider_free(Ecore_Buffer_Provider *provider)
|
||||
{
|
||||
Eina_List *shared_buffers, *l;
|
||||
Shared_Buffer *sb;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(provider);
|
||||
|
||||
DBG("Provider Free");
|
||||
|
||||
if (provider->ebq)
|
||||
{
|
||||
shared_buffers = _ecore_buffer_queue_shared_buffer_list_get(provider->ebq);
|
||||
EINA_LIST_FOREACH(shared_buffers, l, sb)
|
||||
_ecore_buffer_provider_shared_buffer_free(provider, sb);
|
||||
|
||||
_ecore_buffer_queue_free(provider->ebq);
|
||||
}
|
||||
|
||||
bq_provider_destroy(provider->resource);
|
||||
free(provider);
|
||||
}
|
||||
|
||||
EAPI Ecore_Buffer_Return
|
||||
ecore_buffer_provider_buffer_acquire(Ecore_Buffer_Provider *provider, Ecore_Buffer **ret_buf)
|
||||
{
|
||||
Shared_Buffer *sb;
|
||||
Ecore_Buffer_Return ret_flag = ECORE_BUFFER_RETURN_ERROR;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(provider, ret_flag);
|
||||
|
||||
if (!provider->ebq)
|
||||
return ret_flag;
|
||||
|
||||
DBG("Buffer Acquire");
|
||||
|
||||
if (!_ecore_buffer_queue_dequeue(provider->ebq, &sb))
|
||||
{
|
||||
ret_flag = ECORE_BUFFER_RETURN_EMPTY;
|
||||
|
||||
// Check if exist free slot.
|
||||
if (provider->free_slot > 0)
|
||||
ret_flag = ECORE_BUFFER_RETURN_NEED_ALLOC;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This should not happen.
|
||||
if (_shared_buffer_state_get(sb) != SHARED_BUFFER_STATE_RELEASE)
|
||||
{
|
||||
ERR("Unknown error occured - Not on Released State: buffer %p state %s",
|
||||
sb, _shared_buffer_state_string_get(sb));
|
||||
return ECORE_BUFFER_RETURN_ERROR;
|
||||
}
|
||||
|
||||
_shared_buffer_state_set(sb, SHARED_BUFFER_STATE_ACQUIRE);
|
||||
|
||||
ret_flag = ECORE_BUFFER_RETURN_SUCCESS;
|
||||
if (ret_buf) *ret_buf = _shared_buffer_buffer_get(sb);
|
||||
}
|
||||
|
||||
return ret_flag;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
ecore_buffer_provider_buffer_enqueue(Ecore_Buffer_Provider *provider, Ecore_Buffer *buffer)
|
||||
{
|
||||
Shared_Buffer *sb;
|
||||
Shared_Buffer_State state;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(provider, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buffer, EINA_FALSE);
|
||||
|
||||
DBG("Buffer Enqueue");
|
||||
|
||||
if (!provider->ebq)
|
||||
{
|
||||
WARN("Not connected with consumer yet.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!(sb = _ecore_buffer_queue_shared_buffer_find(provider->ebq, buffer)))
|
||||
{
|
||||
// this buffer was never attached before.
|
||||
if (provider->free_slot > 0)
|
||||
{
|
||||
sb = _ecore_buffer_provider_shared_buffer_new(provider, buffer);
|
||||
if (!sb)
|
||||
{
|
||||
ERR("Unkown error occured -"
|
||||
"Failed to attach buffer: buffer %p", buffer);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
provider->free_slot--;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("No Free slot in Queue."
|
||||
"Need to ecore_buffer_free of enqueueed buffer first.");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
state = _shared_buffer_state_get(sb);
|
||||
if ((state != SHARED_BUFFER_STATE_NEW) &&
|
||||
(state != SHARED_BUFFER_STATE_ACQUIRE))
|
||||
{
|
||||
ERR("Failed to enqueue buffer - Not on acquired state: buffer %p state %s",
|
||||
sb, _shared_buffer_state_string_get(sb));
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
_shared_buffer_state_set(sb, SHARED_BUFFER_STATE_ENQUEUE);
|
||||
bq_provider_enqueue_buffer(provider->resource, _shared_buffer_resource_get(sb), 0);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI Ecore_Buffer_Return
|
||||
ecore_buffer_provider_buffer_acquirable_check(Ecore_Buffer_Provider *provider)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(provider, EINA_FALSE);
|
||||
|
||||
if (_ecore_buffer_queue_is_empty(provider->ebq))
|
||||
{
|
||||
if (provider->free_slot > 0)
|
||||
return ECORE_BUFFER_RETURN_NEED_ALLOC;
|
||||
|
||||
return ECORE_BUFFER_RETURN_EMPTY;
|
||||
}
|
||||
|
||||
return ECORE_BUFFER_RETURN_NOT_EMPTY;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_provider_consumer_add_cb_set(Ecore_Buffer_Provider *provider, Ecore_Buffer_Provider_Consumer_Add_Cb func, void *data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(provider);
|
||||
|
||||
provider->cb.consumer_add = func;
|
||||
provider->cb.data = data;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_provider_consumer_del_cb_set(Ecore_Buffer_Provider *provider, Ecore_Buffer_Provider_Consumer_Del_Cb func, void *data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(provider);
|
||||
|
||||
provider->cb.consumer_del = func;
|
||||
provider->cb.data = data;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
ecore_buffer_provider_buffer_released_cb_set(Ecore_Buffer_Provider *provider, Ecore_Buffer_Provider_Enqueue_Cb func, void *data)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(provider);
|
||||
|
||||
provider->cb.enqueue = func;
|
||||
provider->cb.data = data;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_provider_cb_consumer_connected(void *data, struct bq_provider *bq_provider EINA_UNUSED, int32_t queue_size, int32_t width, int32_t height)
|
||||
{
|
||||
Ecore_Buffer_Provider *provider = data;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(provider);
|
||||
|
||||
DBG("Consumer Connected - queue_size %d, size (%dx%d)",
|
||||
queue_size, width, height);
|
||||
|
||||
if (!(provider->ebq = _ecore_buffer_queue_new(width, height, queue_size)))
|
||||
{
|
||||
ERR("Failed to create Ecore_Buffer_Queue - queue_size %d, size (%dx%d)",
|
||||
queue_size, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
_ecore_buffer_queue_connection_state_set(provider->ebq, EINA_TRUE);
|
||||
|
||||
// set the number of free slot which means allocatable buffer number.
|
||||
provider->free_slot = queue_size;
|
||||
|
||||
// CALLBACK_CALL
|
||||
if (provider->cb.consumer_add)
|
||||
provider->cb.consumer_add(provider, queue_size, width, height, provider->cb.data);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_provider_cb_consumer_disconnected(void *data, struct bq_provider *bq_provider EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Provider *provider = data;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(provider);
|
||||
|
||||
DBG("Consumer Disconnected");
|
||||
|
||||
_ecore_buffer_queue_connection_state_set(provider->ebq, EINA_FALSE);
|
||||
|
||||
_ecore_buffer_queue_free(provider->ebq);
|
||||
provider->ebq = NULL;
|
||||
|
||||
CALLBACK_CALL(provider, consumer_del);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_provider_cb_add_buffer(void *data, struct bq_provider *bq_provider EINA_UNUSED, struct bq_buffer *buffer, uint32_t serial EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Provider *provider = data;
|
||||
Shared_Buffer *sb = bq_buffer_get_user_data(buffer);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(provider);
|
||||
|
||||
if (!sb) return;
|
||||
|
||||
DBG("Buffer Enqueued");
|
||||
|
||||
// Mark it as a released buffer.
|
||||
_shared_buffer_state_set(sb, SHARED_BUFFER_STATE_RELEASE);
|
||||
_ecore_buffer_queue_enqueue(provider->ebq, sb);
|
||||
|
||||
CALLBACK_CALL(provider, enqueue);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_provider_cb_buffer_free(Ecore_Buffer *buffer, void *data)
|
||||
{
|
||||
Ecore_Buffer_Provider *provider = data;
|
||||
Shared_Buffer *sb = _ecore_buffer_queue_shared_buffer_find(provider->ebq, buffer);
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(provider);
|
||||
|
||||
if (!sb) return;
|
||||
|
||||
_ecore_buffer_provider_shared_buffer_free(provider, sb);
|
||||
}
|
||||
|
||||
static Shared_Buffer *
|
||||
_ecore_buffer_provider_shared_buffer_new(Ecore_Buffer_Provider *provider, Ecore_Buffer *buffer)
|
||||
{
|
||||
Shared_Buffer *sb;
|
||||
struct bq_buffer *buf_resource;
|
||||
unsigned int w = 0, h = 0, format = 0;
|
||||
Ecore_Export_Type export_type;
|
||||
int export_id;
|
||||
const char *engine;
|
||||
unsigned int flags;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(provider, NULL);
|
||||
|
||||
DBG("Create Shared Buffer - buffer %p", buffer);
|
||||
|
||||
if (!provider->ebq)
|
||||
{
|
||||
WARN("Not connected with consumer yet.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ecore_buffer_size_get(buffer, &w, &h);
|
||||
format = ecore_buffer_format_get(buffer);
|
||||
export_type = _ecore_buffer_export(buffer, &export_id);
|
||||
engine = _ecore_buffer_engine_name_get(buffer);
|
||||
flags = ecore_buffer_flags_get(buffer);
|
||||
|
||||
buf_resource = bq_provider_attach_buffer(provider->resource, engine, w, h, format, flags);
|
||||
if (!buf_resource)
|
||||
{
|
||||
ERR("Fail to attach buffer - engine %s, size (%dx%d), format %d, flags %d",
|
||||
engine, w, h, format, flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (export_type)
|
||||
{
|
||||
case EXPORT_TYPE_ID:
|
||||
bq_provider_set_buffer_id(provider->resource, buf_resource,
|
||||
export_id, 0, 0, 0, 0, 0, 0);
|
||||
break;
|
||||
case EXPORT_TYPE_FD:
|
||||
bq_provider_set_buffer_fd(provider->resource, buf_resource,
|
||||
export_id, 0, 0, 0, 0, 0, 0);
|
||||
close(export_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sb = _shared_buffer_new(engine, buf_resource, w, h, format, flags);
|
||||
_shared_buffer_buffer_set(sb, buffer);
|
||||
_ecore_buffer_queue_shared_buffer_add(provider->ebq, sb);
|
||||
bq_buffer_set_user_data(buf_resource, sb);
|
||||
|
||||
ecore_buffer_free_callback_add(buffer, _ecore_buffer_provider_cb_buffer_free, provider);
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_provider_shared_buffer_free(Ecore_Buffer_Provider *provider, Shared_Buffer *sb)
|
||||
{
|
||||
struct bq_buffer *buf_resource;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(provider);
|
||||
EINA_SAFETY_ON_NULL_RETURN(sb);
|
||||
|
||||
buf_resource = _shared_buffer_resource_get(sb);
|
||||
if (!buf_resource)
|
||||
return;
|
||||
|
||||
DBG("Free Shared Buffer");
|
||||
|
||||
bq_provider_detach_buffer(provider->resource, buf_resource);
|
||||
bq_buffer_destroy(buf_resource);
|
||||
|
||||
_ecore_buffer_queue_shared_buffer_remove(provider->ebq, sb);
|
||||
_shared_buffer_free(sb);
|
||||
|
||||
provider->free_slot++;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#include <Ecore_Buffer_Queue.h>
|
||||
#include "ecore_buffer_private.h"
|
||||
#include "ecore_buffer_con.h"
|
||||
|
||||
int _ecore_buffer_queue_log_dom = -1;
|
||||
static int _ecore_buffer_queue_init_count = 0;
|
||||
|
||||
EAPI int
|
||||
ecore_buffer_queue_init(void)
|
||||
{
|
||||
if (++_ecore_buffer_queue_init_count != 1)
|
||||
return _ecore_buffer_queue_init_count;
|
||||
|
||||
_ecore_buffer_queue_log_dom =
|
||||
eina_log_domain_register("ecore_buffer_queue", EINA_COLOR_GREEN);
|
||||
|
||||
if (_ecore_buffer_queue_log_dom < 0)
|
||||
{
|
||||
EINA_LOG_ERR("Could not register log domain: ecore_buffer_queue");
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
eina_log_abort_on_critical_level_set(EINA_LOG_LEVEL_ERR);
|
||||
eina_log_abort_on_critical_set(EINA_TRUE);
|
||||
#endif
|
||||
|
||||
DBG("Ecore_Buffer_Queue Init");
|
||||
|
||||
if (!_ecore_buffer_con_init())
|
||||
{
|
||||
eina_log_domain_unregister(_ecore_buffer_queue_log_dom);
|
||||
_ecore_buffer_queue_log_dom = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return _ecore_buffer_queue_init_count;
|
||||
err:
|
||||
return --_ecore_buffer_queue_init_count;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
ecore_buffer_queue_shutdown(void)
|
||||
{
|
||||
if (--_ecore_buffer_queue_init_count != 0)
|
||||
return _ecore_buffer_queue_init_count;
|
||||
|
||||
DBG("Ecore_Buffer_Queue Shutdown");
|
||||
_ecore_buffer_con_shutdown();
|
||||
eina_log_domain_unregister(_ecore_buffer_queue_log_dom);
|
||||
_ecore_buffer_queue_log_dom = -1;
|
||||
|
||||
return _ecore_buffer_queue_init_count;
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
#include "shared_buffer.h"
|
||||
|
||||
struct _Shared_Buffer
|
||||
{
|
||||
Ecore_Buffer *buffer;
|
||||
struct bq_buffer *resource;
|
||||
const char *engine;
|
||||
int w, h;
|
||||
int format;
|
||||
unsigned int flags;
|
||||
Shared_Buffer_State state;
|
||||
};
|
||||
|
||||
Shared_Buffer *
|
||||
_shared_buffer_new(const char *engine, struct bq_buffer *resource, int w, int h, int format, unsigned int flags)
|
||||
{
|
||||
Shared_Buffer *sb;
|
||||
|
||||
sb = calloc(1, sizeof(Shared_Buffer));
|
||||
if (!sb)
|
||||
return NULL;
|
||||
|
||||
sb->engine = eina_stringshare_add(engine);
|
||||
sb->resource = resource;
|
||||
sb->w = w;
|
||||
sb->h = h;
|
||||
sb->format = format;
|
||||
sb->flags = flags;
|
||||
sb->state = SHARED_BUFFER_STATE_NEW;
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void
|
||||
_shared_buffer_free(Shared_Buffer *sb)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(sb);
|
||||
|
||||
if (sb->engine) eina_stringshare_del(sb->engine);
|
||||
free(sb);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_shared_buffer_info_get(Shared_Buffer *sb, const char **engine, int *w, int *h, int *format, unsigned int *flags)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sb, EINA_FALSE);
|
||||
|
||||
if (engine) *engine = sb->engine;
|
||||
if (w) *w = sb->w;
|
||||
if (h) *h = sb->h;
|
||||
if (format) *format = sb->format;
|
||||
if (flags) *flags = sb->flags;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_shared_buffer_buffer_set(Shared_Buffer *sb, Ecore_Buffer *buffer)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sb, EINA_FALSE);
|
||||
|
||||
if (sb->buffer)
|
||||
{
|
||||
ERR("Already exist buffer");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
sb->buffer = buffer;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Ecore_Buffer *
|
||||
_shared_buffer_buffer_get(Shared_Buffer *sb)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sb, NULL);
|
||||
|
||||
return sb->buffer;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_shared_buffer_resource_set(Shared_Buffer *sb, struct bq_buffer *resource)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sb, EINA_FALSE);
|
||||
|
||||
if (sb->resource)
|
||||
{
|
||||
ERR("Already exist resource");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
sb->resource = resource;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
struct bq_buffer *
|
||||
_shared_buffer_resource_get(Shared_Buffer *sb)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sb, NULL);
|
||||
|
||||
return sb->resource;
|
||||
}
|
||||
|
||||
void
|
||||
_shared_buffer_state_set(Shared_Buffer *sb, Shared_Buffer_State state)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(sb);
|
||||
|
||||
sb->state = state;
|
||||
}
|
||||
|
||||
Shared_Buffer_State
|
||||
_shared_buffer_state_get(Shared_Buffer *sb)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sb, SHARED_BUFFER_STATE_UNKNOWN);
|
||||
|
||||
return sb->state;
|
||||
}
|
||||
|
||||
const char *
|
||||
_shared_buffer_state_string_get(Shared_Buffer *sb)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sb, "INVAILD OBJECT");
|
||||
|
||||
switch (sb->state)
|
||||
{
|
||||
case SHARED_BUFFER_STATE_ENQUEUE:
|
||||
return "SHARED_BUFFER_STATE_ENQUEUE";
|
||||
case SHARED_BUFFER_STATE_SUBMIT:
|
||||
return "SHARED_BUFFER_STATE_SUBMIT";
|
||||
case SHARED_BUFFER_STATE_DEQUEUE:
|
||||
return "SHARED_BUFFER_STATE_DEQUEUE";
|
||||
case SHARED_BUFFER_STATE_ATTACH:
|
||||
return "SHARED_BUFFER_STATE_ATTACH";
|
||||
case SHARED_BUFFER_STATE_IMPORT:
|
||||
return "SHARED_BUFFER_STATE_IMPORT";
|
||||
case SHARED_BUFFER_STATE_DETACH:
|
||||
return "SHARED_BUFFER_STATE_DETACH";
|
||||
case SHARED_BUFFER_STATE_ACQUIRE:
|
||||
return "SHARED_BUFFER_STATE_ACQUIRE";
|
||||
case SHARED_BUFFER_STATE_RELEASE:
|
||||
return "SHARED_BUFFER_STATE_RELEASE";
|
||||
default:
|
||||
case SHARED_BUFFER_STATE_UNKNOWN:
|
||||
return "SHARED_BUFFER_STATE_UNKNOWN";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef _SHARED_BUFFER_H_
|
||||
# define _SHARED_BUFFER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Eina.h>
|
||||
#include <Ecore_Buffer.h>
|
||||
|
||||
#include "bq_mgr_protocol.h"
|
||||
#include "ecore_buffer_private.h"
|
||||
|
||||
typedef struct _Shared_Buffer Shared_Buffer;
|
||||
|
||||
typedef enum _Shared_Buffer_State
|
||||
{
|
||||
// common
|
||||
SHARED_BUFFER_STATE_UNKNOWN,
|
||||
SHARED_BUFFER_STATE_ENQUEUE,
|
||||
// provider side type
|
||||
SHARED_BUFFER_STATE_NEW,
|
||||
SHARED_BUFFER_STATE_SUBMIT,
|
||||
SHARED_BUFFER_STATE_DEQUEUE,
|
||||
// consumer side type
|
||||
SHARED_BUFFER_STATE_ATTACH,
|
||||
SHARED_BUFFER_STATE_IMPORT,
|
||||
SHARED_BUFFER_STATE_DETACH,
|
||||
SHARED_BUFFER_STATE_ACQUIRE,
|
||||
SHARED_BUFFER_STATE_RELEASE,
|
||||
} Shared_Buffer_State;
|
||||
|
||||
Shared_Buffer *_shared_buffer_new(const char *engine, struct bq_buffer *resource, int w, int h, int format, unsigned int flags);
|
||||
void _shared_buffer_free(Shared_Buffer *sb);
|
||||
Eina_Bool _shared_buffer_info_get(Shared_Buffer *sb, const char **engine, int *w, int *h, int *format, unsigned int *flags);
|
||||
Eina_Bool _shared_buffer_buffer_set(Shared_Buffer *sb, Ecore_Buffer *buffer);
|
||||
Ecore_Buffer *_shared_buffer_buffer_get(Shared_Buffer *sb);
|
||||
Eina_Bool _shared_buffer_resource_set(Shared_Buffer *sb, struct bq_buffer *resource);
|
||||
struct bq_buffer *_shared_buffer_resource_get(Shared_Buffer *sb);
|
||||
void _shared_buffer_state_set(Shared_Buffer *sb, Shared_Buffer_State state);
|
||||
Shared_Buffer_State _shared_buffer_state_get(Shared_Buffer *sb);
|
||||
const char *_shared_buffer_state_string_get(Shared_Buffer *sb);
|
||||
|
||||
#endif /* _SHARED_BUFFER_H_ */
|
|
@ -0,0 +1,172 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Buffer.h>
|
||||
|
||||
typedef struct _Ecore_Buffer_Shm_Data Ecore_Buffer_Shm_Data;
|
||||
|
||||
struct _Ecore_Buffer_Shm_Data {
|
||||
const char *file;
|
||||
void *addr;
|
||||
int w, h, stride, size;
|
||||
Eina_Bool am_owner : 1;
|
||||
};
|
||||
|
||||
static void
|
||||
_ecore_buffer_shm_buffer_free(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
|
||||
{
|
||||
Ecore_Buffer_Shm_Data* b = bdata;
|
||||
|
||||
if (b->am_owner)
|
||||
if (b->file) unlink(b->file);
|
||||
|
||||
if (b->addr != MAP_FAILED) munmap(b->addr, b->size);
|
||||
eina_stringshare_del(b->file);
|
||||
b->file = NULL;
|
||||
b->addr = MAP_FAILED;
|
||||
b->am_owner = EINA_FALSE;
|
||||
b->w = 0;
|
||||
b->h = 0;
|
||||
b->stride = 0;
|
||||
b->size = 0;
|
||||
free(b);
|
||||
}
|
||||
|
||||
|
||||
static Ecore_Buffer_Data
|
||||
_ecore_buffer_shm_buffer_alloc(Ecore_Buffer_Module_Data bmdata, int width, int height, Ecore_Buffer_Format format EINA_UNUSED, unsigned int flags EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Shm_Data* b;
|
||||
char *name;
|
||||
static const char tmp[] = "/ecore-buffer-shared-XXXXXX";
|
||||
const char *path;
|
||||
int fd, size, page_size;
|
||||
|
||||
path = getenv("XDG_RUNTIME_DIR");
|
||||
if (!path)
|
||||
{
|
||||
path = getenv("TMPDIR");
|
||||
if (!path) path = "/tmp";
|
||||
}
|
||||
|
||||
page_size = eina_cpu_page_size();
|
||||
|
||||
b = calloc(1, sizeof(Ecore_Buffer_Shm_Data));
|
||||
fd = -1;
|
||||
b->addr = MAP_FAILED;
|
||||
b->w = width;
|
||||
b->h = height;
|
||||
b->stride = width * sizeof(int);
|
||||
b->size = page_size * (((b->stride * b->h) + (page_size - 1)) / page_size);
|
||||
b->am_owner = EINA_TRUE;
|
||||
|
||||
size = strlen(path) + sizeof(tmp);
|
||||
name = malloc(size);
|
||||
if (!name) goto err;
|
||||
strcpy(name, path);
|
||||
strcat(name, tmp);
|
||||
|
||||
fd = mkostemp(name, O_CLOEXEC);
|
||||
if (fd < 0) goto err_fd;
|
||||
b->file = eina_stringshare_add(name);
|
||||
free(name);
|
||||
|
||||
if (ftruncate(fd, b->size) < 0) goto err;
|
||||
|
||||
b->addr = mmap(NULL, b->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (b->addr == MAP_FAILED) goto err;
|
||||
close(fd);
|
||||
|
||||
return b;
|
||||
err:
|
||||
close(fd);
|
||||
err_fd:
|
||||
_ecore_buffer_shm_buffer_free(bmdata, b);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Ecore_Export_Type
|
||||
_ecore_buffer_shm_buffer_export(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, int *id)
|
||||
{
|
||||
Ecore_Buffer_Shm_Data* b = bdata;
|
||||
int fd;
|
||||
|
||||
fd = open(b->file, O_RDWR | O_CLOEXEC);
|
||||
if (id) *id = fd;
|
||||
|
||||
return EXPORT_TYPE_FD;
|
||||
}
|
||||
|
||||
static void *
|
||||
_ecore_buffer_shm_buffer_import(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, int w, int h, Ecore_Buffer_Format format EINA_UNUSED, Ecore_Export_Type type, int export_id, unsigned int flags EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Shm_Data* b;
|
||||
int fd, page_size;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(type == EXPORT_TYPE_FD, NULL);
|
||||
|
||||
b = calloc(1, sizeof(Ecore_Buffer_Shm_Data));
|
||||
if (!b) return NULL;
|
||||
|
||||
page_size = eina_cpu_page_size();
|
||||
|
||||
fd = export_id;
|
||||
b->w = w;
|
||||
b->h = h;
|
||||
b->stride = w * sizeof(int);
|
||||
b->size = page_size * (((b->stride * b->h) + (page_size - 1)) / page_size);
|
||||
b->am_owner = EINA_FALSE;
|
||||
|
||||
b->addr = mmap(NULL, b->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (b->addr == MAP_FAILED) goto err;
|
||||
|
||||
return b;
|
||||
err:
|
||||
_ecore_buffer_shm_buffer_free(bmdata, b);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
_ecore_buffer_shm_data_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
|
||||
{
|
||||
Ecore_Buffer_Shm_Data *b = bdata;
|
||||
|
||||
return b->addr;
|
||||
}
|
||||
|
||||
static Ecore_Buffer_Backend _ecore_buffer_shm_backend = {
|
||||
"shm",
|
||||
NULL,
|
||||
NULL,
|
||||
&_ecore_buffer_shm_buffer_alloc,
|
||||
&_ecore_buffer_shm_buffer_free,
|
||||
&_ecore_buffer_shm_buffer_export,
|
||||
&_ecore_buffer_shm_buffer_import,
|
||||
&_ecore_buffer_shm_data_get,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
Eina_Bool shm_init(void)
|
||||
{
|
||||
return ecore_buffer_register(&_ecore_buffer_shm_backend);
|
||||
}
|
||||
|
||||
void shm_shutdown(void)
|
||||
{
|
||||
ecore_buffer_unregister(&_ecore_buffer_shm_backend);
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(shm_init);
|
||||
EINA_MODULE_SHUTDOWN(shm_shutdown);
|
|
@ -0,0 +1,538 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_X.h>
|
||||
|
||||
#include <tbm_bufmgr.h>
|
||||
#include <tbm_surface.h>
|
||||
#include <tbm_surface_internal.h>
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <X11/Xmd.h>
|
||||
#include <dri2/dri2.h>
|
||||
|
||||
#include "Ecore_Buffer.h"
|
||||
#include "ecore_buffer_private.h"
|
||||
|
||||
typedef struct _Ecore_Buffer_Module_X11_Dri2_Data Ecore_Buffer_Module_X11_Dri2_Data;
|
||||
typedef struct _Ecore_Buffer_X11_Dri2_Data Ecore_Buffer_X11_Dri2_Data;
|
||||
|
||||
struct _Ecore_Buffer_Module_X11_Dri2_Data {
|
||||
tbm_bufmgr tbm_mgr;
|
||||
};
|
||||
|
||||
struct _Ecore_Buffer_X11_Dri2_Data {
|
||||
Ecore_X_Pixmap pixmap;
|
||||
int w;
|
||||
int h;
|
||||
int stride;
|
||||
Ecore_Buffer_Format format;
|
||||
Eina_Bool is_imported;
|
||||
|
||||
struct
|
||||
{
|
||||
void *surface;
|
||||
Eina_Bool owned;
|
||||
} tbm;
|
||||
};
|
||||
|
||||
static int
|
||||
_buf_get_num_planes(Ecore_Buffer_Format format)
|
||||
{
|
||||
int num_planes = 0;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case ECORE_BUFFER_FORMAT_C8:
|
||||
case ECORE_BUFFER_FORMAT_RGB332:
|
||||
case ECORE_BUFFER_FORMAT_BGR233:
|
||||
case ECORE_BUFFER_FORMAT_XRGB4444:
|
||||
case ECORE_BUFFER_FORMAT_XBGR4444:
|
||||
case ECORE_BUFFER_FORMAT_RGBX4444:
|
||||
case ECORE_BUFFER_FORMAT_BGRX4444:
|
||||
case ECORE_BUFFER_FORMAT_ARGB4444:
|
||||
case ECORE_BUFFER_FORMAT_ABGR4444:
|
||||
case ECORE_BUFFER_FORMAT_RGBA4444:
|
||||
case ECORE_BUFFER_FORMAT_BGRA4444:
|
||||
case ECORE_BUFFER_FORMAT_XRGB1555:
|
||||
case ECORE_BUFFER_FORMAT_XBGR1555:
|
||||
case ECORE_BUFFER_FORMAT_RGBX5551:
|
||||
case ECORE_BUFFER_FORMAT_BGRX5551:
|
||||
case ECORE_BUFFER_FORMAT_ARGB1555:
|
||||
case ECORE_BUFFER_FORMAT_ABGR1555:
|
||||
case ECORE_BUFFER_FORMAT_RGBA5551:
|
||||
case ECORE_BUFFER_FORMAT_BGRA5551:
|
||||
case ECORE_BUFFER_FORMAT_RGB565:
|
||||
case ECORE_BUFFER_FORMAT_BGR565:
|
||||
case ECORE_BUFFER_FORMAT_RGB888:
|
||||
case ECORE_BUFFER_FORMAT_BGR888:
|
||||
case ECORE_BUFFER_FORMAT_XRGB8888:
|
||||
case ECORE_BUFFER_FORMAT_XBGR8888:
|
||||
case ECORE_BUFFER_FORMAT_RGBX8888:
|
||||
case ECORE_BUFFER_FORMAT_BGRX8888:
|
||||
case ECORE_BUFFER_FORMAT_ARGB8888:
|
||||
case ECORE_BUFFER_FORMAT_ABGR8888:
|
||||
case ECORE_BUFFER_FORMAT_RGBA8888:
|
||||
case ECORE_BUFFER_FORMAT_BGRA8888:
|
||||
case ECORE_BUFFER_FORMAT_XRGB2101010:
|
||||
case ECORE_BUFFER_FORMAT_XBGR2101010:
|
||||
case ECORE_BUFFER_FORMAT_RGBX1010102:
|
||||
case ECORE_BUFFER_FORMAT_BGRX1010102:
|
||||
case ECORE_BUFFER_FORMAT_ARGB2101010:
|
||||
case ECORE_BUFFER_FORMAT_ABGR2101010:
|
||||
case ECORE_BUFFER_FORMAT_RGBA1010102:
|
||||
case ECORE_BUFFER_FORMAT_BGRA1010102:
|
||||
case ECORE_BUFFER_FORMAT_YUYV:
|
||||
case ECORE_BUFFER_FORMAT_YVYU:
|
||||
case ECORE_BUFFER_FORMAT_UYVY:
|
||||
case ECORE_BUFFER_FORMAT_VYUY:
|
||||
case ECORE_BUFFER_FORMAT_AYUV:
|
||||
num_planes = 1;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_NV12:
|
||||
case ECORE_BUFFER_FORMAT_NV21:
|
||||
case ECORE_BUFFER_FORMAT_NV16:
|
||||
case ECORE_BUFFER_FORMAT_NV61:
|
||||
num_planes = 2;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUV410:
|
||||
case ECORE_BUFFER_FORMAT_YVU410:
|
||||
case ECORE_BUFFER_FORMAT_YUV411:
|
||||
case ECORE_BUFFER_FORMAT_YVU411:
|
||||
case ECORE_BUFFER_FORMAT_YUV420:
|
||||
case ECORE_BUFFER_FORMAT_YVU420:
|
||||
case ECORE_BUFFER_FORMAT_YUV422:
|
||||
case ECORE_BUFFER_FORMAT_YVU422:
|
||||
case ECORE_BUFFER_FORMAT_YUV444:
|
||||
case ECORE_BUFFER_FORMAT_YVU444:
|
||||
num_planes = 3;
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return num_planes;
|
||||
}
|
||||
|
||||
static int
|
||||
_buf_get_bpp(Ecore_Buffer_Format format)
|
||||
{
|
||||
int bpp = 0;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case ECORE_BUFFER_FORMAT_C8:
|
||||
case ECORE_BUFFER_FORMAT_RGB332:
|
||||
case ECORE_BUFFER_FORMAT_BGR233:
|
||||
bpp = 8;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_XRGB4444:
|
||||
case ECORE_BUFFER_FORMAT_XBGR4444:
|
||||
case ECORE_BUFFER_FORMAT_RGBX4444:
|
||||
case ECORE_BUFFER_FORMAT_BGRX4444:
|
||||
case ECORE_BUFFER_FORMAT_ARGB4444:
|
||||
case ECORE_BUFFER_FORMAT_ABGR4444:
|
||||
case ECORE_BUFFER_FORMAT_RGBA4444:
|
||||
case ECORE_BUFFER_FORMAT_BGRA4444:
|
||||
case ECORE_BUFFER_FORMAT_XRGB1555:
|
||||
case ECORE_BUFFER_FORMAT_XBGR1555:
|
||||
case ECORE_BUFFER_FORMAT_RGBX5551:
|
||||
case ECORE_BUFFER_FORMAT_BGRX5551:
|
||||
case ECORE_BUFFER_FORMAT_ARGB1555:
|
||||
case ECORE_BUFFER_FORMAT_ABGR1555:
|
||||
case ECORE_BUFFER_FORMAT_RGBA5551:
|
||||
case ECORE_BUFFER_FORMAT_BGRA5551:
|
||||
case ECORE_BUFFER_FORMAT_RGB565:
|
||||
case ECORE_BUFFER_FORMAT_BGR565:
|
||||
bpp = 16;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_RGB888:
|
||||
case ECORE_BUFFER_FORMAT_BGR888:
|
||||
bpp = 24;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_XRGB8888:
|
||||
case ECORE_BUFFER_FORMAT_XBGR8888:
|
||||
case ECORE_BUFFER_FORMAT_RGBX8888:
|
||||
case ECORE_BUFFER_FORMAT_BGRX8888:
|
||||
case ECORE_BUFFER_FORMAT_ARGB8888:
|
||||
case ECORE_BUFFER_FORMAT_ABGR8888:
|
||||
case ECORE_BUFFER_FORMAT_RGBA8888:
|
||||
case ECORE_BUFFER_FORMAT_BGRA8888:
|
||||
case ECORE_BUFFER_FORMAT_XRGB2101010:
|
||||
case ECORE_BUFFER_FORMAT_XBGR2101010:
|
||||
case ECORE_BUFFER_FORMAT_RGBX1010102:
|
||||
case ECORE_BUFFER_FORMAT_BGRX1010102:
|
||||
case ECORE_BUFFER_FORMAT_ARGB2101010:
|
||||
case ECORE_BUFFER_FORMAT_ABGR2101010:
|
||||
case ECORE_BUFFER_FORMAT_RGBA1010102:
|
||||
case ECORE_BUFFER_FORMAT_BGRA1010102:
|
||||
case ECORE_BUFFER_FORMAT_YUYV:
|
||||
case ECORE_BUFFER_FORMAT_YVYU:
|
||||
case ECORE_BUFFER_FORMAT_UYVY:
|
||||
case ECORE_BUFFER_FORMAT_VYUY:
|
||||
case ECORE_BUFFER_FORMAT_AYUV:
|
||||
bpp = 32;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_NV12:
|
||||
case ECORE_BUFFER_FORMAT_NV21:
|
||||
bpp = 12;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_NV16:
|
||||
case ECORE_BUFFER_FORMAT_NV61:
|
||||
bpp = 16;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUV410:
|
||||
case ECORE_BUFFER_FORMAT_YVU410:
|
||||
bpp = 9;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUV411:
|
||||
case ECORE_BUFFER_FORMAT_YVU411:
|
||||
case ECORE_BUFFER_FORMAT_YUV420:
|
||||
case ECORE_BUFFER_FORMAT_YVU420:
|
||||
bpp = 12;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUV422:
|
||||
case ECORE_BUFFER_FORMAT_YVU422:
|
||||
bpp = 16;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUV444:
|
||||
case ECORE_BUFFER_FORMAT_YVU444:
|
||||
bpp = 24;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return bpp;
|
||||
}
|
||||
|
||||
static Ecore_Buffer_Module_Data
|
||||
_ecore_buffer_x11_dri2_init(const char *context EINA_UNUSED, const char *options EINA_UNUSED)
|
||||
{
|
||||
Ecore_X_Display *xdpy;
|
||||
Ecore_X_Window root;
|
||||
int eb, ee;
|
||||
int major, minor;
|
||||
char *driver_name;
|
||||
char *device_name;
|
||||
int fd = 0;
|
||||
drm_magic_t magic;
|
||||
Ecore_Buffer_Module_X11_Dri2_Data *mdata = NULL;
|
||||
|
||||
if (!ecore_x_init(NULL))
|
||||
return NULL;
|
||||
|
||||
xdpy = ecore_x_display_get();
|
||||
if (!xdpy)
|
||||
goto on_error;
|
||||
|
||||
root = ecore_x_window_root_first_get();
|
||||
if (!root)
|
||||
goto on_error;
|
||||
|
||||
mdata = calloc(1, sizeof(Ecore_Buffer_Module_X11_Dri2_Data));
|
||||
if (!mdata)
|
||||
goto on_error;
|
||||
|
||||
//Init DRI2 and TBM
|
||||
DRI2QueryExtension(xdpy, &eb, &ee);
|
||||
DRI2QueryVersion(xdpy, &major, &minor);
|
||||
DRI2Connect(xdpy, root, &driver_name, &device_name);
|
||||
|
||||
fd = open (device_name, O_RDWR);
|
||||
if (fd < 0)
|
||||
goto on_error;
|
||||
|
||||
if (drmGetMagic(fd, &magic) < 0)
|
||||
goto on_error;
|
||||
|
||||
if (!(DRI2Authenticate(xdpy, root, magic)))
|
||||
goto on_error;
|
||||
|
||||
mdata->tbm_mgr = tbm_bufmgr_init(fd);
|
||||
if (!mdata->tbm_mgr)
|
||||
goto on_error;
|
||||
|
||||
free(driver_name);
|
||||
free(device_name);
|
||||
close(fd);
|
||||
|
||||
return mdata;
|
||||
|
||||
on_error:
|
||||
if (fd > 0) close(fd);
|
||||
if (driver_name) free(driver_name);
|
||||
if (device_name) free(device_name);
|
||||
if (mdata) free(mdata);
|
||||
ecore_x_shutdown();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_x11_dri2_shutdown(Ecore_Buffer_Module_Data bmdata)
|
||||
{
|
||||
Ecore_Buffer_Module_X11_Dri2_Data *bm = bmdata;
|
||||
|
||||
if (bm->tbm_mgr)
|
||||
tbm_bufmgr_deinit(bm->tbm_mgr);
|
||||
|
||||
ecore_x_shutdown();
|
||||
}
|
||||
|
||||
static Ecore_Buffer_Data
|
||||
_ecore_buffer_x11_dri2_buffer_alloc(Ecore_Buffer_Module_Data bmdata, int width, int height, Ecore_Buffer_Format format, unsigned int flags EINA_UNUSED)
|
||||
{
|
||||
Ecore_X_Display *xdpy;
|
||||
Ecore_X_Pixmap pixmap;
|
||||
Ecore_Buffer_X11_Dri2_Data *buf;
|
||||
Ecore_Buffer_Module_X11_Dri2_Data *bm = bmdata;
|
||||
DRI2Buffer *bufs = NULL;
|
||||
tbm_bo bo = NULL;
|
||||
int bpp;
|
||||
int num_plane;
|
||||
int rw, rh, rcount;
|
||||
unsigned int attachment = DRI2BufferFrontLeft;
|
||||
tbm_surface_info_s info;
|
||||
int i;
|
||||
|
||||
bpp = _buf_get_bpp(format);
|
||||
if (bpp != 32)
|
||||
return NULL;
|
||||
|
||||
num_plane = _buf_get_num_planes(format);
|
||||
if (num_plane != 1)
|
||||
return NULL;
|
||||
|
||||
xdpy = ecore_x_display_get();
|
||||
pixmap = ecore_x_pixmap_new(0, width, height, bpp);
|
||||
if (!pixmap)
|
||||
return NULL;
|
||||
|
||||
buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri2_Data));
|
||||
if (!buf)
|
||||
{
|
||||
ecore_x_pixmap_free(pixmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf->w = width;
|
||||
buf->h = height;
|
||||
buf->format = format;
|
||||
buf->pixmap = pixmap;
|
||||
buf->is_imported = EINA_FALSE;
|
||||
|
||||
//Get DRI2Buffer
|
||||
DRI2CreateDrawable(xdpy, buf->pixmap);
|
||||
bufs = DRI2GetBuffers(xdpy, buf->pixmap, &rw, &rh, &attachment, 1, &rcount);
|
||||
if (!(bufs) || (buf->w != rw) || (buf->h != rh))
|
||||
goto on_error;
|
||||
|
||||
buf->stride = bufs->pitch;
|
||||
|
||||
//Import tbm_surface
|
||||
bo = tbm_bo_import(bm->tbm_mgr, bufs->name);
|
||||
if (!bo)
|
||||
goto on_error;
|
||||
|
||||
info.width = width;
|
||||
info.height = height;
|
||||
info.format = format;
|
||||
info.bpp = bpp;
|
||||
info.size = width * bufs->pitch;
|
||||
for ( i = 0 ; i < num_plane ; i++)
|
||||
{
|
||||
info.planes[i].size = width * bufs->pitch;
|
||||
info.planes[i].stride = bufs->pitch;
|
||||
info.planes[i].offset = 0;
|
||||
}
|
||||
|
||||
buf->tbm.surface = tbm_surface_internal_create_with_bos(&info, &bo, 1);
|
||||
if (!buf->tbm.surface)
|
||||
goto on_error;
|
||||
|
||||
buf->tbm.owned = EINA_TRUE;
|
||||
tbm_bo_unref(bo);
|
||||
free(bufs);
|
||||
|
||||
return buf;
|
||||
|
||||
on_error:
|
||||
if (bo) tbm_bo_unref(bo);
|
||||
if (bufs) free(bufs);
|
||||
ecore_x_pixmap_free(buf->pixmap);
|
||||
DRI2DestroyDrawable(xdpy, buf->pixmap);
|
||||
free(buf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_x11_dri2_buffer_free(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
|
||||
{
|
||||
Ecore_Buffer_X11_Dri2_Data *buf = bdata;
|
||||
|
||||
if (buf->pixmap)
|
||||
{
|
||||
DRI2DestroyDrawable(ecore_x_display_get(), buf->pixmap);
|
||||
|
||||
if (!buf->is_imported)
|
||||
ecore_x_pixmap_free(buf->pixmap);
|
||||
}
|
||||
|
||||
if (buf->tbm.surface)
|
||||
tbm_surface_destroy(buf->tbm.surface);
|
||||
|
||||
free(buf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static Ecore_Export_Type
|
||||
_ecore_buffer_x11_dri2_buffer_export(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, int *id)
|
||||
{
|
||||
Ecore_Buffer_X11_Dri2_Data *buf = bdata;
|
||||
|
||||
if (id) *id = buf->pixmap;
|
||||
|
||||
return EXPORT_TYPE_ID;
|
||||
}
|
||||
|
||||
static void *
|
||||
_ecore_buffer_x11_dri2_buffer_import(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, int w, int h, Ecore_Buffer_Format format, Ecore_Export_Type type, int export_id, unsigned int flags EINA_UNUSED)
|
||||
{
|
||||
Ecore_Buffer_Module_X11_Dri2_Data *bm = bmdata;
|
||||
Ecore_X_Display *xdpy;
|
||||
Ecore_X_Pixmap pixmap = (Ecore_X_Pixmap)export_id;
|
||||
Ecore_Buffer_X11_Dri2_Data *buf;
|
||||
int rw, rh, rx, ry;
|
||||
DRI2Buffer *bufs = NULL;
|
||||
tbm_bo bo = NULL;
|
||||
int rcount;
|
||||
unsigned int attachment = DRI2BufferFrontLeft;
|
||||
tbm_surface_info_s info;
|
||||
int num_plane,i;
|
||||
|
||||
if (type != EXPORT_TYPE_ID)
|
||||
return NULL;
|
||||
|
||||
xdpy = ecore_x_display_get();
|
||||
|
||||
//Check valid pixmap
|
||||
ecore_x_pixmap_geometry_get(pixmap, &rx, &ry, &rw, &rh);
|
||||
if ((rw != w) || (rh != h))
|
||||
return NULL;
|
||||
|
||||
buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri2_Data));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
buf->w = w;
|
||||
buf->h = h;
|
||||
buf->format = format;
|
||||
buf->pixmap = pixmap;
|
||||
buf->is_imported = EINA_TRUE;
|
||||
|
||||
//Get DRI2Buffer
|
||||
DRI2CreateDrawable(xdpy, buf->pixmap);
|
||||
bufs = DRI2GetBuffers(xdpy, buf->pixmap, &rw, &rh, &attachment, 1, &rcount);
|
||||
if ((!bufs) || (buf->w != rw) || (buf->h != rh))
|
||||
goto on_error;
|
||||
|
||||
buf->stride = bufs->pitch;
|
||||
|
||||
//Import tbm_surface
|
||||
bo = tbm_bo_import(bm->tbm_mgr, bufs->name);
|
||||
if (!bo)
|
||||
goto on_error;
|
||||
|
||||
num_plane = _buf_get_num_planes(format);
|
||||
info.width = w;
|
||||
info.height = h;
|
||||
info.format = format;
|
||||
info.bpp = _buf_get_bpp(format);
|
||||
info.size = w * bufs->pitch;
|
||||
for ( i = 0 ; i < num_plane ; i++)
|
||||
{
|
||||
info.planes[i].size = w * bufs->pitch;
|
||||
info.planes[i].stride = bufs->pitch;
|
||||
info.planes[i].offset = 0;
|
||||
}
|
||||
|
||||
buf->tbm.surface = tbm_surface_internal_create_with_bos(&info, &bo, 1);
|
||||
if (!buf->tbm.surface)
|
||||
goto on_error;
|
||||
|
||||
buf->tbm.owned = EINA_TRUE;
|
||||
tbm_bo_unref(bo);
|
||||
free(bufs);
|
||||
|
||||
return buf;
|
||||
on_error:
|
||||
if (bo) tbm_bo_unref(bo);
|
||||
if (bufs) free(bufs);
|
||||
DRI2DestroyDrawable(xdpy, buf->pixmap);
|
||||
free(buf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Ecore_Pixmap
|
||||
_ecore_buffer_x11_dri2_pixmap_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
|
||||
{
|
||||
Ecore_Buffer_X11_Dri2_Data *buf = bdata;
|
||||
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
if (!buf->tbm.owned)
|
||||
return 0;
|
||||
|
||||
return buf->pixmap;
|
||||
}
|
||||
|
||||
static void *
|
||||
_ecore_buffer_x11_dri2_tbm_bo_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
|
||||
{
|
||||
Ecore_Buffer_X11_Dri2_Data *buf = bdata;
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
return buf->tbm.surface;
|
||||
}
|
||||
|
||||
static Ecore_Buffer_Backend _ecore_buffer_x11_dri2_backend = {
|
||||
"x11_dri2",
|
||||
&_ecore_buffer_x11_dri2_init,
|
||||
&_ecore_buffer_x11_dri2_shutdown,
|
||||
&_ecore_buffer_x11_dri2_buffer_alloc,
|
||||
&_ecore_buffer_x11_dri2_buffer_free,
|
||||
&_ecore_buffer_x11_dri2_buffer_export,
|
||||
&_ecore_buffer_x11_dri2_buffer_import,
|
||||
NULL,
|
||||
&_ecore_buffer_x11_dri2_pixmap_get,
|
||||
&_ecore_buffer_x11_dri2_tbm_bo_get,
|
||||
};
|
||||
|
||||
Eina_Bool x11_dri2_init(void)
|
||||
{
|
||||
return ecore_buffer_register(&_ecore_buffer_x11_dri2_backend);
|
||||
}
|
||||
|
||||
void x11_dri2_shutdown(void)
|
||||
{
|
||||
ecore_buffer_unregister(&_ecore_buffer_x11_dri2_backend);
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(x11_dri2_init);
|
||||
EINA_MODULE_SHUTDOWN(x11_dri2_shutdown);
|
|
@ -0,0 +1,602 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <X11/xshmfence.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/dri3.h>
|
||||
#include <xcb/sync.h>
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_X.h>
|
||||
#include <Ecore_Buffer.h>
|
||||
|
||||
#include <tbm_bufmgr.h>
|
||||
#include <tbm_surface.h>
|
||||
#include <tbm_surface_internal.h>
|
||||
|
||||
#include "ecore_buffer_private.h"
|
||||
|
||||
typedef struct _Ecore_Buffer_Module_X11_Dri3_Data Ecore_Buffer_Module_X11_Dri3_Data;
|
||||
typedef struct _Ecore_Buffer_X11_Dri3_Data Ecore_Buffer_X11_Dri3_Data;
|
||||
|
||||
struct _Ecore_Buffer_Module_X11_Dri3_Data {
|
||||
tbm_bufmgr tbm_mgr;
|
||||
};
|
||||
|
||||
struct _Ecore_Buffer_X11_Dri3_Data {
|
||||
Ecore_X_Pixmap pixmap;
|
||||
void *tbm_surface;
|
||||
int w;
|
||||
int h;
|
||||
int stride;
|
||||
unsigned int flags;
|
||||
Ecore_Buffer_Format format;
|
||||
Eina_Bool is_imported;
|
||||
};
|
||||
|
||||
static int
|
||||
_buf_get_num_planes(Ecore_Buffer_Format format)
|
||||
{
|
||||
int num_planes = 0;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case ECORE_BUFFER_FORMAT_C8:
|
||||
case ECORE_BUFFER_FORMAT_RGB332:
|
||||
case ECORE_BUFFER_FORMAT_BGR233:
|
||||
case ECORE_BUFFER_FORMAT_XRGB4444:
|
||||
case ECORE_BUFFER_FORMAT_XBGR4444:
|
||||
case ECORE_BUFFER_FORMAT_RGBX4444:
|
||||
case ECORE_BUFFER_FORMAT_BGRX4444:
|
||||
case ECORE_BUFFER_FORMAT_ARGB4444:
|
||||
case ECORE_BUFFER_FORMAT_ABGR4444:
|
||||
case ECORE_BUFFER_FORMAT_RGBA4444:
|
||||
case ECORE_BUFFER_FORMAT_BGRA4444:
|
||||
case ECORE_BUFFER_FORMAT_XRGB1555:
|
||||
case ECORE_BUFFER_FORMAT_XBGR1555:
|
||||
case ECORE_BUFFER_FORMAT_RGBX5551:
|
||||
case ECORE_BUFFER_FORMAT_BGRX5551:
|
||||
case ECORE_BUFFER_FORMAT_ARGB1555:
|
||||
case ECORE_BUFFER_FORMAT_ABGR1555:
|
||||
case ECORE_BUFFER_FORMAT_RGBA5551:
|
||||
case ECORE_BUFFER_FORMAT_BGRA5551:
|
||||
case ECORE_BUFFER_FORMAT_RGB565:
|
||||
case ECORE_BUFFER_FORMAT_BGR565:
|
||||
case ECORE_BUFFER_FORMAT_RGB888:
|
||||
case ECORE_BUFFER_FORMAT_BGR888:
|
||||
case ECORE_BUFFER_FORMAT_XRGB8888:
|
||||
case ECORE_BUFFER_FORMAT_XBGR8888:
|
||||
case ECORE_BUFFER_FORMAT_RGBX8888:
|
||||
case ECORE_BUFFER_FORMAT_BGRX8888:
|
||||
case ECORE_BUFFER_FORMAT_ARGB8888:
|
||||
case ECORE_BUFFER_FORMAT_ABGR8888:
|
||||
case ECORE_BUFFER_FORMAT_RGBA8888:
|
||||
case ECORE_BUFFER_FORMAT_BGRA8888:
|
||||
case ECORE_BUFFER_FORMAT_XRGB2101010:
|
||||
case ECORE_BUFFER_FORMAT_XBGR2101010:
|
||||
case ECORE_BUFFER_FORMAT_RGBX1010102:
|
||||
case ECORE_BUFFER_FORMAT_BGRX1010102:
|
||||
case ECORE_BUFFER_FORMAT_ARGB2101010:
|
||||
case ECORE_BUFFER_FORMAT_ABGR2101010:
|
||||
case ECORE_BUFFER_FORMAT_RGBA1010102:
|
||||
case ECORE_BUFFER_FORMAT_BGRA1010102:
|
||||
case ECORE_BUFFER_FORMAT_YUYV:
|
||||
case ECORE_BUFFER_FORMAT_YVYU:
|
||||
case ECORE_BUFFER_FORMAT_UYVY:
|
||||
case ECORE_BUFFER_FORMAT_VYUY:
|
||||
case ECORE_BUFFER_FORMAT_AYUV:
|
||||
num_planes = 1;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_NV12:
|
||||
case ECORE_BUFFER_FORMAT_NV21:
|
||||
case ECORE_BUFFER_FORMAT_NV16:
|
||||
case ECORE_BUFFER_FORMAT_NV61:
|
||||
num_planes = 2;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUV410:
|
||||
case ECORE_BUFFER_FORMAT_YVU410:
|
||||
case ECORE_BUFFER_FORMAT_YUV411:
|
||||
case ECORE_BUFFER_FORMAT_YVU411:
|
||||
case ECORE_BUFFER_FORMAT_YUV420:
|
||||
case ECORE_BUFFER_FORMAT_YVU420:
|
||||
case ECORE_BUFFER_FORMAT_YUV422:
|
||||
case ECORE_BUFFER_FORMAT_YVU422:
|
||||
case ECORE_BUFFER_FORMAT_YUV444:
|
||||
case ECORE_BUFFER_FORMAT_YVU444:
|
||||
num_planes = 3;
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return num_planes;
|
||||
}
|
||||
|
||||
static int
|
||||
_buf_get_bpp(Ecore_Buffer_Format format)
|
||||
{
|
||||
int bpp = 0;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case ECORE_BUFFER_FORMAT_C8:
|
||||
case ECORE_BUFFER_FORMAT_RGB332:
|
||||
case ECORE_BUFFER_FORMAT_BGR233:
|
||||
bpp = 8;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_XRGB4444:
|
||||
case ECORE_BUFFER_FORMAT_XBGR4444:
|
||||
case ECORE_BUFFER_FORMAT_RGBX4444:
|
||||
case ECORE_BUFFER_FORMAT_BGRX4444:
|
||||
case ECORE_BUFFER_FORMAT_ARGB4444:
|
||||
case ECORE_BUFFER_FORMAT_ABGR4444:
|
||||
case ECORE_BUFFER_FORMAT_RGBA4444:
|
||||
case ECORE_BUFFER_FORMAT_BGRA4444:
|
||||
case ECORE_BUFFER_FORMAT_XRGB1555:
|
||||
case ECORE_BUFFER_FORMAT_XBGR1555:
|
||||
case ECORE_BUFFER_FORMAT_RGBX5551:
|
||||
case ECORE_BUFFER_FORMAT_BGRX5551:
|
||||
case ECORE_BUFFER_FORMAT_ARGB1555:
|
||||
case ECORE_BUFFER_FORMAT_ABGR1555:
|
||||
case ECORE_BUFFER_FORMAT_RGBA5551:
|
||||
case ECORE_BUFFER_FORMAT_BGRA5551:
|
||||
case ECORE_BUFFER_FORMAT_RGB565:
|
||||
case ECORE_BUFFER_FORMAT_BGR565:
|
||||
bpp = 16;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_RGB888:
|
||||
case ECORE_BUFFER_FORMAT_BGR888:
|
||||
bpp = 24;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_XRGB8888:
|
||||
case ECORE_BUFFER_FORMAT_XBGR8888:
|
||||
case ECORE_BUFFER_FORMAT_RGBX8888:
|
||||
case ECORE_BUFFER_FORMAT_BGRX8888:
|
||||
case ECORE_BUFFER_FORMAT_ARGB8888:
|
||||
case ECORE_BUFFER_FORMAT_ABGR8888:
|
||||
case ECORE_BUFFER_FORMAT_RGBA8888:
|
||||
case ECORE_BUFFER_FORMAT_BGRA8888:
|
||||
case ECORE_BUFFER_FORMAT_XRGB2101010:
|
||||
case ECORE_BUFFER_FORMAT_XBGR2101010:
|
||||
case ECORE_BUFFER_FORMAT_RGBX1010102:
|
||||
case ECORE_BUFFER_FORMAT_BGRX1010102:
|
||||
case ECORE_BUFFER_FORMAT_ARGB2101010:
|
||||
case ECORE_BUFFER_FORMAT_ABGR2101010:
|
||||
case ECORE_BUFFER_FORMAT_RGBA1010102:
|
||||
case ECORE_BUFFER_FORMAT_BGRA1010102:
|
||||
case ECORE_BUFFER_FORMAT_YUYV:
|
||||
case ECORE_BUFFER_FORMAT_YVYU:
|
||||
case ECORE_BUFFER_FORMAT_UYVY:
|
||||
case ECORE_BUFFER_FORMAT_VYUY:
|
||||
case ECORE_BUFFER_FORMAT_AYUV:
|
||||
bpp = 32;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_NV12:
|
||||
case ECORE_BUFFER_FORMAT_NV21:
|
||||
bpp = 12;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_NV16:
|
||||
case ECORE_BUFFER_FORMAT_NV61:
|
||||
bpp = 16;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUV410:
|
||||
case ECORE_BUFFER_FORMAT_YVU410:
|
||||
bpp = 9;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUV411:
|
||||
case ECORE_BUFFER_FORMAT_YVU411:
|
||||
case ECORE_BUFFER_FORMAT_YUV420:
|
||||
case ECORE_BUFFER_FORMAT_YVU420:
|
||||
bpp = 12;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUV422:
|
||||
case ECORE_BUFFER_FORMAT_YVU422:
|
||||
bpp = 16;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUV444:
|
||||
case ECORE_BUFFER_FORMAT_YVU444:
|
||||
bpp = 24;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return bpp;
|
||||
}
|
||||
|
||||
static int
|
||||
_buf_get_depth(Ecore_Buffer_Format format)
|
||||
{
|
||||
int depth = 0;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case ECORE_BUFFER_FORMAT_C8:
|
||||
case ECORE_BUFFER_FORMAT_RGB332:
|
||||
case ECORE_BUFFER_FORMAT_BGR233:
|
||||
depth = 8;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_XRGB4444:
|
||||
case ECORE_BUFFER_FORMAT_XBGR4444:
|
||||
case ECORE_BUFFER_FORMAT_RGBX4444:
|
||||
case ECORE_BUFFER_FORMAT_BGRX4444:
|
||||
depth = 12;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_ARGB4444:
|
||||
case ECORE_BUFFER_FORMAT_ABGR4444:
|
||||
case ECORE_BUFFER_FORMAT_RGBA4444:
|
||||
case ECORE_BUFFER_FORMAT_BGRA4444:
|
||||
depth = 16;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_XRGB1555:
|
||||
case ECORE_BUFFER_FORMAT_XBGR1555:
|
||||
case ECORE_BUFFER_FORMAT_RGBX5551:
|
||||
case ECORE_BUFFER_FORMAT_BGRX5551:
|
||||
depth = 15;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_ARGB1555:
|
||||
case ECORE_BUFFER_FORMAT_ABGR1555:
|
||||
case ECORE_BUFFER_FORMAT_RGBA5551:
|
||||
case ECORE_BUFFER_FORMAT_BGRA5551:
|
||||
case ECORE_BUFFER_FORMAT_RGB565:
|
||||
case ECORE_BUFFER_FORMAT_BGR565:
|
||||
depth = 16;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_RGB888:
|
||||
case ECORE_BUFFER_FORMAT_BGR888:
|
||||
depth = 24;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_XRGB8888:
|
||||
case ECORE_BUFFER_FORMAT_XBGR8888:
|
||||
case ECORE_BUFFER_FORMAT_RGBX8888:
|
||||
case ECORE_BUFFER_FORMAT_BGRX8888:
|
||||
depth = 24;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_ARGB8888:
|
||||
case ECORE_BUFFER_FORMAT_ABGR8888:
|
||||
case ECORE_BUFFER_FORMAT_RGBA8888:
|
||||
case ECORE_BUFFER_FORMAT_BGRA8888:
|
||||
depth = 32;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_XRGB2101010:
|
||||
case ECORE_BUFFER_FORMAT_XBGR2101010:
|
||||
case ECORE_BUFFER_FORMAT_RGBX1010102:
|
||||
case ECORE_BUFFER_FORMAT_BGRX1010102:
|
||||
depth = 30;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_ARGB2101010:
|
||||
case ECORE_BUFFER_FORMAT_ABGR2101010:
|
||||
case ECORE_BUFFER_FORMAT_RGBA1010102:
|
||||
case ECORE_BUFFER_FORMAT_BGRA1010102:
|
||||
depth = 32;
|
||||
break;
|
||||
case ECORE_BUFFER_FORMAT_YUYV:
|
||||
case ECORE_BUFFER_FORMAT_YVYU:
|
||||
case ECORE_BUFFER_FORMAT_UYVY:
|
||||
case ECORE_BUFFER_FORMAT_VYUY:
|
||||
case ECORE_BUFFER_FORMAT_AYUV:
|
||||
case ECORE_BUFFER_FORMAT_NV12:
|
||||
case ECORE_BUFFER_FORMAT_NV21:
|
||||
case ECORE_BUFFER_FORMAT_NV16:
|
||||
case ECORE_BUFFER_FORMAT_NV61:
|
||||
case ECORE_BUFFER_FORMAT_YUV410:
|
||||
case ECORE_BUFFER_FORMAT_YVU410:
|
||||
case ECORE_BUFFER_FORMAT_YUV411:
|
||||
case ECORE_BUFFER_FORMAT_YVU411:
|
||||
case ECORE_BUFFER_FORMAT_YUV420:
|
||||
case ECORE_BUFFER_FORMAT_YVU420:
|
||||
case ECORE_BUFFER_FORMAT_YUV422:
|
||||
case ECORE_BUFFER_FORMAT_YVU422:
|
||||
case ECORE_BUFFER_FORMAT_YUV444:
|
||||
case ECORE_BUFFER_FORMAT_YVU444:
|
||||
default :
|
||||
depth = 0; //unknown in X
|
||||
break;
|
||||
}
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
static int
|
||||
_dri3_open(Ecore_X_Display *dpy, Ecore_X_Window root, unsigned provider)
|
||||
{
|
||||
xcb_connection_t *c = XGetXCBConnection(dpy);
|
||||
xcb_dri3_open_cookie_t cookie;
|
||||
xcb_dri3_open_reply_t *reply;
|
||||
|
||||
cookie = xcb_dri3_open(c, root, provider);
|
||||
reply = xcb_dri3_open_reply(c, cookie, NULL);
|
||||
if ((!reply) || (reply->nfd != 1))
|
||||
return -1;
|
||||
|
||||
return xcb_dri3_open_reply_fds(c, reply)[0];
|
||||
}
|
||||
|
||||
static Ecore_X_Pixmap
|
||||
_dri3_pixmap_from_fd(Ecore_X_Display *dpy, Ecore_X_Drawable draw, int width, int height, int depth, int fd, int bpp, int stride, int size)
|
||||
{
|
||||
xcb_connection_t *c = XGetXCBConnection(dpy);
|
||||
Ecore_X_Pixmap pixmap = xcb_generate_id(c);
|
||||
|
||||
if (!dpy)
|
||||
return 0;
|
||||
|
||||
c = XGetXCBConnection(dpy);
|
||||
if (!c)
|
||||
return 0;
|
||||
|
||||
pixmap = xcb_generate_id(c);
|
||||
if (!pixmap)
|
||||
return 0;
|
||||
|
||||
xcb_dri3_pixmap_from_buffer(c, pixmap, draw, size, width, height, stride, depth, bpp, fd);
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
static Ecore_Buffer_Module_Data
|
||||
_ecore_buffer_x11_dri3_init(const char *context EINA_UNUSED, const char *options EINA_UNUSED)
|
||||
{
|
||||
Ecore_X_Display *xdpy;
|
||||
Ecore_X_Window root;
|
||||
Ecore_Buffer_Module_X11_Dri3_Data *mdata = NULL;
|
||||
int fd = 0;
|
||||
|
||||
if (!ecore_x_init(NULL))
|
||||
return NULL;
|
||||
|
||||
xdpy = ecore_x_display_get();
|
||||
if (!xdpy)
|
||||
goto on_error;
|
||||
|
||||
root = ecore_x_window_root_first_get();
|
||||
if (!root)
|
||||
goto on_error;
|
||||
|
||||
mdata = calloc(1, sizeof(Ecore_Buffer_Module_X11_Dri3_Data));
|
||||
if (!mdata)
|
||||
goto on_error;
|
||||
|
||||
//Init DRI3 and TBM
|
||||
fd = _dri3_open(xdpy, root, 0);
|
||||
if (fd < 0)
|
||||
goto on_error;
|
||||
|
||||
mdata->tbm_mgr = tbm_bufmgr_init(fd);
|
||||
if (!mdata->tbm_mgr)
|
||||
goto on_error;
|
||||
|
||||
close(fd);
|
||||
|
||||
return mdata;
|
||||
|
||||
on_error:
|
||||
if (fd > 0) close(fd);
|
||||
if (mdata) free(mdata);
|
||||
ecore_x_shutdown();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_buffer_x11_dri3_shutdown(Ecore_Buffer_Module_Data bmdata)
|
||||
{
|
||||
Ecore_Buffer_Module_X11_Dri3_Data *bm = bmdata;
|
||||
|
||||
if (!bm)
|
||||
return;
|
||||
|
||||
if (bm->tbm_mgr)
|
||||
tbm_bufmgr_deinit(bm->tbm_mgr);
|
||||
|
||||
ecore_x_shutdown();
|
||||
}
|
||||
|
||||
static Ecore_Buffer_Data
|
||||
_ecore_buffer_x11_dri3_buffer_alloc(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, int width, int height, Ecore_Buffer_Format format, unsigned int flags)
|
||||
{
|
||||
Ecore_Buffer_X11_Dri3_Data *buf;
|
||||
|
||||
buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri3_Data));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
buf->w = width;
|
||||
buf->h = height;
|
||||
buf->format = format;
|
||||
buf->flags = flags;
|
||||
buf->is_imported = EINA_FALSE;
|
||||
buf->tbm_surface = tbm_surface_create(width,height,(tbm_format)format);
|
||||
if (!buf->tbm_surface)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static Ecore_Buffer_Data
|
||||
static void
|
||||
_ecore_buffer_x11_dri3_buffer_free(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
|
||||
{
|
||||
Ecore_Buffer_X11_Dri3_Data *buf = bdata;
|
||||
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
if (buf->pixmap)
|
||||
ecore_x_pixmap_free(buf->pixmap);
|
||||
|
||||
if (buf->tbm_surface)
|
||||
tbm_surface_destroy(buf->tbm_surface);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static Ecore_Export_Type
|
||||
_ecore_buffer_x11_dri3_buffer_export(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, int *id)
|
||||
{
|
||||
Ecore_Buffer_X11_Dri3_Data *buf = bdata;
|
||||
tbm_bo bo;
|
||||
|
||||
if (_buf_get_num_planes(buf->format) != 1)
|
||||
return EXPORT_TYPE_INVALID;
|
||||
|
||||
bo = tbm_surface_internal_get_bo(buf->tbm_surface, 0);
|
||||
if (!bo)
|
||||
return EXPORT_TYPE_INVALID;
|
||||
|
||||
if (id) *id = tbm_bo_export_fd(bo);
|
||||
|
||||
return EXPORT_TYPE_FD;
|
||||
}
|
||||
|
||||
static Ecore_Buffer_Data
|
||||
_ecore_buffer_x11_dri3_buffer_import(Ecore_Buffer_Module_Data bmdata, int w, int h, Ecore_Buffer_Format format, Ecore_Export_Type type, int export_id, unsigned int flags)
|
||||
{
|
||||
Ecore_Buffer_Module_X11_Dri3_Data *bm = bmdata;
|
||||
Ecore_Buffer_X11_Dri3_Data *buf;
|
||||
tbm_bo bo;
|
||||
tbm_surface_info_s info;
|
||||
int i, num_plane;
|
||||
|
||||
if (!bm)
|
||||
return NULL;
|
||||
|
||||
if (type != EXPORT_TYPE_FD)
|
||||
return NULL;
|
||||
|
||||
if (export_id < 1)
|
||||
return NULL;
|
||||
|
||||
buf = calloc(1, sizeof(Ecore_Buffer_X11_Dri3_Data));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
buf->w = w;
|
||||
buf->h = h;
|
||||
buf->format = format;
|
||||
buf->flags = flags;
|
||||
buf->is_imported = EINA_TRUE;
|
||||
|
||||
//Import tbm_surface
|
||||
bo = tbm_bo_import_fd(bm->tbm_mgr, export_id);
|
||||
if (!bo)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
num_plane = _buf_get_num_planes(format);
|
||||
info.width = w;
|
||||
info.height = h;
|
||||
info.format = format;
|
||||
info.bpp = _buf_get_bpp(format);
|
||||
info.size = w * h * info.bpp;
|
||||
for ( i = 0 ; i < num_plane ; i++)
|
||||
{
|
||||
info.planes[i].size = w * h * info.bpp;
|
||||
info.planes[i].stride = w * info.bpp;
|
||||
info.planes[i].offset = 0;
|
||||
}
|
||||
|
||||
buf->tbm_surface = tbm_surface_internal_create_with_bos(&info, &bo, 1);
|
||||
if (!buf->tbm_surface)
|
||||
{
|
||||
tbm_bo_unref(bo);
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tbm_bo_unref(bo);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static Ecore_Pixmap
|
||||
_ecore_buffer_x11_dri3_pixmap_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
|
||||
{
|
||||
Ecore_Buffer_X11_Dri3_Data *buf = bdata;
|
||||
Ecore_X_Display *xdpy;
|
||||
Ecore_X_Window root;
|
||||
tbm_surface_info_s info;
|
||||
tbm_bo bo;
|
||||
int ret;
|
||||
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
if (buf->pixmap)
|
||||
return buf->pixmap;
|
||||
|
||||
ret = tbm_surface_get_info(buf->tbm_surface, &info);
|
||||
if (ret != 0)
|
||||
return 0;
|
||||
|
||||
if (info.num_planes != 1)
|
||||
return 0;
|
||||
|
||||
bo = tbm_surface_internal_get_bo(buf->tbm_surface, 0);
|
||||
if (!bo)
|
||||
return 0;
|
||||
|
||||
xdpy = ecore_x_display_get();
|
||||
root = ecore_x_window_root_first_get();
|
||||
buf->pixmap = _dri3_pixmap_from_fd(xdpy, root,
|
||||
buf->w, buf->h,
|
||||
_buf_get_depth(buf->format),
|
||||
tbm_bo_export_fd(bo),
|
||||
_buf_get_bpp(buf->format),
|
||||
info.planes[0].stride,
|
||||
info.planes[0].size);
|
||||
|
||||
return buf->pixmap;
|
||||
}
|
||||
|
||||
static void *
|
||||
_ecore_buffer_x11_dri3_tbm_bo_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
|
||||
{
|
||||
Ecore_Buffer_X11_Dri3_Data *buf = bdata;
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
return buf->tbm_surface;
|
||||
}
|
||||
|
||||
static Ecore_Buffer_Backend _ecore_buffer_x11_dri3_backend = {
|
||||
"x11_dri3",
|
||||
&_ecore_buffer_x11_dri3_init,
|
||||
&_ecore_buffer_x11_dri3_shutdown,
|
||||
&_ecore_buffer_x11_dri3_buffer_alloc,
|
||||
&_ecore_buffer_x11_dri3_buffer_free,
|
||||
&_ecore_buffer_x11_dri3_buffer_export,
|
||||
&_ecore_buffer_x11_dri3_buffer_import,
|
||||
NULL,
|
||||
&_ecore_buffer_x11_dri3_pixmap_get,
|
||||
&_ecore_buffer_x11_dri3_tbm_bo_get,
|
||||
};
|
||||
|
||||
Eina_Bool x11_dri3_init(void)
|
||||
{
|
||||
return ecore_buffer_register(&_ecore_buffer_x11_dri3_backend);
|
||||
}
|
||||
|
||||
void x11_dri3_shutdown(void)
|
||||
{
|
||||
ecore_buffer_unregister(&_ecore_buffer_x11_dri3_backend);
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(x11_dri3_init);
|
||||
EINA_MODULE_SHUTDOWN(x11_dri3_shutdown);
|
Loading…
Reference in New Issue