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
acf868771c
commit
dd7ef2dbc5
|
@ -43,3 +43,6 @@
|
||||||
/ecore_thread_example
|
/ecore_thread_example
|
||||||
/ecore_time_functions_example
|
/ecore_time_functions_example
|
||||||
/ecore_timer_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/eo \
|
||||||
-I$(top_srcdir)/src/lib/evas \
|
-I$(top_srcdir)/src/lib/evas \
|
||||||
-I$(top_srcdir)/src/lib/ecore \
|
-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 \
|
||||||
-I$(top_srcdir)/src/lib/ecore_input_evas \
|
-I$(top_srcdir)/src/lib/ecore_input_evas \
|
||||||
-I$(top_srcdir)/src/lib/ecore_file \
|
-I$(top_srcdir)/src/lib/ecore_file \
|
||||||
|
@ -35,6 +36,9 @@ AM_CPPFLAGS = \
|
||||||
|
|
||||||
EXTRA_PROGRAMS = \
|
EXTRA_PROGRAMS = \
|
||||||
ecore_animator_example \
|
ecore_animator_example \
|
||||||
|
ecore_buffer_example \
|
||||||
|
ecore_buffer_consumer_example \
|
||||||
|
ecore_buffer_provider_example \
|
||||||
ecore_client_bench \
|
ecore_client_bench \
|
||||||
ecore_compose_get_example \
|
ecore_compose_get_example \
|
||||||
ecore_con_client_example \
|
ecore_con_client_example \
|
||||||
|
@ -112,6 +116,18 @@ $(ECORE_COMMON_LDADD)
|
||||||
ecore_animator_example_SOURCES = ecore_animator_example.c
|
ecore_animator_example_SOURCES = ecore_animator_example.c
|
||||||
ecore_animator_example_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
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_SOURCES = ecore_client_bench.c
|
||||||
ecore_client_bench_LDADD = $(ECORE_CON_COMMON_LDADD)
|
ecore_client_bench_LDADD = $(ECORE_CON_COMMON_LDADD)
|
||||||
|
|
||||||
|
@ -249,6 +265,9 @@ ecore_con_eet_server_example_LDADD = $(ECORE_CON_COMMON_LDADD)
|
||||||
|
|
||||||
SRCS = \
|
SRCS = \
|
||||||
ecore_animator_example.c \
|
ecore_animator_example.c \
|
||||||
|
ecore_buffer_example.c \
|
||||||
|
ecore_buffer_consumer_example.c \
|
||||||
|
ecore_buffer_provider_example.c \
|
||||||
ecore_audio_custom.c \
|
ecore_audio_custom.c \
|
||||||
ecore_audio_playback.c \
|
ecore_audio_playback.c \
|
||||||
ecore_audio_to_ogg.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;
|
||||||
|
}
|
Loading…
Reference in New Issue