forked from enlightenment/efl
Evas filters: OpenGL support part 1.
Quick and dirty solution to support the OpenGL engine: [1] Allocate CPU buffers [2] Render text and process all effects to these buffers [3] Push final image as an OpenGL texture. This patch implements [1].
This commit is contained in:
parent
4c4b44a575
commit
0135b45c12
|
@ -10,6 +10,10 @@ EAPI Eo_Op EVAS_OBJ_TEXT_BASE_ID = EO_NOOP;
|
||||||
|
|
||||||
#define MY_CLASS_NAME "Evas_Text"
|
#define MY_CLASS_NAME "Evas_Text"
|
||||||
|
|
||||||
|
#ifdef EVAS_CSERVE2
|
||||||
|
# include "evas_cs2_private.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* save typing */
|
/* save typing */
|
||||||
#define ENFN obj->layer->evas->engine.func
|
#define ENFN obj->layer->evas->engine.func
|
||||||
#define ENDT obj->layer->evas->engine.data.output
|
#define ENDT obj->layer->evas->engine.data.output
|
||||||
|
@ -2131,6 +2135,13 @@ evas_object_text_render(Evas_Object *eo_obj EINA_UNUSED,
|
||||||
void *filter_ctx;
|
void *filter_ctx;
|
||||||
Eina_Bool ok;
|
Eina_Bool ok;
|
||||||
|
|
||||||
|
/* NOTE: Font effect rendering is now done ENTIRELY on CPU.
|
||||||
|
* So we rely on cache/cache2 to allocate a real image buffer,
|
||||||
|
* that we can draw to. The OpenGL texture will be created only
|
||||||
|
* after the rendering has been done, as we simply push the output
|
||||||
|
* image to GL.
|
||||||
|
*/
|
||||||
|
|
||||||
W = obj->cur->geometry.w;
|
W = obj->cur->geometry.w;
|
||||||
H = obj->cur->geometry.h;
|
H = obj->cur->geometry.h;
|
||||||
X = obj->cur->geometry.x;
|
X = obj->cur->geometry.x;
|
||||||
|
@ -2197,16 +2208,13 @@ evas_object_text_render(Evas_Object *eo_obj EINA_UNUSED,
|
||||||
filter_ctx = ENFN->context_new(ENDT);
|
filter_ctx = ENFN->context_new(ENDT);
|
||||||
ENFN->context_color_set(ENDT, filter_ctx, 255, 255, 255, 255);
|
ENFN->context_color_set(ENDT, filter_ctx, 255, 255, 255, 255);
|
||||||
|
|
||||||
// Alloc input now
|
// Alloc input now so we can draw text asap
|
||||||
evas_filter_buffer_data_set(filter, inbuf, NULL, W, H, EINA_TRUE);
|
evas_filter_buffer_data_set(filter, inbuf, NULL, W, H, EINA_TRUE);
|
||||||
input = evas_filter_buffer_backing_get(filter, inbuf);
|
input = evas_filter_buffer_backing_get(filter, inbuf);
|
||||||
|
|
||||||
// Allocate output so we can keep it around
|
// Allocate output so we can keep it around
|
||||||
outputimg = ENFN->image_new_from_copied_data
|
evas_filter_buffer_data_set(filter, outbuf, NULL, W, H, EINA_FALSE);
|
||||||
(ENDT, W, H, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
|
outputimg = evas_filter_buffer_backing_get(filter, outbuf);
|
||||||
memset(outputimg->image.data, 0, W * H * sizeof(DATA32));
|
|
||||||
evas_filter_buffer_data_set
|
|
||||||
(filter, outbuf, outputimg->image.data, W, H, EINA_FALSE);
|
|
||||||
o->cur.filter.output = outputimg;
|
o->cur.filter.output = outputimg;
|
||||||
|
|
||||||
// Render text to input buffer
|
// Render text to input buffer
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
#include "evas_private.h"
|
#include "evas_private.h"
|
||||||
#include "evas_filter_private.h"
|
#include "evas_filter_private.h"
|
||||||
|
|
||||||
|
#ifdef EVAS_CSERVE2
|
||||||
|
# include "evas_cs2_private.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static void _buffer_free(Evas_Filter_Buffer *fb);
|
static void _buffer_free(Evas_Filter_Buffer *fb);
|
||||||
static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd);
|
static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd);
|
||||||
|
|
||||||
|
@ -43,10 +47,14 @@ evas_filter_context_new(Evas_Public_Data *evas)
|
||||||
{
|
{
|
||||||
Evas_Filter_Context *ctx;
|
Evas_Filter_Context *ctx;
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(evas, NULL);
|
||||||
|
|
||||||
ctx = calloc(1, sizeof(Evas_Filter_Context));
|
ctx = calloc(1, sizeof(Evas_Filter_Context));
|
||||||
if (!ctx) return NULL;
|
if (!ctx) return NULL;
|
||||||
|
|
||||||
ctx->evas = evas;
|
ctx->evas = evas;
|
||||||
|
ctx->gl_engine = !!strstr(evas->engine.module->definition->name, "gl");
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +80,31 @@ evas_filter_context_clear(Evas_Filter_Context *ctx)
|
||||||
// Note: don't reset post_run, as it it set by the client
|
// Note: don't reset post_run, as it it set by the client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_filter_buffer_backing_free(Evas_Filter_Buffer *fb)
|
||||||
|
{
|
||||||
|
void *backing;
|
||||||
|
if (!fb) return;
|
||||||
|
|
||||||
|
backing = fb->backing;
|
||||||
|
fb->backing = NULL;
|
||||||
|
|
||||||
|
if (!fb->allocated) return;
|
||||||
|
fb->allocated = EINA_FALSE;
|
||||||
|
|
||||||
|
if (!backing) return;
|
||||||
|
|
||||||
|
if (!fb->ctx->gl_engine)
|
||||||
|
fb->ENFN->image_free(fb->ENDT, backing);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!evas_cserve2_use_get())
|
||||||
|
evas_cache_image_drop(backing);
|
||||||
|
else
|
||||||
|
evas_cache2_image_close(backing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @hidden private bind proxy to context */
|
/** @hidden private bind proxy to context */
|
||||||
void
|
void
|
||||||
evas_filter_context_proxy_bind(Evas_Filter_Context *ctx, Evas_Object *eo_proxy,
|
evas_filter_context_proxy_bind(Evas_Filter_Context *ctx, Evas_Object *eo_proxy,
|
||||||
|
@ -209,8 +242,7 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
|
||||||
if (source->proxy->surface && !source->proxy->redraw)
|
if (source->proxy->surface && !source->proxy->redraw)
|
||||||
{
|
{
|
||||||
INF("Source already rendered");
|
INF("Source already rendered");
|
||||||
if (fb->backing && fb->allocated)
|
_filter_buffer_backing_free(fb);
|
||||||
fb->ENFN->image_free(fb->ENDT, fb->backing);
|
|
||||||
fb->backing = source->proxy->surface;
|
fb->backing = source->proxy->surface;
|
||||||
fb->w = source->cur->geometry.w;
|
fb->w = source->cur->geometry.w;
|
||||||
fb->h = source->cur->geometry.h;
|
fb->h = source->cur->geometry.h;
|
||||||
|
@ -221,8 +253,7 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
|
||||||
{
|
{
|
||||||
INF("Source needs to be rendered");
|
INF("Source needs to be rendered");
|
||||||
_proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, do_async);
|
_proxy_subrender(ctx->evas->evas, fb->source, eo_obj, obj, do_async);
|
||||||
if (fb->backing && fb->allocated)
|
_filter_buffer_backing_free(fb);
|
||||||
fb->ENFN->image_free(fb->ENDT, fb->backing);
|
|
||||||
fb->backing = source->proxy->surface;
|
fb->backing = source->proxy->surface;
|
||||||
fb->w = source->cur->geometry.w;
|
fb->w = source->cur->geometry.w;
|
||||||
fb->h = source->cur->geometry.h;
|
fb->h = source->cur->geometry.h;
|
||||||
|
@ -284,15 +315,42 @@ _rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data)
|
||||||
size_t sz;
|
size_t sz;
|
||||||
|
|
||||||
cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888;
|
cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888;
|
||||||
if (!data)
|
if (!fb->ctx->gl_engine)
|
||||||
{
|
{
|
||||||
image = fb->ENFN->image_new_from_copied_data
|
if (!data)
|
||||||
(fb->ENDT, fb->w, fb->h, NULL, EINA_TRUE, cspace);
|
{
|
||||||
|
image = fb->ENFN->image_new_from_copied_data
|
||||||
|
(fb->ENDT, fb->w, fb->h, NULL, EINA_TRUE, cspace);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
image = fb->ENFN->image_new_from_data
|
||||||
|
(fb->ENDT, fb->w, fb->h, data, EINA_TRUE, cspace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
image = fb->ENFN->image_new_from_data
|
WRN("EXPERIMENTAL OpenGL support. VERY HACKISH!");
|
||||||
(fb->ENDT, fb->w, fb->h, data, EINA_TRUE, cspace);
|
// FIXME: Directly calling the alloc functions since we want to use sw surfaces.
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
if (!evas_cserve2_use_get())
|
||||||
|
image = (RGBA_Image *) evas_cache_image_copied_data
|
||||||
|
(evas_common_image_cache_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
|
||||||
|
else
|
||||||
|
image = (RGBA_Image *) evas_cache2_image_copied_data
|
||||||
|
(evas_common_image_cache2_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!evas_cserve2_use_get())
|
||||||
|
image = (RGBA_Image *) evas_cache_image_data
|
||||||
|
(evas_common_image_cache_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
|
||||||
|
else
|
||||||
|
image = (RGBA_Image *) evas_cache2_image_data
|
||||||
|
(evas_common_image_cache2_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!image) return EINA_FALSE;
|
if (!image) return EINA_FALSE;
|
||||||
|
|
||||||
|
@ -323,9 +381,7 @@ evas_filter_buffer_alloc(Evas_Filter_Buffer *fb, int w, int h)
|
||||||
//return EINA_FALSE;
|
//return EINA_FALSE;
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
fb->ENFN->image_free(fb->ENDT, fb->backing);
|
_filter_buffer_backing_free(fb);
|
||||||
fb->backing = NULL;
|
|
||||||
fb->allocated = EINA_FALSE;
|
|
||||||
}
|
}
|
||||||
if ((fb->w && (fb->w != w)) || (fb->h && (fb->h != h)))
|
if ((fb->w && (fb->w != w)) || (fb->h && (fb->h != h)))
|
||||||
{
|
{
|
||||||
|
@ -367,10 +423,7 @@ evas_filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data,
|
||||||
fb = _filter_buffer_get(ctx, bufid);
|
fb = _filter_buffer_get(ctx, bufid);
|
||||||
if (!fb) return EINA_FALSE;
|
if (!fb) return EINA_FALSE;
|
||||||
|
|
||||||
if (fb->allocated)
|
_filter_buffer_backing_free(fb);
|
||||||
fb->ENFN->image_free(fb->ENDT, fb->backing);
|
|
||||||
fb->allocated = EINA_FALSE;
|
|
||||||
fb->backing = NULL;
|
|
||||||
if (w <= 0 || h <= 0)
|
if (w <= 0 || h <= 0)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
@ -436,9 +489,7 @@ evas_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h,
|
||||||
static void
|
static void
|
||||||
_buffer_free(Evas_Filter_Buffer *fb)
|
_buffer_free(Evas_Filter_Buffer *fb)
|
||||||
{
|
{
|
||||||
if (!fb) return;
|
_filter_buffer_backing_free(fb);
|
||||||
if (fb->allocated)
|
|
||||||
fb->ENFN->image_free(fb->ENDT, fb->backing);
|
|
||||||
free(fb);
|
free(fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,7 +1310,7 @@ _filter_command_run(Evas_Filter_Command *cmd)
|
||||||
// FIXME: Must call engine function, not CPU directly.
|
// FIXME: Must call engine function, not CPU directly.
|
||||||
|
|
||||||
if (strncmp(cmd->ctx->evas->engine.module->definition->name, "software", 8))
|
if (strncmp(cmd->ctx->evas->engine.module->definition->name, "software", 8))
|
||||||
CRI("Only the software engine is supported for now.");
|
WRN("EXPERIMENTAL OpenGL support! ALL HELL WILL BREAK LOOSE!");
|
||||||
|
|
||||||
switch (cmd->mode)
|
switch (cmd->mode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
#undef ENDT
|
#undef ENDT
|
||||||
#define ENFN cmd->ctx->evas->engine.func
|
#define ENFN cmd->ctx->evas->engine.func
|
||||||
#define ENDT cmd->ctx->evas->engine.data.output
|
#define ENDT cmd->ctx->evas->engine.data.output
|
||||||
|
|
||||||
|
#ifdef CLAMP
|
||||||
|
# undef CLAMP
|
||||||
|
#endif
|
||||||
#define CLAMP(a,b,c) MIN(MAX((b),(a)),(c))
|
#define CLAMP(a,b,c) MIN(MAX((b),(a)),(c))
|
||||||
|
|
||||||
#define DEFAULT_ZANGLE 45.f
|
#define DEFAULT_ZANGLE 45.f
|
||||||
|
|
|
@ -56,6 +56,8 @@ struct _Evas_Filter_Context
|
||||||
Evas_Filter_Cb cb;
|
Evas_Filter_Cb cb;
|
||||||
void *data;
|
void *data;
|
||||||
} post_run;
|
} post_run;
|
||||||
|
|
||||||
|
Eina_Bool gl_engine : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Evas_Filter_Command
|
struct _Evas_Filter_Command
|
||||||
|
|
|
@ -328,20 +328,21 @@ evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned i
|
||||||
switch (cspace)
|
switch (cspace)
|
||||||
{
|
{
|
||||||
case EVAS_COLORSPACE_ARGB8888:
|
case EVAS_COLORSPACE_ARGB8888:
|
||||||
break;
|
case EVAS_COLORSPACE_GRY8:
|
||||||
|
break;
|
||||||
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
||||||
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
||||||
if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
|
if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
|
||||||
im->tex = NULL;
|
im->tex = NULL;
|
||||||
im->cs.no_free = 0;
|
im->cs.no_free = 0;
|
||||||
if (im->im->cache_entry.h > 0)
|
if (im->im->cache_entry.h > 0)
|
||||||
im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
|
im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
|
||||||
if ((data) && (im->cs.data))
|
if ((data) && (im->cs.data))
|
||||||
memcpy(im->cs.data, data, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
|
memcpy(im->cs.data, data, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue