summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-02-25 19:05:12 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2015-02-27 13:06:09 +0900
commitfddaf62fcc4ea94914bfd8a608eceb2eb4610473 (patch)
treeeb4facee25f1696264badb69689b906b85c05b1b
parentf298183d4e9ba38c06793b3079f4965eaba8fb63 (diff)
downloadefl-fddaf62fcc4ea94914bfd8a608eceb2eb4610473.tar.gz
Evas masking: Add fast path for image-only masks in GL.
This will currently optimize most of the masks when using the GL engine[1]. This is a very special case that adds a highly optimized path for masking in GL. It works by creating a virtual image, containing a pointer to the original image and a new geometry[2]. Instead of creating a new FBO-based surface (image_map_surface), we refer to the original image and adjust the mask geometry on the fly. KNOWN BUGS: - masking a map with such a scaled image is now broken. [1] Right now all masks are simple Evas Object Image, so that means all cases of masking, except masks of masks, or masks of maps, will be optimized with this new method. [2] This virtual image mechanism is still quite hackish and may be improved (for memory usage, refcounting, etc...)
-rw-r--r--src/lib/evas/canvas/evas_object_image.c21
-rw-r--r--src/lib/evas/canvas/evas_render.c163
-rw-r--r--src/lib/evas/include/evas_private.h3
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h21
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_context.c38
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_font.c79
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_image.c67
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_polygon.c4
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_rectangle.c41
-rw-r--r--src/modules/evas/engines/gl_generic/evas_engine.c52
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c1
11 files changed, 337 insertions, 153 deletions
diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c
index 63f777f04a..2faf393578 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -3541,6 +3541,18 @@ state_write:
}
}
+static inline void
+_image_mask_image_set(Evas_Object_Protected_Data *obj, Eina_Bool smooth, void *image)
+{
+ if ((obj->mask->image != image) || (obj->mask->smooth_scale != smooth))
+ {
+ EINA_COW_WRITE_BEGIN(evas_object_mask_cow, obj->mask, Evas_Object_Mask_Data, mask)
+ mask->image = image;
+ mask->smooth_scale = smooth;
+ EINA_COW_WRITE_END(evas_object_mask_cow, obj->mask, mask);
+ }
+}
+
static void
evas_object_image_render_pre(Evas_Object *eo_obj,
Evas_Object_Protected_Data *obj,
@@ -3561,6 +3573,15 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
if ((o->cur->fill.w < 1) || (o->cur->fill.h < 1)) return;
+ /* plain mask images */
+ if (obj->mask->is_mask && !o->cur->scene && !o->cur->source)
+ {
+ DBG("Setting image pointer in mask data.");
+ _image_mask_image_set(obj, o->cur->smooth_scale, o->engine_data);
+ }
+ else
+ _image_mask_image_set(obj, EINA_FALSE, NULL);
+
/* if someone is clipping this obj - go calculate the clipper */
if (obj->cur->clipper)
{
diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c
index b88c224931..27c9ef9cc1 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -368,7 +368,10 @@ _evas_render_phase1_direct(Evas_Public_Data *e,
{
/* is image clipper */
if (_evas_render_object_changed_get(obj))
- _evas_mask_redraw_set(e, obj);
+ {
+ obj->func->render_pre(obj->object, obj, obj->private_data);
+ _evas_mask_redraw_set(e, obj);
+ }
}
}
for (i = 0; i < render_objects->count; i++)
@@ -1768,6 +1771,7 @@ evas_render_mask_subrender(Evas_Public_Data *evas,
int level)
{
int x, y, w, h, r, g, b, a;
+ Eina_Bool is_image, done = EINA_FALSE;
void *ctx;
if (!mask) return;
@@ -1779,6 +1783,8 @@ evas_render_mask_subrender(Evas_Public_Data *evas,
RD(level, "evas_render_mask_subrender(%p, prev: %p)\n", mask, prev_mask);
+ is_image = eo_isa(mask->object, EVAS_IMAGE_CLASS);
+
x = mask->cur->geometry.x;
y = mask->cur->geometry.y;
w = mask->cur->geometry.w;
@@ -1821,81 +1827,102 @@ evas_render_mask_subrender(Evas_Public_Data *evas,
EINA_COW_WRITE_BEGIN(evas_object_mask_cow, mask->mask, Evas_Object_Mask_Data, mdata)
mdata->redraw = EINA_FALSE;
- /* delete render surface if changed or if already alpha
- * (we don't know how to render objects to alpha) */
- if (mdata->surface && ((w != mdata->w) || (h != mdata->h) || mdata->is_alpha))
- {
- ENFN->image_map_surface_free(ENDT, mdata->surface);
- mdata->surface = NULL;
- }
-
- /* create new RGBA render surface if needed */
- if (!mdata->surface)
+ if (is_image && !prev_mask && mdata->image && ENFN->image_scaled_update)
{
- mdata->surface = ENFN->image_map_surface_new(ENDT, w, h, EINA_TRUE);
- if (!mdata->surface) goto end;
- mdata->is_alpha = EINA_FALSE;
- mdata->w = w;
- mdata->h = h;
+ /* Fast path (for GL) that avoids creating a map surface, render the
+ * scaled image in it, when the shaders can just scale on the fly. */
+ void *scaled = ENFN->image_scaled_update
+ (ENDT, mdata->surface, mdata->image, w, h,
+ mdata->smooth_scale, EINA_TRUE, EVAS_COLORSPACE_GRY8);
+ if (scaled)
+ {
+ done = EINA_TRUE;
+ if (mdata->surface && (mdata->surface != scaled))
+ ENFN->image_map_surface_free(ENDT, mdata->surface);
+ mdata->surface = scaled;
+ mdata->w = w;
+ mdata->h = h;
+ mdata->is_alpha = (ENFN->image_colorspace_get(ENDT, scaled) == EVAS_COLORSPACE_GRY8);
+ }
}
- /* Clear surface with transparency */
- ctx = ENFN->context_new(ENDT);
- ENFN->context_color_set(ENDT, ctx, 0, 0, 0, 0);
- ENFN->context_render_op_set(ENDT, ctx, EVAS_RENDER_COPY);
- ENFN->rectangle_draw(ENDT, ctx, mdata->surface, 0, 0, w, h, EINA_FALSE);
- ENFN->context_free(ENDT, ctx);
-
- /* Render mask to RGBA surface */
- ctx = ENFN->context_new(ENDT);
- if (prev_mask)
+ if (!done)
{
- ENFN->context_clip_image_set(ENDT, ctx,
- prev_mask->mask->surface,
- prev_mask->cur->geometry.x - x,
- prev_mask->cur->geometry.y - y);
- }
- evas_render_mapped(evas, mask->object, mask, ctx, mdata->surface,
- -x, -y, 1, 0, 0, evas->output.w, evas->output.h,
- NULL, level, EINA_TRUE, EINA_FALSE);
- ENFN->context_free(ENDT, ctx);
-
- /* BEGIN HACK */
-
- /* Now we want to convert this RGBA surface to Alpha.
- * NOTE: So, this is not going to work with the GL engine but only with
- * the SW engine. Here's the detection hack:
- * FIXME: If you know of a way to support rendering to GL_ALPHA in GL,
- * then we should render directly to an ALPHA surface. A priori,
- * GLES FBO does not support this.
- */
- if (!ENFN->gl_surface_read_pixels)
- {
- RGBA_Image *alpha_surface;
- DATA32 *rgba;
- DATA8* alpha;
-
- alpha_surface = ENFN->image_new_from_copied_data
- (ENDT, w, h, NULL, EINA_TRUE, EVAS_COLORSPACE_GRY8);
- if (!alpha_surface) goto end;
-
- /* Copy alpha channel */
- rgba = ((RGBA_Image *) mdata->surface)->image.data;
- alpha = alpha_surface->image.data8;
- for (y = h; y; --y)
- for (x = w; x; --x, alpha++, rgba++)
- *alpha = (DATA8) A_VAL(rgba);
-
- /* Now we can drop the original surface */
- ENFN->image_map_surface_free(ENDT, mdata->surface);
- mdata->surface = alpha_surface;
- mdata->is_alpha = EINA_TRUE;
+ /* delete render surface if changed or if already alpha
+ * (we don't know how to render objects to alpha) */
+ if (mdata->surface && ((w != mdata->w) || (h != mdata->h) || mdata->is_alpha))
+ {
+ ENFN->image_map_surface_free(ENDT, mdata->surface);
+ mdata->surface = NULL;
+ }
+
+ /* create new RGBA render surface if needed */
+ if (!mdata->surface)
+ {
+ mdata->surface = ENFN->image_map_surface_new(ENDT, w, h, EINA_TRUE);
+ if (!mdata->surface) goto end;
+ mdata->is_alpha = EINA_FALSE;
+ mdata->w = w;
+ mdata->h = h;
+ }
+
+ /* Clear surface with transparency */
+ ctx = ENFN->context_new(ENDT);
+ ENFN->context_color_set(ENDT, ctx, 0, 0, 0, 0);
+ ENFN->context_render_op_set(ENDT, ctx, EVAS_RENDER_COPY);
+ ENFN->rectangle_draw(ENDT, ctx, mdata->surface, 0, 0, w, h, EINA_FALSE);
+ ENFN->context_free(ENDT, ctx);
+
+ /* Render mask to RGBA surface */
+ ctx = ENFN->context_new(ENDT);
+ if (prev_mask)
+ {
+ ENFN->context_clip_image_set(ENDT, ctx,
+ prev_mask->mask->surface,
+ prev_mask->cur->geometry.x - x,
+ prev_mask->cur->geometry.y - y);
+ }
+ evas_render_mapped(evas, mask->object, mask, ctx, mdata->surface,
+ -x, -y, 1, 0, 0, evas->output.w, evas->output.h,
+ NULL, level, EINA_TRUE, EINA_FALSE);
+ ENFN->context_free(ENDT, ctx);
+
+ /* BEGIN HACK */
+
+ /* Now we want to convert this RGBA surface to Alpha.
+ * NOTE: So, this is not going to work with the GL engine but only with
+ * the SW engine. Here's the detection hack:
+ * FIXME: If you know of a way to support rendering to GL_ALPHA in GL,
+ * then we should render directly to an ALPHA surface. A priori,
+ * GLES FBO does not support this.
+ */
+ if (!ENFN->gl_surface_read_pixels)
+ {
+ RGBA_Image *alpha_surface;
+ DATA32 *rgba;
+ DATA8* alpha;
+
+ alpha_surface = ENFN->image_new_from_copied_data
+ (ENDT, w, h, NULL, EINA_TRUE, EVAS_COLORSPACE_GRY8);
+ if (!alpha_surface) goto end;
+
+ /* Copy alpha channel */
+ rgba = ((RGBA_Image *) mdata->surface)->image.data;
+ alpha = alpha_surface->image.data8;
+ for (y = h; y; --y)
+ for (x = w; x; --x, alpha++, rgba++)
+ *alpha = (DATA8) A_VAL(rgba);
+
+ /* Now we can drop the original surface */
+ ENFN->image_map_surface_free(ENDT, mdata->surface);
+ mdata->surface = alpha_surface;
+ mdata->is_alpha = EINA_TRUE;
+ }
+ /* END OF HACK */
}
mdata->surface = ENFN->image_dirty_region(ENDT, mdata->surface, 0, 0, w, h);
- /* END OF HACK */
-
end:
EINA_COW_WRITE_END(evas_object_mask_cow, mask->mask, mdata);
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 862bc9631b..f71d26e74e 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -911,10 +911,12 @@ struct _Evas_Object_3D_Data
struct _Evas_Object_Mask_Data
{
void *surface;
+ void *image; // original image
int w, h;
Eina_Bool is_mask : 1;
Eina_Bool redraw : 1;
Eina_Bool is_alpha : 1;
+ Eina_Bool smooth_scale : 1;
};
struct _Evas_Object_Protected_State
@@ -1279,6 +1281,7 @@ struct _Evas_Func
void *(*image_map_surface_new) (void *data, int w, int h, int alpha);
void (*image_map_surface_free) (void *data, void *surface);
void (*image_map_clean) (void *data, RGBA_Map *m);
+ void *(*image_scaled_update) (void *data, void *scaled, void *image, int dst_w, int dst_h, Eina_Bool smooth, Eina_Bool alpha, Evas_Colorspace cspace);
void (*image_content_hint_set) (void *data, void *surface, int hint);
int (*image_content_hint_get) (void *data, void *surface);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h
index f2f816198f..b1ba6f360a 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -491,6 +491,7 @@ struct _Evas_Engine_GL_Context
Eina_Bool use_texsam : 1;
Eina_Bool use_texm : 1;
Eina_Bool anti_alias : 1;
+ Eina_Bool mask_smooth : 1;
Evas_GL_Image *im;
GLuint buffer;
int buffer_alloc;
@@ -605,6 +606,12 @@ struct _Evas_GL_Image
unsigned char loose : 1;
} native;
+ struct {
+ Evas_GL_Image *origin;
+ int w, h;
+ Eina_Bool smooth : 1;
+ } scaled;
+
int scale_hint, content_hint;
int csize;
@@ -700,46 +707,46 @@ void evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
void evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
int x, int y, int w, int h,
int r, int g, int b, int a,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh);
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth);
void evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth, Eina_Bool tex_only);
void evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a);
void evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c
index 9ab866395a..04f248f92b 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -1251,10 +1251,10 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
#define PUSH_MASK(pn, mtex, mx, my, mw, mh) if (mtex) do { \
GLfloat tmx1, tmx2, tmy1, tmy2; \
- tmx1 = (mtex->x + mx) / (double)mtex->pt->w; \
- tmy1 = (mtex->y + my) / (double)mtex->pt->h; \
- tmx2 = (mtex->x + mx + mw) / (double)mtex->pt->w; \
- tmy2 = (mtex->y + my + mh) / (double)mtex->pt->h; \
+ tmx1 = mx; \
+ tmy1 = my; \
+ tmx2 = mx + mw; \
+ tmy2 = my + mh; \
PUSH_TEXM(pn, tmx1, tmy1); \
PUSH_TEXM(pn, tmx2, tmy1); \
PUSH_TEXM(pn, tmx1, tmy2); \
@@ -1262,6 +1262,12 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
PUSH_TEXM(pn, tmx2, tmy2); \
PUSH_TEXM(pn, tmx1, tmy2); \
} while(0)
+/* was:
+ tmx1 = (mtex->x + mx) / (double)mtex->pt->w; \
+ tmy1 = (mtex->y + my) / (double)mtex->pt->h; \
+ tmx2 = (mtex->x + mx + mw) / (double)mtex->pt->w; \
+ tmy2 = (mtex->y + my + mh) / (double)mtex->pt->h; \
+ */
#define PIPE_GROW(gc, pn, inc) \
int nv = gc->pipe[pn].array.num * 3; (void) nv; \
@@ -1580,7 +1586,7 @@ evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
int x, int y, int w, int h,
int r, int g, int b, int a,
Evas_GL_Texture *mtex,
- int mx, int my, int mw, int mh)
+ double mx, double my, double mw, double mh, Eina_Bool mask_smooth)
{
Eina_Bool blend = EINA_FALSE;
Evas_GL_Shader shader = SHADER_RECT;
@@ -1728,7 +1734,7 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth, Eina_Bool tex_only)
{
@@ -1959,6 +1965,7 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
gc->pipe[pn].array.use_texuv3 = 0;
gc->pipe[pn].array.use_texm = !!mtex;
gc->pipe[pn].array.use_texsam = sam;
+ gc->pipe[pn].array.mask_smooth = mask_smooth;
pipe_region_expand(gc, pn, x, y, w, h);
PIPE_GROW(gc, pn, 6);
@@ -2007,7 +2014,7 @@ evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a)
{
GLfloat tx1, tx2, ty1, ty2;
@@ -2047,6 +2054,7 @@ evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
gc->pipe[pn].array.use_texuv3 = 0;
gc->pipe[pn].array.use_texm = !!mtex;
gc->pipe[pn].array.use_texsam = 0;
+ gc->pipe[pn].array.mask_smooth = mask_smooth;
pipe_region_expand(gc, pn, x, y, w, h);
PIPE_GROW(gc, pn, 6);
@@ -2077,7 +2085,7 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth)
{
@@ -2126,6 +2134,7 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
gc->pipe[pn].array.use_texuv3 = 1;
gc->pipe[pn].array.use_texm = !!mtex;
gc->pipe[pn].array.use_texsam = 0;
+ gc->pipe[pn].array.mask_smooth = mask_smooth;
pipe_region_expand(gc, pn, x, y, w, h);
PIPE_GROW(gc, pn, 6);
@@ -2153,7 +2162,7 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth)
{
@@ -2201,6 +2210,7 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
gc->pipe[pn].array.use_texuv3 = 0;
gc->pipe[pn].array.use_texm = !!mtex;
gc->pipe[pn].array.use_texsam = 0;
+ gc->pipe[pn].array.mask_smooth = mask_smooth;
pipe_region_expand(gc, pn, x, y, w, h);
PIPE_GROW(gc, pn, 6);
@@ -2227,7 +2237,7 @@ evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth)
{
@@ -2277,6 +2287,7 @@ evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
gc->pipe[pn].array.use_texuv3 = 0;
gc->pipe[pn].array.use_texm = !!mtex;
gc->pipe[pn].array.use_texsam = 0;
+ gc->pipe[pn].array.mask_smooth = mask_smooth;
pipe_region_expand(gc, pn, x, y, w, h);
PIPE_GROW(gc, pn, 6);
@@ -2304,7 +2315,7 @@ evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
double sx, double sy,
double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Evas_GL_Texture *mtex, double mx, double my, double mw, double mh, Eina_Bool mask_smooth,
int r, int g, int b, int a,
Eina_Bool smooth)
@@ -2359,6 +2370,7 @@ evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
gc->pipe[pn].array.use_texa = EINA_TRUE;
gc->pipe[pn].array.use_texsam = 0;
gc->pipe[pn].array.use_texm = !!mtex;
+ gc->pipe[pn].array.mask_smooth = mask_smooth;
pipe_region_expand(gc, pn, x, y, w, h);
PIPE_GROW(gc, pn, 6);
@@ -2589,6 +2601,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
gc->pipe[pn].array.use_texm = !!mtex;
gc->pipe[pn].array.use_texa = !!mtex;
gc->pipe[pn].array.use_texsam = gc->pipe[pn].array.use_texm;
+ gc->pipe[pn].array.mask_smooth = EINA_FALSE;
pipe_region_expand(gc, pn, x, y, w, h);
PIPE_GROW(gc, pn, 6);
@@ -3281,7 +3294,7 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
if (shared->info.anisotropic > 0.0)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, shared->info.anisotropic);
#endif
- if (gc->pipe[i].shader.smooth)
+ if (gc->pipe[i].array.mask_smooth) // (gc->pipe[i].shader.smooth)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -3359,6 +3372,7 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
gc->pipe[i].array.use_texa = 0;
gc->pipe[i].array.use_texsam = 0;
gc->pipe[i].array.use_texm = 0;
+ gc->pipe[i].array.mask_smooth = 0;
gc->pipe[i].array.vertex = NULL;
gc->pipe[i].array.color = NULL;
diff --git a/src/modules/evas/engines/gl_common/evas_gl_font.c b/src/modules/evas/engines/gl_common/evas_gl_font.c
index 248634bb07..ca6eae9a13 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_font.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_font.c
@@ -61,14 +61,16 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
{
Evas_Engine_GL_Context *gc = context;
RGBA_Draw_Context *dc = draw_context;
- Evas_GL_Texture *tex, *mtex = NULL;
+ Evas_GL_Image *mask = gc->dc->clip.mask;
+ Evas_GL_Texture *tex, *mtex = mask ? mask->tex : NULL;
Cutout_Rect *rct;
int r, g, b, a;
double ssx, ssy, ssw, ssh;
int c, cx, cy, cw, ch;
int i;
int sx, sy, sw, sh;
- double mmx = 0.0, mmy = 0.0, mmw = 0.0, mmh = 0.0;
+ double mx = 0.0, my = 0.0, mw = 0.0, mh = 0.0;
+ Eina_Bool mask_smooth = EINA_FALSE;
if (dc != gc->dc) return;
tex = fg->ext_dat;
@@ -82,36 +84,43 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
if (gc->dc->clip.mask && (sw > 0) && (sh > 0))
{
- // FIXME: This code path does not handle half the stuff the other path does...
- Evas_GL_Image *mask = gc->dc->clip.mask;
- int nx, ny, nw, nh, dx, dy, dw, dh;
- double mx, my, mw, mh;
-
- if (mask->tex)
+ double nx, ny, nw, nh, dx, dy, dw, dh;
+ const double mask_x = gc->dc->clip.mask_x;
+ const double mask_y = gc->dc->clip.mask_y;
+ const double tmw = mtex->pt->w;
+ const double tmh = mtex->pt->h;
+ double scalex = 1.0;
+ double scaley = 1.0;
+
+ // canvas coords
+ nx = x; ny = y; nw = tex->w; nh = tex->h;
+ RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
+ gc->dc->clip.x, gc->dc->clip.y,
+ gc->dc->clip.w, gc->dc->clip.h);
+ if ((nw < 1) || (nh < 1)) return;
+ dx = x; dy = y; dw = sw; dh = sh;
+ mx = mask_x; my = mask_y;
+ if (mask->scaled.origin && mask->scaled.w && mask->scaled.h)
{
- nx = x; ny = y; nw = tex->w; nh = tex->h;
- RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
- gc->dc->clip.x, gc->dc->clip.y,
- gc->dc->clip.w, gc->dc->clip.h);
- if ((nw < 1) || (nh < 1)) return;
-
- //ssx = (double)sx + ((double)(sw * (nx - x)) / (double)(tex->w));
- //ssy = (double)sy + ((double)(sh * (ny - y)) / (double)(tex->h));
- //ssw = ((double)sw * (double)(nw)) / (double)(tex->w);
- //ssh = ((double)sh * (double)(nh)) / (double)(tex->h);
-
- dx = x; dy = y; dw = sw; dh = sh;
- mx = gc->dc->clip.mask_x; my = gc->dc->clip.mask_y; mw = mask->w; mh = mask->h;
- //RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
- RECTS_CLIP_TO_RECT(mx, my, mw, mh, dx, dy, dw, dh);
-
- mmx = (double)(mx - gc->dc->clip.mask_x) + ((double)(mw * (nx - dx)) / (double)(dw));
- mmy = (double)(my - gc->dc->clip.mask_y) + ((double)(mh * (ny - dy)) / (double)(dh));
- mmw = ((double)mw * (double)(nw)) / (double)(dw);
- mmh = ((double)mh * (double)(nh)) / (double)(dh);
-
- mtex = mask->tex;
+ mw = mask->scaled.w;
+ mh = mask->scaled.h;
+ scalex = mask->w / (double)mask->scaled.w;
+ scaley = mask->h / (double)mask->scaled.h;
+ mask_smooth = mask->scaled.smooth;
+ }
+ else
+ {
+ mw = mask->w;
+ mh = mask->h;
}
+ //RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
+ RECTS_CLIP_TO_RECT(mx, my, mw, mh, dx, dy, dw, dh);
+
+ // convert to tex coords
+ mx = (mtex->x / tmw) + ((mx - mask_x + (mw * (nx - dx)) / dw) * scalex / tmw);
+ my = (mtex->y / tmh) + ((my - mask_y + (mh * (ny - dy)) / dy) * scaley / tmh);
+ mw = (mw * nw * scalex / dw) / tmw;
+ mh = (mh * nh * scaley / dh) / tmh;
}
if ((!gc->dc->cutout.rects) ||
@@ -133,7 +142,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
0.0, 0.0, 0.0, 0.0,
// sx, sy, sw, sh,
x, y, tex->w, tex->h,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a);
return;
}
@@ -144,7 +153,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
evas_gl_common_context_font_push(gc, tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a);
}
else
@@ -153,7 +162,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
0.0, 0.0, 0.0, 0.0,
// sx, sy, sw, sh,
x, y, tex->w, tex->h,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a);
}
return;
@@ -183,7 +192,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
0.0, 0.0, 0.0, 0.0,
// sx, sy, sw, sh,
x, y, tex->w, tex->h,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a);
continue;
}
@@ -194,7 +203,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
evas_gl_common_context_font_push(gc, tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a);
}
evas_common_draw_context_cutouts_free(_evas_gl_common_cutout_rects);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c
index 0bd990a641..2fdc60889f 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_image.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_image.c
@@ -690,6 +690,9 @@ evas_gl_common_image_free(Evas_GL_Image *im)
im->references--;
if (im->references > 0) return;
+ if (im->scaled.origin)
+ evas_gl_common_image_free(im->scaled.origin);
+
if (im->native.func.free)
im->native.func.free(im->native.func.data, im);
@@ -964,6 +967,9 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
mmw = mw;
mmh = mh;
mtex = mask->tex;
+ // TODO: implement support for scaled masks
+ //if (mask->scaled.origin)
+ //mask_smooth = mask->scaled.smooth;
}
evas_gl_common_context_image_map_push(gc, im->tex, npoints, p,
@@ -984,9 +990,10 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
Eina_Bool yuv, Eina_Bool yuy2, Eina_Bool nv12,
Eina_Bool rgb_a_pair)
{
- double mmx = 0, mmy = 0, mmw = 0, mmh = 0;
+ double mx = 0, my = 0, mw = 0, mh = 0;
double ssx, ssy, ssw, ssh;
- Evas_GL_Texture *mtex = NULL;
+ Evas_GL_Texture *mtex = mask ? mask->tex : NULL;
+ Eina_Bool mask_smooth = EINA_FALSE;
int nx, ny, nw, nh;
nx = dx; ny = dy; nw = dw; nh = dh;
@@ -995,18 +1002,36 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
if ((nw < 1) || (nh < 1)) return;
if (!im->tex) return;
- if (mask && mask->tex)
+ if (mtex && mtex->pt && mtex->pt->w && mtex->pt->h)
{
- double mx, my, mw, mh;
-
- mx = mask_x; my = mask_y; mw = mask->w; mh = mask->h;
+ const double tmw = mtex->pt->w;
+ const double tmh = mtex->pt->h;
+ double scalex = 1.0;
+ double scaley = 1.0;
+
+ // canvas coords
+ mx = mask_x; my = mask_y;
+ if (mask->scaled.origin)
+ {
+ mw = mask->scaled.w;
+ mh = mask->scaled.h;
+ scalex = mask->w / (double)mask->scaled.w;
+ scaley = mask->h / (double)mask->scaled.h;
+ mask_smooth = mask->scaled.smooth;
+ }
+ else
+ {
+ mw = mask->w;
+ mh = mask->h;
+ }
RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
RECTS_CLIP_TO_RECT(mx, my, mw, mh, dx, dy, dw, dh);
- mmx = mx - mask_x;
- mmy = my - mask_y;
- mmw = mw;
- mmh = mh;
- mtex = mask->tex;
+
+ // convert to tex coords
+ mx = (mtex->x / tmw) + ((mx - mask_x) * scalex / tmw);
+ my = (mtex->y / tmh) + ((my - mask_y) * scaley / tmh);
+ mw = mw * scalex / tmw;
+ mh = mh * scaley / tmh;
}
if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
@@ -1016,7 +1041,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else if (yuy2)
@@ -1024,7 +1049,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else if (nv12)
@@ -1032,7 +1057,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else if (rgb_a_pair)
@@ -1040,7 +1065,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else
@@ -1048,7 +1073,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth, im->tex_only);
return;
@@ -1064,7 +1089,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else if (yuy2)
@@ -1072,7 +1097,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else if (nv12)
@@ -1080,7 +1105,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else if (rgb_a_pair)
@@ -1088,7 +1113,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth);
else
@@ -1096,7 +1121,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mmx, mmy, mmw, mmh,
+ mtex, mx, my, mw, mh, mask_smooth,
r, g, b, a,
smooth, im->tex_only);
}
diff --git a/src/modules/evas/engines/gl_common/evas_gl_polygon.c b/src/modules/evas/engines/gl_common/evas_gl_polygon.c
index 0e5dd7f83a..df87cb79cc 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_polygon.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_polygon.c
@@ -272,7 +272,7 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
h = 1;
evas_gl_common_context_rectangle_push(gc, x, y, w, h,
cr, cg, cb, ca,
- NULL, 0, 0, 0, 0);
+ NULL, 0, 0, 0, 0, EINA_FALSE);
}
}
else
@@ -296,7 +296,7 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
if ((w > 0) && (h > 0))
evas_gl_common_context_rectangle_push(gc, x, y, w, h,
cr, cg, cb, ca,
- NULL, 0, 0, 0, 0);
+ NULL, 0, 0, 0, 0, EINA_FALSE);
}
}
}
diff --git a/src/modules/evas/engines/gl_common/evas_gl_rectangle.c b/src/modules/evas/engines/gl_common/evas_gl_rectangle.c
index 7ef30fc149..39c0c00ad6 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_rectangle.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_rectangle.c
@@ -6,7 +6,9 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
Cutout_Rect *r;
int c, cx, cy, cw, ch, cr, cg, cb, ca, i;
double mx = 0, my = 0, mw = 0, mh = 0;
- Evas_GL_Texture *mtex = NULL;
+ Eina_Bool mask_smooth = EINA_FALSE;
+ Evas_GL_Image *mask = gc->dc->clip.mask;
+ Evas_GL_Texture *mtex = mask ? mask->tex : NULL;
if ((w <= 0) || (h <= 0)) return;
if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, gc->w, gc->h))) return;
@@ -28,21 +30,44 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
gc->dc->clip.w, gc->dc->clip.h);
}
- if (gc->dc->clip.mask)
+ if (mtex)
{
- Evas_GL_Image *mask = gc->dc->clip.mask;
+ const double mask_x = gc->dc->clip.mask_x;
+ const double mask_y = gc->dc->clip.mask_y;
+ const double tmw = mtex->pt->w;
+ const double tmh = mtex->pt->h;
+ double scalex = 1.0;
+ double scaley = 1.0;
- mx = gc->dc->clip.mask_x; mw = mask->w;
- my = gc->dc->clip.mask_y; mh = mask->h;
+ // canvas coords
+ mx = mask_x; my = mask_y;
+ if (mask->scaled.origin && mask->scaled.w && mask->scaled.h)
+ {
+ mw = mask->scaled.w;
+ mh = mask->scaled.h;
+ scalex = mask->w / (double)mask->scaled.w;
+ scaley = mask->h / (double)mask->scaled.h;
+ mask_smooth = mask->scaled.smooth;
+ }
+ else
+ {
+ mw = mask->w;
+ mh = mask->h;
+ }
RECTS_CLIP_TO_RECT(mx, my, mw, mh, cx, cy, cw, ch);
mx -= gc->dc->clip.mask_x;
my -= gc->dc->clip.mask_y;
- mtex = mask->tex;
+
+ // convert to tex coords
+ mx = (mtex->x / tmw) + ((mx - mask_x) * scalex / tmw);
+ my = (mtex->y / tmh) + ((my - mask_y) * scaley / tmh);
+ mw = mw * scalex / tmw;
+ mh = mh * scaley / tmh;
}
if (!gc->dc->cutout.rects)
{
- evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca, mtex, mx, my, mw, mh);
+ evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca, mtex, mx, my, mw, mh, mask_smooth);
}
else
{
@@ -56,7 +81,7 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
r = _evas_gl_common_cutout_rects->rects + i;
if ((r->w > 0) && (r->h > 0))
{
- evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca, mtex, mx, my, mw, mh);
+ evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca, mtex, mx, my, mw, mh, mask_smooth);
}
}
evas_common_draw_context_cutouts_free(_evas_gl_common_cutout_rects);
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c
index c63e7f1bc8..95c4c97d2a 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -950,6 +950,57 @@ eng_image_map_surface_free(void *data, void *surface)
evas_gl_common_image_free(surface);
}
+static void *
+eng_image_scaled_update(void *data EINA_UNUSED, void *scaled, void *image,
+ int dst_w, int dst_h,
+ Eina_Bool smooth, Eina_Bool alpha,
+ Evas_Colorspace cspace EINA_UNUSED)
+{
+ Evas_GL_Image *dst = scaled;
+ Evas_GL_Image *src = image;
+ Evas_Engine_GL_Context *gc;
+
+ if (!src) return NULL;
+
+ gc = src->gc;
+ if ((dst_w > gc->shared->info.max_texture_size) ||
+ (dst_h > gc->shared->info.max_texture_size))
+ return NULL;
+
+ if (dst && (dst->scaled.origin == src) &&
+ (dst->scaled.w == dst_w) && (dst->scaled.h == dst_h))
+ return dst;
+
+ if (dst) evas_gl_common_image_free(dst);
+ evas_gl_common_image_update(gc, src);
+ if (!src->tex)
+ {
+ ERR("No source texture.");
+ return NULL;
+ }
+
+ dst = calloc(1, sizeof(Evas_GL_Image));
+ if (!dst) return NULL;
+
+ dst->references = 1;
+ dst->gc = gc;
+ dst->cs.space = src->cs.space;
+ dst->alpha = alpha;
+ dst->w = src->w;
+ dst->h = src->h;
+ dst->tex = src->tex;
+ dst->tex->references++;
+ dst->tex_only = 1;
+
+ src->references++;
+ dst->scaled.origin = src;
+ dst->scaled.w = dst_w;
+ dst->scaled.h = dst_h;
+ dst->scaled.smooth = smooth;
+
+ return dst;
+}
+
static void
eng_image_content_hint_set(void *data, void *image, int hint)
{
@@ -2016,6 +2067,7 @@ module_open(Evas_Module *em)
ORD(image_map_surface_new);
ORD(image_map_surface_free);
ORD(image_map_clean);
+ ORD(image_scaled_update);
ORD(image_content_hint_set);
ORD(image_content_hint_get);
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index b4b0f4b629..b9239979e4 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -3545,6 +3545,7 @@ static Evas_Func func =
eng_image_map_surface_new,
eng_image_map_surface_free,
eng_image_map_clean,
+ NULL, // eng_image_scaled_get - used for live scaling in GL only (fastpath)
NULL, // eng_image_content_hint_set - software doesn't use it
NULL, // eng_image_content_hint_get - software doesn't use it
eng_font_pen_coords_get,