PUSH_VERTEX(pn, x , y + h, 0); PUSH_VERTEX(pn, x + w, y , 0); \
PUSH_VERTEX(pn, x + w, y + h, 0); PUSH_VERTEX(pn, x , y + h, 0); \
} while (0)
-#define PUSH_6_TEXUV(pn, x1, y1, x2, y2) do { \
- PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y2); \
- PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y2); \
+#define PUSH_6_TEXUV(pn, Tex, x1, y1, x2, y2) do { \
+ Evas_GL_Texture *_tex = Tex; \
+ if (_tex && _tex->im) \
+ { \
+ switch (_tex->im->orient) \
+ { \
+ case EVAS_IMAGE_ORIENT_NONE: \
+ PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y2); \
+ PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y2); \
+ break; \
+ case EVAS_IMAGE_ORIENT_90: \
+ PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y2); \
+ PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x2, y2); \
+ break; \
+ case EVAS_IMAGE_ORIENT_180: \
+ PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x2, y1); \
+ PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y1); \
+ break; \
+ case EVAS_IMAGE_ORIENT_270: \
+ PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y1); \
+ PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x1, y1); \
+ break; \
+ case EVAS_IMAGE_FLIP_HORIZONTAL: \
+ PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y2); \
+ PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x2, y2); \
+ break; \
+ case EVAS_IMAGE_FLIP_VERTICAL: \
+ PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y1); \
+ PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y1); \
+ break; \
+ case EVAS_IMAGE_FLIP_TRANSVERSE: \
+ PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y2); \
+ PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x1, y2); \
+ break; \
+ case EVAS_IMAGE_FLIP_TRANSPOSE: \
+ PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x2, y1); \
+ PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x2, y1); \
+ break; \
+ default: \
+ ERR("Wrong orientation"); \
+ } \
+ } \
+ else \
+ { \
+ PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y2); \
+ PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y2); \
+ } \
} while (0)
#define PUSH_6_TEXUV2(pn, x1, y1, x2, y2) do { \
PUSH_TEXUV2(pn, x1, y1); PUSH_TEXUV2(pn, x2, y1); PUSH_TEXUV2(pn, x1, y2); \
Evas_GL_Texture_Pool *pt;
GLfloat tx1, tx2, ty1, ty2;
GLfloat offsetx, offsety;
+ double pw, ph;
Eina_Bool blend = EINA_FALSE;
Evas_GL_Shader shader = SHADER_IMG;
GLuint prog = gc->shared->shader[shader].prog;
pipe_region_expand(gc, pn, x, y, w, h);
PIPE_GROW(gc, pn, 6);
+ pw = pt->w;
+ ph = pt->h;
+ if (tex->im &&
+ (tex->im->orient == EVAS_IMAGE_ORIENT_90 ||
+ tex->im->orient == EVAS_IMAGE_ORIENT_270 ||
+ tex->im->orient == EVAS_IMAGE_FLIP_TRANSPOSE ||
+ tex->im->orient == EVAS_IMAGE_FLIP_TRANSVERSE))
+ {
+ // Adjust size for taking rotation into account as im->w and h are already modified.
+ pw = pt->h;
+ ph = pt->w;
+ }
+
if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
{
- tx1 = ((double)(offsetx) + sx) / (double)pt->w;
- ty1 = 1.0 - ((double)(offsety) + sy) / (double)pt->h;
- tx2 = ((double)(offsetx) + sx + sw) / (double)pt->w;
- ty2 = 1.0 - ((double)(offsety) + sy + sh) / (double)pt->h;
+ tx1 = ((double)(offsetx) + sx) / pw;
+ ty1 = 1.0 - ((double)(offsety) + sy) / ph;
+ tx2 = ((double)(offsetx) + sx + sw) / pw;
+ ty2 = 1.0 - ((double)(offsety) + sy + sh) / ph;
}
else
{
- tx1 = ((double)(offsetx) + sx) / (double)pt->w;
- ty1 = ((double)(offsety) + sy) / (double)pt->h;
- tx2 = ((double)(offsetx) + sx + sw) / (double)pt->w;
- ty2 = ((double)(offsety) + sy + sh) / (double)pt->h;
+ tx1 = ((double)(offsetx) + sx) / pw;
+ ty1 = ((double)(offsety) + sy) / ph;
+ tx2 = ((double)(offsetx) + sx + sw) / pw;
+ ty2 = ((double)(offsety) + sy + sh) / ph;
}
PUSH_6_VERTICES(pn, x, y, w, h);
- PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
+ PUSH_6_TEXUV(pn, tex, tx1, ty1, tx2, ty2);
if (sam)
{
}
PUSH_6_VERTICES(pn, x, y, w, h);
- PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
+ PUSH_6_TEXUV(pn, NULL, tx1, ty1, tx2, ty2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
PUSH_6_COLORS(pn, r, g, b, a);
}
t2y2 = ((sy + sh) / 2) / (double)tex->ptu->h;
PUSH_6_VERTICES(pn, x, y, w, h);
- PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
+ PUSH_6_TEXUV(pn, NULL, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV2(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_6_TEXUV3(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
t2y2 = (sy + sh) / (double)tex->ptuv->h;
PUSH_6_VERTICES(pn, x, y, w, h);
- PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
+ PUSH_6_TEXUV(pn, NULL, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV2(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
if (!nomul)
t2y2 = (sy + sh) / (double)tex->ptuv->h;
PUSH_6_VERTICES(pn, x, y, w, h);
- PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
+ PUSH_6_TEXUV(pn, NULL, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV2(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
if (!nomul)
t2y2 = (tex->y + sy + sh) / (double)tex->pta->h;
PUSH_6_VERTICES(pn, x, y, w, h);
- PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
+ PUSH_6_TEXUV(pn, NULL, tx1, ty1, tx2, ty2);
PUSH_6_TEXA(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
if (!nomul)
#define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_GL_log_dom, __VA_ARGS__)
#define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_GL_log_dom, __VA_ARGS__)
+#ifdef GL_GLES
+# ifndef GL_FRAMEBUFFER
+# define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
+# endif
+#else
+# ifndef GL_FRAMEBUFFER
+# define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
+# endif
+#endif
+
static int eng_gl_image_direct_get(void *data EINA_UNUSED, void *image);
+static int eng_gl_surface_destroy(void *data, void *surface);
static void
eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED)
static void
eng_image_size_get(void *data EINA_UNUSED, void *image, int *w, int *h)
{
+ Evas_GL_Image *im;
if (!image)
{
*w = 0;
*h = 0;
return;
}
- if (w) *w = ((Evas_GL_Image *)image)->w;
- if (h) *h = ((Evas_GL_Image *)image)->h;
+ im = image;
+ if (im->orient == EVAS_IMAGE_ORIENT_90 ||
+ im->orient == EVAS_IMAGE_ORIENT_270 ||
+ im->orient == EVAS_IMAGE_FLIP_TRANSPOSE ||
+ im->orient == EVAS_IMAGE_FLIP_TRANSVERSE)
+ {
+ if (w) *w = ((Evas_GL_Image *)image)->h;
+ if (h) *h = ((Evas_GL_Image *)image)->w;
+ }
+ else
+ {
+ if (w) *w = ((Evas_GL_Image *)image)->w;
+ if (h) *h = ((Evas_GL_Image *)image)->h;
+ }
}
static void *
return image;
}
+static Evas_GL_Image *
+_rotate_image_data(void *data, void *img)
+{
+ int alpha;
+ Evas_GL_Image *im1, *im2;
+ Evas_Engine_GL_Context *gl_context;
+ Render_Engine_GL_Generic *re = data;
+ RGBA_Draw_Context *dc;
+ DATA32 *pixels;
+ int w, h;
+
+ re->window_use(re->software.ob);
+ gl_context = re->window_gl_context_get(re->software.ob);
+ im1 = img;
+
+ w = im1->w;
+ h = im1->h;
+ alpha = eng_image_alpha_get(data, img);
+
+ if (im1->orient == EVAS_IMAGE_ORIENT_90 ||
+ im1->orient == EVAS_IMAGE_ORIENT_270 ||
+ im1->orient == EVAS_IMAGE_FLIP_TRANSPOSE ||
+ im1->orient == EVAS_IMAGE_FLIP_TRANSVERSE)
+ {
+ w = im1->h;
+ h = im1->w;
+ }
+
+ im2 = evas_gl_common_image_surface_new(gl_context, w, h, alpha);
+
+ evas_gl_common_context_target_surface_set(gl_context, im2);
+
+ // Create a new and temporary context
+ dc = evas_common_draw_context_new();
+ evas_common_draw_context_set_clip(dc, 0, 0, im2->w, im2->h);
+ gl_context->dc = dc;
+
+ // Image draw handle the rotation magically for us
+ evas_gl_common_image_draw(gl_context, im1,
+ 0, 0, w, h,
+ 0, 0, im2->w, im2->h,
+ 0);
+ // Do not forget to flush everything or you will have nothing in your buffer
+ evas_gl_common_context_flush(gl_context);
+
+ gl_context->dc = NULL;
+ evas_common_draw_context_free(dc);
+
+ glsym_glBindFramebuffer(GL_FRAMEBUFFER, im2->tex->pt->fb);
+ GLERRV("glsym_glBindFramebuffer");
+
+ // Rely on Evas_GL_Image infrastructure to allocate pixels
+ im2->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
+ if (!im2->im) return NULL;
+ im2->im->cache_entry.flags.alpha = !!alpha;
+ evas_gl_common_image_alloc_ensure(im2);
+ pixels = im2->im->image.data;
+
+ if (im2->tex->pt->format == GL_BGRA)
+ {
+ glReadPixels(0, 0, im2->w, im2->h, GL_BGRA,
+ GL_UNSIGNED_BYTE, pixels);
+ }
+ else
+ {
+ DATA32 *ptr = pixels;
+ unsigned int k;
+
+ glReadPixels(0, 0, im2->w, im2->h, GL_RGBA,
+ GL_UNSIGNED_BYTE, pixels);
+ for (k = im2->w * im2->h; k; --k)
+ {
+ const DATA32 v = *ptr;
+ *ptr++ = (v & 0xFF00FF00)
+ | ((v & 0x00FF0000) >> 16)
+ | ((v & 0x000000FF) << 16);
+ }
+ }
+
+ glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ GLERRV("glsym_glBindFramebuffer");
+
+ return im2;
+}
+
static void *
eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
{
Evas_GL_Image *im;
int error;
+ *image_data = NULL;
+
if (!image)
{
- *image_data = NULL;
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
return NULL;
}
im = image;
if (im->native.data)
{
- *image_data = NULL;
if (err) *err = EVAS_LOAD_ERROR_NONE;
return im;
}
+ if (im->orient != EVAS_IMAGE_ORIENT_NONE)
+ {
+ Evas_GL_Image *im_new = _rotate_image_data(data, image);
+ if (!im_new)
+ {
+ if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ return im;
+ }
+ evas_gl_common_image_free(im);
+
+ *image_data = im_new->im->image.data;
+ return im_new;
+ }
+
#ifdef GL_GLES
re->window_use(re->software.ob);
return im;
}
+static void *
+eng_image_orient_set(void *data, void *image, Evas_Image_Orient orient)
+{
+ Render_Engine_GL_Generic *re = data;
+ Evas_GL_Image *im;
+
+ if (!image) return NULL;
+ im = image;
+ if (im->orient == orient) return image;
+
+ re->window_use(re->software.ob);
+
+ im->orient = orient;
+ return im;
+}
+
+static Evas_Image_Orient
+eng_image_orient_get(void *data EINA_UNUSED, void *image)
+{
+ Evas_GL_Image *im;
+
+ if (!image) return EVAS_IMAGE_ORIENT_NONE;
+ im = image;
+ return im->orient;
+}
+
static void
eng_image_data_preload_request(void *data, void *image, const Eo *target)
{
return EINA_FALSE;
}
-#ifdef GL_GLES
-# ifndef GL_FRAMEBUFFER
-# define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
-# endif
-#else
-# ifndef GL_FRAMEBUFFER
-# define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
-# endif
-#endif
-
/* Since this is an FBO, the pixels are already in the right Y order.
* But some devices don't support GL_BGRA, so we still need to convert.
*/
ORD(image_data_preload_cancel);
ORD(image_alpha_set);
ORD(image_alpha_get);
+ ORD(image_orient_set);
+ ORD(image_orient_get);
ORD(image_border_set);
ORD(image_border_get);
ORD(image_draw);