From f83220c857c4ffbd8ef5a30479b27bfbaf1e98ee Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sun, 17 Dec 2006 15:48:52 +0000 Subject: [PATCH] not complete yet - actually i need help with the fragment shader. in evas_gl_texture.c i have a frag shader, and it tries to use a set of 3 textures that act as the yuv planes, BUT the u and v textures (Utex and Vtex) are simply getting values from the Ytex - regardless of what i try. grrr. what's up with that? SVN revision: 27495 --- legacy/evas/src/lib/Evas.h | 4 +- .../evas/src/lib/canvas/evas_object_image.c | 34 +- .../src/lib/engines/common/evas_image_main.c | 39 ++ legacy/evas/src/lib/include/evas_common.h | 8 + legacy/evas/src/lib/include/evas_private.h | 4 +- .../modules/engines/cairo_x11/evas_engine.c | 8 +- .../directfb/evas_engine_dfb_image_objects.c | 4 +- .../src/modules/engines/fb/evas_fb_main.c | 9 +- .../engines/gl_common/evas_gl_common.h | 14 +- .../engines/gl_common/evas_gl_context.c | 49 ++- .../modules/engines/gl_common/evas_gl_image.c | 149 +++++-- .../engines/gl_common/evas_gl_texture.c | 153 ++++++- .../src/modules/engines/gl_x11/evas_engine.c | 347 ++++++++++------ .../engines/software_generic/evas_engine.c | 392 ++++++++++++------ .../modules/engines/xrender_x11/evas_engine.c | 10 +- .../modules/engines/xrender_x11/evas_engine.h | 4 +- .../engines/xrender_x11/evas_engine_image.c | 10 +- .../modules/engines/xrender_xcb/evas_engine.c | 4 +- 18 files changed, 903 insertions(+), 339 deletions(-) diff --git a/legacy/evas/src/lib/Evas.h b/legacy/evas/src/lib/Evas.h index 2680d72b8d..712424a4db 100644 --- a/legacy/evas/src/lib/Evas.h +++ b/legacy/evas/src/lib/Evas.h @@ -65,8 +65,8 @@ typedef enum _Evas_Colorspace { EVAS_COLORSPACE_ARGB8888, /**< ARGB 32 bits per pixel, high-byte is Alpha, accessed 1 32bit word at a time */ /* these are not currently supported - but planned for the future */ - EVAS_COLORSPACE_YCBCR422P601, /**< YCbCr 4:2:2 Planar with Planes in order Y, Cb and Cr, ITU.BT-601 specifications */ - EVAS_COLORSPACE_YCBCR422P709 /**< YCbCr 4:2:2 Planar with Planes in order Y, Cb and Cr, ITU-BT-709 specifications */ + EVAS_COLORSPACE_YCBCR422P601_PL, /**< YCbCr 4:2:2 Planar, ITU.BT-601 specifications. The data poitned to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */ + EVAS_COLORSPACE_YCBCR422P709_PL /**< YCbCr 4:2:2 Planar, ITU.BT-709 specifications. The data poitned to is just an array of row pointer, pointing to the Y rows, then the Cb, then Cr rows */ } Evas_Colorspace; /**< Colorspaces for pixel data supported by Evas */ typedef struct _Evas_List Evas_List; /**< A generic linked list node handle */ diff --git a/legacy/evas/src/lib/canvas/evas_object_image.c b/legacy/evas/src/lib/canvas/evas_object_image.c index 33ab3d9055..01ab11cd8e 100644 --- a/legacy/evas/src/lib/canvas/evas_object_image.c +++ b/legacy/evas/src/lib/canvas/evas_object_image.c @@ -25,6 +25,7 @@ struct _Evas_Object_Image const char *file; const char *key; + int cspace; char smooth_scale : 1; char has_alpha :1; @@ -174,6 +175,8 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key) o->engine_data, &w, &h); o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output, o->engine_data); + o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output, + o->engine_data); o->cur.image.w = w; o->cur.image.h = h; } @@ -181,6 +184,7 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key) { o->load_error = EVAS_LOAD_ERROR_GENERIC; o->cur.has_alpha = 1; + o->cur.cspace = EVAS_COLORSPACE_ARGB8888; o->cur.image.w = 0; o->cur.image.h = 0; } @@ -508,12 +512,15 @@ evas_object_image_size_set(Evas_Object *obj, int w, int h) o->engine_data, w, h); else - o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data(obj->layer->evas->engine.data.output, - w, h, NULL); + o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data + (obj->layer->evas->engine.data.output, w, h, NULL, o->cur.has_alpha, + o->cur.cspace); +/* FIXME - in engine call above if (o->engine_data) o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output, o->engine_data, o->cur.has_alpha); + */ EVAS_OBJECT_IMAGE_FREE_FILE_AND_KEY(o); o->changed = 1; evas_object_change(obj); @@ -602,7 +609,9 @@ evas_object_image_data_set(Evas_Object *obj, void *data) o->engine_data = obj->layer->evas->engine.func->image_new_from_data(obj->layer->evas->engine.data.output, o->cur.image.w, o->cur.image.h, - data); + data, + o->cur.has_alpha, + o->cur.cspace); } else { @@ -614,10 +623,12 @@ evas_object_image_data_set(Evas_Object *obj, void *data) o->cur.image.h = 0; o->engine_data = NULL; } +/* FIXME - in engine call above if (o->engine_data) o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output, o->engine_data, o->cur.has_alpha); + */ if (o->pixels_checked_out > 0) o->pixels_checked_out--; if (p_data != o->engine_data) { @@ -689,7 +700,9 @@ evas_object_image_data_copy_set(Evas_Object *obj, void *data) o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data(obj->layer->evas->engine.data.output, o->cur.image.w, o->cur.image.h, - data); + data, + o->cur.has_alpha, + o->cur.cspace); if (o->engine_data) o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output, o->engine_data, @@ -1241,9 +1254,11 @@ evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace) MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); return; MAGIC_CHECK_END(); - obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output, - o->engine_data, - cspace); + o->cur.cspace = cspace; + if (o->engine_data) + obj->layer->evas->engine.func->image_colorspace_set(obj->layer->evas->engine.data.output, + o->engine_data, + cspace); } /** @@ -1452,6 +1467,7 @@ evas_object_image_unload(Evas_Object *obj) o->engine_data = NULL; o->load_error = EVAS_LOAD_ERROR_NONE; o->cur.has_alpha = 1; + o->cur.cspace = EVAS_COLORSPACE_ARGB8888; o->cur.image.w = 0; o->cur.image.h = 0; } @@ -1482,6 +1498,8 @@ evas_object_image_load(Evas_Object *obj) o->engine_data, &w, &h); o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output, o->engine_data); + o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output, + o->engine_data); o->cur.image.w = w; o->cur.image.h = h; } @@ -1571,6 +1589,7 @@ evas_object_image_new(void) o->cur.fill.h = 32.0; o->cur.smooth_scale = 1; o->cur.border.fill = 1; + o->cur.cspace = EVAS_COLORSPACE_ARGB8888; o->prev = o->cur; return o; } @@ -1881,6 +1900,7 @@ evas_object_image_render_pre(Evas_Object *obj) if ((o->cur.image.w != o->prev.image.w) || (o->cur.image.h != o->prev.image.h) || (o->cur.has_alpha != o->prev.has_alpha) || + (o->cur.cspace != o->prev.cspace) || (o->cur.smooth_scale != o->prev.smooth_scale)) { updates = evas_object_render_pre_prev_cur_add(updates, obj); diff --git a/legacy/evas/src/lib/engines/common/evas_image_main.c b/legacy/evas/src/lib/engines/common/evas_image_main.c index 780cc4052d..b5d3cdc192 100644 --- a/legacy/evas/src/lib/engines/common/evas_image_main.c +++ b/legacy/evas/src/lib/engines/common/evas_image_main.c @@ -258,6 +258,7 @@ evas_common_image_new(void) if (!im) return NULL; im->flags = RGBA_IMAGE_NOTHING; im->ref = 1; + im->cs.space = EVAS_COLORSPACE_ARGB8888; return im; } @@ -266,6 +267,11 @@ evas_common_image_free(RGBA_Image *im) { im->ref--; if (im->ref > 0) return; + if (im->cs.data != im->image->data) + { + if (!im->cs.no_free) free(im->cs.data); + } + im->cs.data = NULL; evas_common_pipe_free(im); if (im->image) evas_common_image_surface_free(im->image); if (im->info.file) evas_stringshare_del(im->info.file); @@ -307,6 +313,39 @@ evas_common_image_unref(RGBA_Image *im) } } +EAPI void +evas_common_image_colorspace_normalize(RGBA_Image *im) +{ + if ((!im->cs.data) || (!im->cs.dirty)) return; + switch (im->cs.space) + { + case EVAS_COLORSPACE_ARGB8888: + if (im->image->data != im->cs.data) + { + if (!im->image->no_free) free(im->image->data); + im->image->data = im->cs.data; + im->cs.no_free = im->image->no_free; + } + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + if ((im->image->data) && (*((unsigned char **)im->cs.data))) + evas_common_convert_yuv_420p_601_rgba(im->cs.data, im->image->data, + im->image->w, im->image->h); + break; + case EVAS_COLORSPACE_YCBCR422P709_PL: + break; + default: + break; + } + im->cs.dirty = 0; +} + +EAPI void +evas_common_image_colorspace_dirty(RGBA_Image *im) +{ + im->cs.dirty = 1; +} + EAPI void evas_common_image_cache(RGBA_Image *im) { diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index 89a1627bb3..7bc77f76e2 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -353,6 +353,12 @@ struct _RGBA_Image unsigned char scale; RGBA_Pipe *pipe; int ref; + struct { + void *data; + int space; + unsigned char no_free : 1; + unsigned char dirty : 1; + } cs; }; struct _RGBA_Gradient_Color_Stop @@ -803,6 +809,8 @@ EAPI RGBA_Surface *evas_common_image_surface_new (RGBA_Image *im);/*2*/ EAPI void evas_common_image_surface_free (RGBA_Surface *is);/*2*/ EAPI void evas_common_image_surface_alloc (RGBA_Surface *is);/*2*/ EAPI void evas_common_image_surface_dealloc (RGBA_Surface *is);/*2*/ +EAPI void evas_common_image_colorspace_normalize(RGBA_Image *im); +EAPI void evas_common_image_colorspace_dirty (RGBA_Image *im); EAPI void evas_common_image_cache (RGBA_Image *im); /*2*/ EAPI void evas_common_image_uncache (RGBA_Image *im); /*2*/ EAPI void evas_common_image_store (RGBA_Image *im); /*2*/ diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index e426515c24..ebd885fcbf 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -575,8 +575,8 @@ struct _Evas_Func void (*gradient_draw) (void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h); void *(*image_load) (void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo); - void *(*image_new_from_data) (void *data, int w, int h, DATA32 *image_data); - void *(*image_new_from_copied_data) (void *data, int w, int h, DATA32 *image_data); + void *(*image_new_from_data) (void *data, int w, int h, DATA32 *image_data, int alpha, int cspace); + void *(*image_new_from_copied_data) (void *data, int w, int h, DATA32 *image_data, int alpha, int cspace); void (*image_free) (void *data, void *image); void (*image_size_get) (void *data, void *image, int *w, int *h); void *(*image_size_set) (void *data, void *image, int w, int h); diff --git a/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c b/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c index 30bf8d20a1..91bc43b62e 100644 --- a/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c @@ -71,8 +71,8 @@ static void eng_gradient_render_post(void *data, void *gradient); static void eng_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h); static void *eng_image_load(void *data, char *file, char *key, int *error, Evas_Image_Load_Opts *lo); -static void *eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data); -static void *eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); +static void *eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace); +static void *eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace); static void eng_image_free(void *data, void *image); static void eng_image_size_get(void *data, void *image, int *w, int *h); static void *eng_image_size_set(void *data, void *image, int w, int h); @@ -912,7 +912,7 @@ eng_image_load(void *data, char *file, char *key, int *error, Evas_Image_Load_Op } static void * -eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data) +eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re; Evas_Cairo_Image *im; @@ -946,7 +946,7 @@ eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data) } static void * -eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data) +eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re; Evas_Cairo_Image *im; diff --git a/legacy/evas/src/modules/engines/directfb/evas_engine_dfb_image_objects.c b/legacy/evas/src/modules/engines/directfb/evas_engine_dfb_image_objects.c index ce0bd9d3a9..9af384d154 100644 --- a/legacy/evas/src/modules/engines/directfb/evas_engine_dfb_image_objects.c +++ b/legacy/evas/src/modules/engines/directfb/evas_engine_dfb_image_objects.c @@ -96,7 +96,7 @@ evas_engine_directfb_image_load(void *data, char *file, char *key, int *error, E void * evas_engine_directfb_image_new_from_data(void *data, int w, int h, - DATA32 * image_data) + DATA32 * image_data, int alpha, int cspace) { /* FIXME document this peculiarity */ return evas_engine_directfb_image_new_from_copied_data(data, w, h, image_data); @@ -104,7 +104,7 @@ evas_engine_directfb_image_new_from_data(void *data, int w, int h, void * evas_engine_directfb_image_new_from_copied_data(void *data, int w, int h, - DATA32 * image_data) + DATA32 * image_data, int alpha, int cspace) { Render_Engine *re; diff --git a/legacy/evas/src/modules/engines/fb/evas_fb_main.c b/legacy/evas/src/modules/engines/fb/evas_fb_main.c index 75e0743404..9fef6d083d 100644 --- a/legacy/evas/src/modules/engines/fb/evas_fb_main.c +++ b/legacy/evas/src/modules/engines/fb/evas_fb_main.c @@ -342,9 +342,12 @@ fb_getmode(void) mode->fb_var.yres + mode->fb_var.lower_margin + mode->fb_var.vsync_len; - clockrate = - 1000000 / mode->fb_var.pixclock; - mode->refresh = clockrate * 1000000 / (lines * hpix); + if (mode->fb_var.pixclock > 0) + clockrate = 1000000 / mode->fb_var.pixclock; + else + clockrate = 0; + if ((lines > 0) && (hpix > 0)) + mode->refresh = clockrate * 1000000 / (lines * hpix); switch (mode->fb_var.bits_per_pixel) { case 1: diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h b/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h index 9d01857fe3..3a98e941fa 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h @@ -95,7 +95,8 @@ struct _Evas_GL_Texture int tw, th; int uw, uh; - GLuint texture; + GLuint texture, texture2, texture3; + GLhandleARB prog; unsigned char smooth : 1; unsigned char changed : 1; @@ -115,6 +116,11 @@ struct _Evas_GL_Image RGBA_Image_Loadopts load_opts; int putcount; int references; + struct { + int space; + void *data; + unsigned char no_free : 1; + } cs; unsigned char dirty : 1; unsigned char cached : 1; }; @@ -183,9 +189,9 @@ void evas_gl_common_texture_free(Evas_GL_Texture *tex); void evas_gl_common_texture_mipmaps_build(Evas_GL_Texture *tex, RGBA_Image *im, int smooth); Evas_GL_Image *evas_gl_common_image_load(Evas_GL_Context *gc, char *file, char *key, Evas_Image_Load_Opts *lo); -Evas_GL_Image *evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, int *data); -Evas_GL_Image *evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, int *data); -Evas_GL_Image *evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h); +Evas_GL_Image *evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, int *data, int alpha, int cspace); +Evas_GL_Image *evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, int *data, int alpha, int cspace); +Evas_GL_Image *evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h, int alpha, int cspace); void evas_gl_common_image_free(Evas_GL_Image *im); void evas_gl_common_image_dirty(Evas_GL_Image *im); diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c index 5046ab2b4c..7d38fa4d88 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c @@ -63,9 +63,9 @@ evas_gl_common_context_use(Evas_GL_Context *gc) ext = glGetString(GL_EXTENSIONS); if (ext) { - if (strstr(ext, "GL_SGIS_generate_mipmap")) gc->ext.sgis_generate_mipmap = 1; - if (strstr(ext, "GL_NV_texture_rectangle")) gc->ext.nv_texture_rectangle = 1; - if (strstr(ext, "GL_EXT_texture_rectangle")) gc->ext.nv_texture_rectangle = 1; +// if (strstr(ext, "GL_SGIS_generate_mipmap")) gc->ext.sgis_generate_mipmap = 1; +// if (strstr(ext, "GL_NV_texture_rectangle")) gc->ext.nv_texture_rectangle = 1; +// if (strstr(ext, "GL_EXT_texture_rectangle")) gc->ext.nv_texture_rectangle = 1; if (strstr(ext, "GL_ARB_texture_non_power_of_two")) gc->ext.arb_texture_non_power_of_two = 1; printf("GL EXT supported: GL_SGIS_generate_mipmap = %x\n", gc->ext.sgis_generate_mipmap); printf("GL EXT supported: GL_NV_texture_rectangle = %x\n", gc->ext.nv_texture_rectangle); @@ -74,7 +74,7 @@ evas_gl_common_context_use(Evas_GL_Context *gc) // changing textures a lot (doing video). so we wont do anything with this // for now, but it does work. // gc->ext.arb_texture_non_power_of_two = 0; printf("DISABLE GL_ARB_texture_non_power_of_two\n"); - gc->ext.nv_texture_rectangle = 0; printf("DISABLE GL_NV_texture_rectangle\n"); +// gc->ext.nv_texture_rectangle = 0; printf("DISABLE GL_NV_texture_rectangle\n"); } else { @@ -317,6 +317,7 @@ _evas_gl_common_texture_set(Evas_GL_Context *gc) if (!gc->change.texture) return; if (gc->font_texture > 0) { + glUseProgramObjectARB(0); if (gc->font_texture_rectangle) { glEnable(GL_TEXTURE_2D); @@ -342,8 +343,38 @@ _evas_gl_common_texture_set(Evas_GL_Context *gc) else { if (gc->ext.nv_texture_rectangle) glDisable(GL_TEXTURE_RECTANGLE_NV); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, gc->texture->texture); + if ((gc->texture->prog) && + (gc->texture->texture2) && (gc->texture->texture3)) + { + int i; + + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, gc->texture->texture2); + + glActiveTexture(GL_TEXTURE2); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, gc->texture->texture3); + + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, gc->texture->texture); + + glUseProgramObjectARB(gc->texture->prog); + } + else + { + glUseProgramObjectARB(0); + + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE2); + glDisable(GL_TEXTURE_2D); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gc->texture->texture); + glEnable(GL_TEXTURE_2D); + } } if (gc->texture->rectangle) { @@ -375,9 +406,9 @@ _evas_gl_common_texture_set(Evas_GL_Context *gc) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - if (gc->texture->have_mipmaps) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - else +// if (gc->texture->have_mipmaps) +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); +// else glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c index 01643b5eaa..f9a48c4f09 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c @@ -35,13 +35,14 @@ evas_gl_common_image_load(Evas_GL_Context *gc, char *file, char *key, Evas_Image im->gc = gc; im->references = 1; im->cached = 1; + im->cs.space = EVAS_COLORSPACE_ARGB8888; if (lo) im->load_opts = *lo; gc->images = evas_list_prepend(gc->images, im); return im; } Evas_GL_Image * -evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, int *data) +evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, int *data, int alpha, int cspace) { Evas_GL_Image *im; Evas_List *l; @@ -75,20 +76,40 @@ evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, int *data) free(im); return NULL; } + im->gc = gc; im->im->image->w = w; im->im->image->h = h; - im->im->image->data = data; - im->im->image->no_free = 1; - im->gc = gc; -/* - im->cached = 1; - gc->images = evas_list_prepend(gc->images, im); - */ + im->cs.space = cspace; + if (alpha) + im->im->flags |= RGBA_IMAGE_HAS_ALPHA; + else + im->im->flags &= ~RGBA_IMAGE_HAS_ALPHA; + switch (cspace) + { + case EVAS_COLORSPACE_ARGB8888: + im->im->image->data = data; + im->im->image->no_free = 1; + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + if (im->tex) evas_gl_common_texture_free(im->tex); + im->tex = NULL; + im->cs.data = data; + im->cs.no_free = 1; + break; + default: + abort(); + break; + } + /* + im->cached = 1; + gc->images = evas_list_prepend(gc->images, im); + */ return im; } Evas_GL_Image * -evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, int *data) +evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, int *data, int alpha, int cspace) { Evas_GL_Image *im; @@ -101,14 +122,37 @@ evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, int free(im); return NULL; } - if (data) - memcpy(im->im->image->data, data, w * h * sizeof(DATA32)); im->gc = gc; + im->cs.space = cspace; + if (alpha) + im->im->flags |= RGBA_IMAGE_HAS_ALPHA; + else + im->im->flags &= ~RGBA_IMAGE_HAS_ALPHA; + switch (cspace) + { + case EVAS_COLORSPACE_ARGB8888: + if (data) + memcpy(im->im->image->data, data, w * h * sizeof(DATA32)); + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + evas_common_image_surface_dealloc(im->im->image); + im->im->image->data = NULL; + if (im->tex) evas_gl_common_texture_free(im->tex); + im->tex = NULL; + im->cs.data = calloc(1, im->im->image->h * sizeof(unsigned char *) * 2); + if ((data) && (im->cs.data)) + memcpy(im->cs.data, data, im->im->image->h * sizeof(unsigned char *) * 2); + break; + default: + abort(); + break; + } return im; } Evas_GL_Image * -evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h) +evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h, int alpha, int cspace) { Evas_GL_Image *im; @@ -130,8 +174,11 @@ evas_gl_common_image_free(Evas_GL_Image *im) im->references--; if (im->references > 0) return; - if (im->cached) - im->gc->images = evas_list_remove(im->gc->images, im); + if (im->cs.data) + { + if (!im->cs.no_free) free(im->cs.data); + } + if (im->cached) im->gc->images = evas_list_remove(im->gc->images, im); if (im->im) evas_common_image_unref(im->im); if (im->tex) evas_gl_common_texture_free(im->tex); free(im); @@ -167,35 +214,61 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy r = g = b = a = 255; } evas_common_load_image_data_from_file(im->im); - if ((im->tex) && (im->dirty)) - { - evas_gl_common_texture_update(im->tex, im->im, im->tex->smooth); - im->dirty = 0; - } - if (!im->tex) - im->tex = evas_gl_common_texture_new(gc, im->im, smooth); - ow = (dw * im->tex->tw) / sw; - oh = (dh * im->tex->th) / sh; - evas_gl_common_context_texture_set(gc, im->tex, smooth, ow, oh); - if ((!im->tex->have_mipmaps) && (smooth) && - ((im->tex->uw < im->tex->tw) || (im->tex->uh < im->tex->th)) && - (!gc->ext.sgis_generate_mipmap)) - evas_gl_common_texture_mipmaps_build(im->tex, im->im, smooth); - - if (im->tex->rectangle) - { - tx1 = sx; - ty1 = sy; - tx2 = sx + sw; - ty2 = sy + sh; - } - else + switch (im->cs.space) { + case EVAS_COLORSPACE_ARGB8888: + if ((im->tex) && (im->dirty)) + { + evas_gl_common_texture_update(im->tex, im->im, im->tex->smooth); + im->dirty = 0; + } + if (!im->tex) + im->tex = evas_gl_common_texture_new(gc, im->im, smooth); + ow = (dw * im->tex->tw) / sw; + oh = (dh * im->tex->th) / sh; + if (im->tex->rectangle) + { + tx1 = sx; + ty1 = sy; + tx2 = sx + sw; + ty2 = sy + sh; + } + else + { + tx1 = (double)(sx ) / (double)(im->tex->w); + ty1 = (double)(sy ) / (double)(im->tex->h); + tx2 = (double)(sx + sw) / (double)(im->tex->w); + ty2 = (double)(sy + sh) / (double)(im->tex->h); + } + evas_gl_common_context_texture_set(gc, im->tex, smooth, ow, oh); + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + if ((im->tex) && (im->dirty)) + { + evas_gl_common_ycbcr601pl_texture_update(im->tex, im->cs.data, im->im->image->w, im->im->image->h); + im->dirty = 0; + } + if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data))) + im->tex = evas_gl_common_ycbcr601pl_texture_new(gc, im->cs.data, im->im->image->w, im->im->image->h); + if (!im->tex) return; + ow = (dw * im->tex->tw) / sw; + oh = (dh * im->tex->th) / sh; tx1 = (double)(sx ) / (double)(im->tex->w); ty1 = (double)(sy ) / (double)(im->tex->h); tx2 = (double)(sx + sw) / (double)(im->tex->w); ty2 = (double)(sy + sh) / (double)(im->tex->h); - } + evas_gl_common_context_texture_set(gc, im->tex, smooth, ow, oh); + break; + default: + abort(); + break; + } +// if ((!im->tex->have_mipmaps) && (smooth) && +// ((im->tex->uw < im->tex->tw) || (im->tex->uh < im->tex->th)) && +// (!gc->ext.sgis_generate_mipmap)) +// evas_gl_common_texture_mipmaps_build(im->tex, im->im, smooth); + evas_gl_common_context_color_set(gc, r, g, b, a); if ((a < 255) || (im->im->flags & RGBA_IMAGE_HAS_ALPHA)) evas_gl_common_context_blend_set(gc, 1); diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_texture.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_texture.c index f4ce8b9b3b..a5948a281b 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_texture.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_texture.c @@ -83,7 +83,7 @@ evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im, int smooth) gc->change.texture = 1; tex->references++; -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -101,6 +101,7 @@ evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im, int smooth) glTexImage2D(GL_TEXTURE_2D, 0, texfmt, tw, th, 0, pixfmt, NATIVE_PIX_UNIT, NULL); +/* { int ttw, tth; int l; @@ -120,6 +121,7 @@ evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im, int smooth) pixfmt, NATIVE_PIX_UNIT, NULL); } } + */ if (gc->ext.sgis_generate_mipmap) { glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); @@ -292,6 +294,10 @@ evas_gl_common_texture_free(Evas_GL_Texture *tex) tex->gc->change.texture = 1; } glDeleteTextures(1, &tex->texture); + if (tex->texture2) glDeleteTextures(1, &tex->texture2); + if (tex->texture3) glDeleteTextures(1, &tex->texture3); + if (tex->prog) + glDeleteObjectARB(tex->prog); free(tex); } @@ -405,3 +411,148 @@ evas_gl_common_texture_mipmaps_build(Evas_GL_Texture *tex, RGBA_Image *im, int s if (mmx) evas_common_cpu_end_opt(); #endif } + +Evas_GL_Texture * +evas_gl_common_ycbcr601pl_texture_new(Evas_GL_Context *gc, unsigned char **rows, int w, int h) +{ + Evas_GL_Texture *tex; + int im_w, im_h; + int tw, th; + GLenum pixfmt, texfmt; + GLhandleARB fshad; + + if (!gc->ext.arb_texture_non_power_of_two) return NULL; + + tex = calloc(1, sizeof(Evas_GL_Texture)); + if (!tex) return NULL; + + tw = w; + th = h; + tex->gc = gc; + tex->w = tw; + tex->h = th; + tex->tw = w; + tex->th = h; + tex->references = 0; + tex->smooth = 0; + tex->changed = 1; + + tex->prog = glCreateProgramObjectARB(); + fshad = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); + + { + const char *code = + "uniform sampler2D Ytex, Utex, Vtex;\n" + "void main(void) {\n" + + " float r, g, b, y, u, v;\n" + + " y = texture2D(Ytex, gl_TexCoord[0].st).r;\n" + " u = texture2D(Utex, gl_TexCoord[0].st).r;\n" + " v = texture2D(Vtex, gl_TexCoord[0].st).r;\n" + +#if 0 // enable this to direct-test y u and v values + " gl_FragColor = vec4(y, u, v, 1.0);\n" +#else + " y = (y - 0.0625) * 1.164;\n" + " u = u - 0.5;\n" + " v = v - 0.5;\n" + + " r = y + (1.402 * v);\n" + " g = y - (0.34414 * u) - (0.71414 * v);\n" + " b = y + (1.772 * u);\n" + + " gl_FragColor = vec4(r, g, b, 1.0);\n" +#endif + "}\n"; + glShaderSourceARB(fshad, 1, &code, NULL); + } + + glCompileShaderARB(fshad); + glAttachObjectARB(tex->prog, fshad); + glLinkProgramARB(tex->prog); + + glEnable(GL_TEXTURE_2D); + texfmt = GL_LUMINANCE; + + glGenTextures(1, &(tex->texture)); + glUniform1iARB(glGetUniformLocationARB(tex->prog, "Ytex", tex->texture)); + glBindTexture(GL_TEXTURE_2D, tex->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, + texfmt, tw, th, 0, + texfmt, GL_UNSIGNED_BYTE, rows[0]); + + glGenTextures(1, &(tex->texture2)); + glUniform1iARB(glGetUniformLocationARB(tex->prog, "Utex", tex->texture2)); + glBindTexture(GL_TEXTURE_2D, tex->texture2); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, + texfmt, tw / 2, th / 2, 0, + texfmt, GL_UNSIGNED_BYTE, rows[th]); + + glGenTextures(1, &(tex->texture3)); + glUniform1iARB(glGetUniformLocationARB(tex->prog, "Vtex", 2)); + glBindTexture(GL_TEXTURE_2D, tex->texture3); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, + texfmt, tw / 2, th / 2, 0, + texfmt, GL_UNSIGNED_BYTE, rows[th + (th / 2)]); + + if (gc->texture) gc->texture->references--; + gc->texture = tex; + gc->change.texture = 1; + tex->references++; + + /* FIXME: should use subimage */ +/* + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, 0, im_w, im_h, + pixfmt, NATIVE_PIX_UNIT, + im_data); + */ + return tex; +} + +void +evas_gl_common_ycbcr601pl_texture_update(Evas_GL_Texture *tex, unsigned char **rows, int w, int h) +{ + int texfmt; + + return; + /* FIXME: should use subimage */ + glEnable(GL_TEXTURE_2D); + texfmt = GL_LUMINANCE; + + glBindTexture(GL_TEXTURE_2D, tex->texture); + glTexImage2D(GL_TEXTURE_2D, 0, + texfmt, tex->w, tex->h, 0, + texfmt, GL_UNSIGNED_BYTE, rows[0]); + + glBindTexture(GL_TEXTURE_2D, tex->texture2); + glTexImage2D(GL_TEXTURE_2D, 0, + texfmt, tex->w / 2, tex->h / 2, 0, + texfmt, GL_UNSIGNED_BYTE, rows[tex->h]); + + glBindTexture(GL_TEXTURE_2D, tex->texture3); + glTexImage2D(GL_TEXTURE_2D, 0, + texfmt, tex->w / 2, tex->h / 2, 0, + texfmt, GL_UNSIGNED_BYTE, rows[tex->h + (tex->h / 2)]); + + if (tex->gc->texture) tex->gc->texture->references--; + tex->gc->texture = tex; + tex->gc->change.texture = 1; + tex->references++; +} diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c index c72a2695a8..0a118695d8 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c @@ -457,6 +457,161 @@ eng_gradient_draw(void *data, void *context, void *surface, void *gradient, int evas_gl_common_gradient_draw(re->win->gl_context, gradient, x, y, w, h); } +static int +eng_image_alpha_get(void *data, void *image) +{ + Render_Engine *re; + Evas_GL_Image *im; + + re = (Render_Engine *)data; + im = image; + /* FIXME: can move to gl_common */ + switch (im->cs.space) + { + case EVAS_COLORSPACE_ARGB8888: + if (im->im->flags & RGBA_IMAGE_HAS_ALPHA) return 1; + default: + break; + } + return 0; +} + +static int +eng_image_colorspace_get(void *data, void *image) +{ + Render_Engine *re; + Evas_GL_Image *im; + + re = (Render_Engine *)data; + im = image; + return im->cs.space; +} + +static void * +eng_image_alpha_set(void *data, void *image, int has_alpha) +{ + Render_Engine *re; + Evas_GL_Image *im; + + re = (Render_Engine *)data; + eng_window_use(re->win); + im = image; + /* FIXME: can move to gl_common */ + if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return im; + if ((has_alpha) && (im->im->flags & RGBA_IMAGE_HAS_ALPHA)) return image; + else if ((!has_alpha) && (!(im->im->flags & RGBA_IMAGE_HAS_ALPHA))) return image; + if (im->references > 1) + { + Evas_GL_Image *im_new; + + im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->image->w, im->im->image->h, im->im->image->data, + eng_image_alpha_get(data, image), + eng_image_colorspace_get(data, image)); + if (!im_new) return im; + evas_gl_common_image_free(im); + im = im_new; + } + else + evas_gl_common_image_dirty(im); + if (has_alpha) + im->im->flags |= RGBA_IMAGE_HAS_ALPHA; + else + im->im->flags &= ~RGBA_IMAGE_HAS_ALPHA; + return image; +} + +static void * +eng_image_border_set(void *data, void *image, int l, int r, int t, int b) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return image; +} + +static void +eng_image_border_get(void *data, void *image, int *l, int *r, int *t, int *b) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + +static char * +eng_image_comment_get(void *data, void *image, char *key) +{ + Render_Engine *re; + Evas_GL_Image *im; + + re = (Render_Engine *)data; + im = image; + return im->im->info.comment; +} + +static char * +eng_image_format_get(void *data, void *image) +{ + Render_Engine *re; + Evas_GL_Image *im; + + re = (Render_Engine *)data; + im = image; + return NULL; +} + +static void +eng_image_colorspace_set(void *data, void *image, int cspace) +{ + Render_Engine *re; + Evas_GL_Image *im; + + re = (Render_Engine *)data; + im = image; + /* FIXME: can move to gl_common */ + if (im->cs.space == cspace) return; + switch (cspace) + { + case EVAS_COLORSPACE_ARGB8888: + if (im->cs.data) + { + if (!im->cs.no_free) free(im->cs.data); + im->cs.data = NULL; + im->cs.no_free = 0; + } + if (!im->im->image->no_free) + evas_common_image_surface_alloc(im->im->image); + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + evas_common_image_surface_dealloc(im->im->image); + im->im->image->data = NULL; + if (im->tex) evas_gl_common_texture_free(im->tex); + im->tex = NULL; + if (im->cs.data) + { + if (!im->cs.no_free) free(im->cs.data); + } + im->cs.data = calloc(1, im->im->image->h * sizeof(unsigned char *) * 2); + im->cs.no_free = 0; + break; + default: + abort(); + break; + } + im->cs.space = cspace; +} + +static void +eng_image_native_set(void *data, void *image, void *native) +{ +} + +static void * +eng_image_native_get(void *data, void *image) +{ + return NULL; +} + static void * eng_image_load(void *data, char *file, char *key, int *error, Evas_Image_Load_Opts *lo) { @@ -469,23 +624,23 @@ eng_image_load(void *data, char *file, char *key, int *error, Evas_Image_Load_Op } static void * -eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data) +eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re; re = (Render_Engine *)data; eng_window_use(re->win); - return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data); + return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace); } static void * -eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data) +eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re; re = (Render_Engine *)data; eng_window_use(re->win); - return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data); + return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace); } static void @@ -520,17 +675,23 @@ eng_image_size_set(void *data, void *image, int w, int h) im_old = image; if ((im_old) && (im_old->im->image->w == w) && (im_old->im->image->h == h)) return image; - im = evas_gl_common_image_new(re->win->gl_context, w, h); if (im_old) { + im = evas_gl_common_image_new(re->win->gl_context, w, h, + eng_image_alpha_get(data, image), + eng_image_colorspace_get(data, image)); +/* evas_common_load_image_data_from_file(im_old->im); if (im_old->im->image->data) { evas_common_blit_rectangle(im_old->im, im->im, 0, 0, w, h, 0, 0); evas_common_cpu_end_opt(); } + */ evas_gl_common_image_free(im_old); } + else + im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888); return im; } @@ -554,24 +715,38 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data) im = image; eng_window_use(re->win); evas_common_load_image_data_from_file(im->im); - if (to_write) + switch (im->cs.space) { - if (im->references > 1) + case EVAS_COLORSPACE_ARGB8888: + if (to_write) { - Evas_GL_Image *im_new; - - im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->image->w, im->im->image->h, im->im->image->data); - if (!im_new) + if (im->references > 1) { - return im; - *image_data = NULL; + Evas_GL_Image *im_new; + + im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->image->w, im->im->image->h, im->im->image->data, + eng_image_alpha_get(data, image), + eng_image_colorspace_get(data, image)); + if (!im_new) + { + return im; + *image_data = NULL; + } + im = im_new; } - im = im_new; + else + evas_gl_common_image_dirty(im); } - else - evas_gl_common_image_dirty(im); + *image_data = im->im->image->data; + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + *image_data = im->cs.data; + break; + default: + abort(); + break; } - *image_data = im->im->image->data; return im; } @@ -584,79 +759,41 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) re = (Render_Engine *)data; im = image; eng_window_use(re->win); - if (image_data != im->im->image->data) + switch (im->cs.space) { - int w, h; - - w = im->im->image->w; - h = im->im->image->h; - evas_gl_common_image_free(im); - return eng_image_new_from_data(data, w, h, image_data); + case EVAS_COLORSPACE_ARGB8888: + if (image_data != im->im->image->data) + { + int w, h; + + w = im->im->image->w; + h = im->im->image->h; + evas_gl_common_image_free(im); + return eng_image_new_from_data(data, w, h, image_data, + eng_image_alpha_get(data, image), + eng_image_colorspace_get(data, image)); + } + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + if (image_data != im->cs.data) + { + if (im->cs.data) + { + if (!im->cs.no_free) free(im->cs.data); + } + im->cs.data = image_data; + } + break; + default: + abort(); + break; } /* hmmm - but if we wrote... why bother? */ evas_gl_common_image_dirty(im); return im; } -static void * -eng_image_alpha_set(void *data, void *image, int has_alpha) -{ - Render_Engine *re; - Evas_GL_Image *im; - - re = (Render_Engine *)data; - eng_window_use(re->win); - im = image; - if ((has_alpha) && (im->im->flags & RGBA_IMAGE_HAS_ALPHA)) return image; - else if ((!has_alpha) && (!(im->im->flags & RGBA_IMAGE_HAS_ALPHA))) return image; - if (im->references > 1) - { - Evas_GL_Image *im_new; - - im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->image->w, im->im->image->h, im->im->image->data); - if (!im_new) return im; - evas_gl_common_image_free(im); - im = im_new; - } - else - evas_gl_common_image_dirty(im); - if (has_alpha) - im->im->flags |= RGBA_IMAGE_HAS_ALPHA; - else - im->im->flags &= ~RGBA_IMAGE_HAS_ALPHA; - return image; -} - -static int -eng_image_alpha_get(void *data, void *image) -{ - Render_Engine *re; - Evas_GL_Image *im; - - re = (Render_Engine *)data; - im = image; - eng_window_use(re->win); - if (im->im->flags & RGBA_IMAGE_HAS_ALPHA) return 1; - return 0; -} - -static void * -eng_image_border_set(void *data, void *image, int l, int r, int t, int b) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - return image; -} - -static void -eng_image_border_get(void *data, void *image, int *l, int *r, int *t, int *b) -{ - Render_Engine *re; - - re = (Render_Engine *)data; -} - static void eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) { @@ -671,50 +808,6 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, smooth); } -static char * -eng_image_comment_get(void *data, void *image, char *key) -{ - Render_Engine *re; - Evas_GL_Image *im; - - re = (Render_Engine *)data; - im = image; - return im->im->info.comment; -} - -static char * -eng_image_format_get(void *data, void *image) -{ - Render_Engine *re; - Evas_GL_Image *im; - - re = (Render_Engine *)data; - im = image; - return NULL; -} - -static void -eng_image_colorspace_set(void *data, void *image, int cspace) -{ -} - -static int -eng_image_colorspace_get(void *data, void *image) -{ - return EVAS_COLORSPACE_ARGB8888; -} - -static void -eng_image_native_set(void *data, void *image, void *native) -{ -} - -static void * -eng_image_native_get(void *data, void *image) -{ - return NULL; -} - static void eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, char *text) { diff --git a/legacy/evas/src/modules/engines/software_generic/evas_engine.c b/legacy/evas/src/modules/engines/software_generic/evas_engine.c index 041bd711d3..d5e7a3f922 100644 --- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c @@ -329,6 +329,150 @@ eng_gradient_draw(void *data, void *context, void *surface, void *gradient, int } } +static int +eng_image_alpha_get(void *data, void *image) +{ + RGBA_Image *im; + + im = image; + switch (im->cs.space) + { + case EVAS_COLORSPACE_ARGB8888: + if (im->flags & RGBA_IMAGE_HAS_ALPHA) return 1; + default: + break; + } + return 0; +} + +static int +eng_image_colorspace_get(void *data, void *image) +{ + RGBA_Image *im; + + im = image; + return im->cs.space; +} + +static void * +eng_image_alpha_set(void *data, void *image, int has_alpha) +{ + RGBA_Image *im; + + im = image; + if (im->cs.space != EVAS_COLORSPACE_ARGB8888) + { + im->flags &= ~RGBA_IMAGE_HAS_ALPHA; + return im; + } + if (im->references > 1) + { + RGBA_Image *im_new; + + im_new = evas_common_image_create(im->image->w, im->image->h); + if (!im_new) return im; + evas_common_load_image_data_from_file(im); + evas_common_image_colorspace_normalize(im); + evas_common_blit_rectangle(im, im_new, 0, 0, im->image->w, im->image->h, 0, 0); + evas_common_cpu_end_opt(); + evas_common_image_unref(im); + im = im_new; + } + else + { + evas_common_image_dirty(im); + evas_common_image_colorspace_dirty(im); + } + if (has_alpha) + im->flags |= RGBA_IMAGE_HAS_ALPHA; + else + im->flags &= ~RGBA_IMAGE_HAS_ALPHA; + return im; +} + +static void * +eng_image_border_set(void *data, void *image, int l, int r, int t, int b) +{ + RGBA_Image *im; + + im = image; + return im; +} + +static void +eng_image_border_get(void *data, void *image, int *l, int *r, int *t, int *b) +{ + RGBA_Image *im; + + im = image; +} + +static char * +eng_image_comment_get(void *data, void *image, char *key) +{ + RGBA_Image *im; + + im = image; + return im->info.comment; +} + +static char * +eng_image_format_get(void *data, void *image) +{ + return NULL; +} + +static void +eng_image_colorspace_set(void *data, void *image, int cspace) +{ + RGBA_Image *im; + + im = image; + if (im->cs.space == cspace) return; + switch (cspace) + { + case EVAS_COLORSPACE_ARGB8888: + if (im->cs.data) + { + if (!im->cs.no_free) free(im->cs.data); + im->cs.data = NULL; + im->cs.no_free = 0; + } + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + if (im->image->no_free) + { + im->image->data = NULL; + im->image->no_free = 0; + evas_common_image_surface_alloc(im->image); + } + if (im->cs.data) + { + if (!im->cs.no_free) free(im->cs.data); + } + im->cs.data = calloc(1, im->image->h * sizeof(unsigned char *) * 2); + im->cs.no_free = 0; + break; + default: + abort(); + break; + } + im->cs.space = cspace; + evas_common_image_colorspace_dirty(im); +} + +static void +eng_image_native_set(void *data, void *image, void *native) +{ +} + +static void * +eng_image_native_get(void *data, void *image) +{ + return NULL; +} + static void * eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo) { @@ -337,7 +481,7 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I } static void * -eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data) +eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { RGBA_Image *im; @@ -348,22 +492,65 @@ eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data) evas_common_image_free(im); return NULL; } - im->image->w = w; - im->image->h = h; - im->image->data = image_data; - im->image->no_free = 1; + switch (cspace) + { + case EVAS_COLORSPACE_ARGB8888: + im->image->w = w; + im->image->h = h; + im->image->data = image_data; + im->image->no_free = 1; + if (alpha) + im->flags |= RGBA_IMAGE_HAS_ALPHA; + else + im->flags &= ~RGBA_IMAGE_HAS_ALPHA; + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + im->image->w = w; + im->image->h = h; + evas_common_image_surface_alloc(im->image); + im->cs.data = image_data; + im->cs.no_free = 1; + break; + default: + abort(); + break; + } + im->cs.space = cspace; + evas_common_image_colorspace_dirty(im); return im; } static void * -eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data) +eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { RGBA_Image *im; - im = evas_common_image_create(w, h); - if (!im) return NULL; - if (image_data) - memcpy(im->image->data, image_data, w * h * sizeof(DATA32)); + switch (cspace) + { + case EVAS_COLORSPACE_ARGB8888: + im = evas_common_image_create(w, h); + if (!im) return NULL; + if (alpha) + im->flags |= RGBA_IMAGE_HAS_ALPHA; + else + im->flags &= ~RGBA_IMAGE_HAS_ALPHA; + if (image_data) + memcpy(im->image->data, image_data, w * h * sizeof(DATA32)); + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + im = evas_common_image_create(w, h); + im->cs.data = calloc(1, im->image->h * sizeof(unsigned char *) * 2); + if ((image_data) && (im->cs.data)) + memcpy(im->cs.data, image_data, im->image->h * sizeof(unsigned char *) * 2); + break; + default: + abort(); + break; + } + im->cs.space = cspace; + evas_common_image_colorspace_dirty(im); return im; } @@ -393,12 +580,16 @@ eng_image_size_set(void *data, void *image, int w, int h) if (!im) return im_old; if (im_old) { + im->cs.space = im_old->cs.space; +/* evas_common_load_image_data_from_file(im_old); + evas_common_image_colorspace_normalize(im); if (im_old->image->data) { evas_common_blit_rectangle(im_old, im, 0, 0, w, h, 0, 0); evas_common_cpu_end_opt(); } + */ evas_common_image_unref(im_old); } return im; @@ -408,6 +599,7 @@ static void * eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h) { evas_common_image_dirty(image); + evas_common_image_colorspace_dirty(image); return image; } @@ -418,23 +610,36 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data) im = image; evas_common_load_image_data_from_file(im); - if (to_write) + switch (im->cs.space) { - if (im->references > 1) + case EVAS_COLORSPACE_ARGB8888: + if (to_write) { - RGBA_Image *im_new; - - im_new = evas_common_image_create(im->image->w, im->image->h); - if (!im_new) return im; - evas_common_blit_rectangle(im, im_new, 0, 0, im->image->w, im->image->h, 0, 0); - evas_common_cpu_end_opt(); - evas_common_image_unref(im); - im = im_new; + if (im->references > 1) + { + RGBA_Image *im_new; + + im_new = evas_common_image_create(im->image->w, im->image->h); + if (!im_new) return im; + evas_common_image_colorspace_normalize(im); + evas_common_blit_rectangle(im, im_new, 0, 0, im->image->w, im->image->h, 0, 0); + evas_common_cpu_end_opt(); + evas_common_image_unref(im); + im = im_new; + } + else + evas_common_image_dirty(im); } - else - evas_common_image_dirty(im); + *image_data = im->image->data; + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + *image_data = im->cs.data; + break; + default: + abort(); + break; } - *image_data = im->image->data; return im; } @@ -444,134 +649,69 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) RGBA_Image *im; im = image; - if (image_data != im->image->data) + switch (im->cs.space) { - int w, h; - - w = im->image->w; - h = im->image->h; - evas_common_image_unref(im); - return eng_image_new_from_data(data, w, h, image_data); + case EVAS_COLORSPACE_ARGB8888: + if (image_data != im->image->data) + { + int w, h; + + w = im->image->w; + h = im->image->h; + evas_common_image_unref(im); + return eng_image_new_from_data(data, w, h, image_data, + eng_image_alpha_get(data, image), + eng_image_colorspace_get(data, image)); + } + break; + case EVAS_COLORSPACE_YCBCR422P601_PL: + case EVAS_COLORSPACE_YCBCR422P709_PL: + if (image_data != im->cs.data) + { + if (im->cs.data) + { + if (!im->cs.no_free) free(im->cs.data); + } + im->cs.data = image_data; + evas_common_image_colorspace_dirty(im); + } + break; + default: + abort(); + break; } return im; } -static void * -eng_image_alpha_set(void *data, void *image, int has_alpha) -{ - RGBA_Image *im; - - im = image; - if (im->references > 1) - { - RGBA_Image *im_new; - - im_new = evas_common_image_create(im->image->w, im->image->h); - if (!im_new) return im; - evas_common_load_image_data_from_file(im); - evas_common_blit_rectangle(im, im_new, 0, 0, im->image->w, im->image->h, 0, 0); - evas_common_cpu_end_opt(); - evas_common_image_unref(im); - im = im_new; - } - else - evas_common_image_dirty(im); - if (has_alpha) - im->flags |= RGBA_IMAGE_HAS_ALPHA; - else - im->flags &= ~RGBA_IMAGE_HAS_ALPHA; - return im; -} - - -static int -eng_image_alpha_get(void *data, void *image) -{ - RGBA_Image *im; - - im = image; - if (im->flags & RGBA_IMAGE_HAS_ALPHA) return 1; - return 0; -} - -static void * -eng_image_border_set(void *data, void *image, int l, int r, int t, int b) -{ - RGBA_Image *im; - - im = image; - return im; -} - -static void -eng_image_border_get(void *data, void *image, int *l, int *r, int *t, int *b) -{ - RGBA_Image *im; - - im = image; -} - static void eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) { - evas_common_load_image_data_from_file(image); + RGBA_Image *im; + + im = image; + if (im->cs.space == EVAS_COLORSPACE_ARGB8888) + evas_common_load_image_data_from_file(im); + evas_common_image_colorspace_normalize(im); #ifdef BUILD_PTHREAD if (cpunum > 1) - evas_common_pipe_image_draw(image, surface, context, smooth, + evas_common_pipe_image_draw(im, surface, context, smooth, src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h); else #endif { if (smooth) - evas_common_scale_rgba_in_to_out_clip_smooth(image, surface, context, + evas_common_scale_rgba_in_to_out_clip_smooth(im, surface, context, src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h); else - evas_common_scale_rgba_in_to_out_clip_sample(image, surface, context, + evas_common_scale_rgba_in_to_out_clip_sample(im, surface, context, src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h); evas_common_cpu_end_opt(); } } -static char * -eng_image_comment_get(void *data, void *image, char *key) -{ - RGBA_Image *im; - - im = image; - return im->info.comment; -} - -static char * -eng_image_format_get(void *data, void *image) -{ - return NULL; -} - -static void -eng_image_colorspace_set(void *data, void *image, int cspace) -{ -} - -static int -eng_image_colorspace_get(void *data, void *image) -{ - return EVAS_COLORSPACE_ARGB8888; -} - -static void -eng_image_native_set(void *data, void *image, void *native) -{ -} - -static void * -eng_image_native_get(void *data, void *image) -{ - return NULL; -} - static void eng_image_cache_flush(void *data) { diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c b/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c index c987137d0b..d9141dbd00 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine.c @@ -475,24 +475,24 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I } static void * -eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data) +eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re; XR_Image *im; re = (Render_Engine *)data; - im = _xre_image_new_from_data(re->xinf, w, h, image_data); + im = _xre_image_new_from_data(re->xinf, w, h, image_data, alpha, cspace); return im; } static void * -eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data) +eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re; XR_Image *im; re = (Render_Engine *)data; - im = _xre_image_new_from_copied_data(re->xinf, w, h, image_data); + im = _xre_image_new_from_copied_data(re->xinf, w, h, image_data, alpha, cspace); return im; } @@ -590,7 +590,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) { if (!image) { - image = _xre_image_new_from_data(old_image->xinf, old_image->w, old_image->h, image_data); + image = _xre_image_new_from_data(old_image->xinf, old_image->w, old_image->h, image_data, old_image->alpha, EVAS_COLORSPACE_ARGB8888); if (image) { ((XR_Image *)image)->alpha = old_image->alpha; diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine.h b/legacy/evas/src/modules/engines/xrender_x11/evas_engine.h index 4d3b0b8fc3..a99fca0d5b 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine.h +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine.h @@ -106,8 +106,8 @@ struct _XR_Image }; XR_Image *_xre_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo); -XR_Image *_xre_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data); -XR_Image *_xre_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data); +XR_Image *_xre_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace); +XR_Image *_xre_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace); XR_Image *_xre_image_new(Ximage_Info *xinf, int w, int h); void _xre_image_resize(XR_Image *im, int w, int h); void _xre_image_free(XR_Image *im); diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c index c18eb8273c..8ae9b684cb 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c @@ -117,7 +117,7 @@ _xre_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image } XR_Image * -_xre_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data) +_xre_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace) { XR_Image *im; @@ -129,14 +129,14 @@ _xre_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data) im->h = h; im->references = 1; im->data = data; - im->alpha = 1; + im->alpha = alpha; im->dirty = 1; __xre_image_dirty_hash_add(im); return im; } XR_Image * -_xre_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data) +_xre_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace) { XR_Image *im; @@ -162,7 +162,7 @@ _xre_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data) im->xinf = xinf; im->xinf->references++; im->free_data = 1; - im->alpha = 1; + im->alpha = alpha; im->dirty = 1; __xre_image_dirty_hash_add(im); return im; @@ -268,7 +268,7 @@ _xre_image_copy(XR_Image *im) } } if (!data) return NULL; - im2 = _xre_image_new_from_copied_data(im->xinf, im->w, im->h, data); + im2 = _xre_image_new_from_copied_data(im->xinf, im->w, im->h, data, im->alpha, EVAS_COLORSPACE_ARGB8888); if (im2) im2->alpha = im->alpha; if ((im->im) && (!im->dirty)) { diff --git a/legacy/evas/src/modules/engines/xrender_xcb/evas_engine.c b/legacy/evas/src/modules/engines/xrender_xcb/evas_engine.c index 23832e7008..2f8bb605d2 100644 --- a/legacy/evas/src/modules/engines/xrender_xcb/evas_engine.c +++ b/legacy/evas/src/modules/engines/xrender_xcb/evas_engine.c @@ -490,7 +490,7 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I } static void * -eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data) +eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re; XR_Image *im; @@ -501,7 +501,7 @@ eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data) } static void * -eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data) +eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace) { Render_Engine *re; XR_Image *im;