forked from enlightenment/efl
Evas: Implement image_data_get for FBO images
This commit is contained in:
parent
d927c1623a
commit
fd4e133cc1
|
@ -1216,6 +1216,8 @@ _evas_image_data_convert(Eo *eo_obj, Evas_Image_Data *o, Evas_Colorspace to_cspa
|
||||||
DATA32 *data;
|
DATA32 *data;
|
||||||
void* result = NULL;
|
void* result = NULL;
|
||||||
|
|
||||||
|
// FIXME: This function is not really useful, and can't work with GL.
|
||||||
|
|
||||||
evas_object_async_block(obj);
|
evas_object_async_block(obj);
|
||||||
if ((o->preloading) && (o->engine_data))
|
if ((o->preloading) && (o->engine_data))
|
||||||
{
|
{
|
||||||
|
@ -1227,7 +1229,7 @@ _evas_image_data_convert(Eo *eo_obj, Evas_Image_Data *o, Evas_Colorspace to_cspa
|
||||||
o->pixels->video.update_pixels(o->pixels->video.data, eo_obj, &o->pixels->video);
|
o->pixels->video.update_pixels(o->pixels->video.data, eo_obj, &o->pixels->video);
|
||||||
if (o->cur->cspace == to_cspace) return NULL;
|
if (o->cur->cspace == to_cspace) return NULL;
|
||||||
data = NULL;
|
data = NULL;
|
||||||
o->engine_data = ENFN->image_data_get(ENDT, o->engine_data, 0, &data, &o->load_error);
|
o->engine_data = ENFN->image_data_get(ENDT, o->engine_data, 0, &data, &o->load_error, NULL);
|
||||||
result = evas_object_image_data_convert_internal(o, data, to_cspace);
|
result = evas_object_image_data_convert_internal(o, data, to_cspace);
|
||||||
if (o->engine_data)
|
if (o->engine_data)
|
||||||
{
|
{
|
||||||
|
@ -1324,6 +1326,8 @@ EOLIAN static void*
|
||||||
_evas_image_data_get(const Eo *eo_obj, Evas_Image_Data *_pd EINA_UNUSED, Eina_Bool for_writing)
|
_evas_image_data_get(const Eo *eo_obj, Evas_Image_Data *_pd EINA_UNUSED, Eina_Bool for_writing)
|
||||||
{
|
{
|
||||||
Evas_Image_Data *o = (Evas_Image_Data *) _pd;
|
Evas_Image_Data *o = (Evas_Image_Data *) _pd;
|
||||||
|
int stride = 0;
|
||||||
|
void *pixels;
|
||||||
DATA32 *data;
|
DATA32 *data;
|
||||||
|
|
||||||
if (!o->engine_data) return NULL;
|
if (!o->engine_data) return NULL;
|
||||||
|
@ -1338,27 +1342,24 @@ _evas_image_data_get(const Eo *eo_obj, Evas_Image_Data *_pd EINA_UNUSED, Eina_Bo
|
||||||
ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint);
|
ENFN->image_scale_hint_set(ENDT, o->engine_data, o->scale_hint);
|
||||||
if (ENFN->image_content_hint_set)
|
if (ENFN->image_content_hint_set)
|
||||||
ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint);
|
ENFN->image_content_hint_set(ENDT, o->engine_data, o->content_hint);
|
||||||
o->engine_data = ENFN->image_data_get(ENDT, o->engine_data, for_writing, &data, &o->load_error);
|
pixels = ENFN->image_data_get(ENDT, o->engine_data, for_writing, &data, &o->load_error, NULL);
|
||||||
|
|
||||||
/* if we fail to get engine_data, we have to return NULL */
|
/* if we fail to get engine_data, we have to return NULL */
|
||||||
if (!o->engine_data) return NULL;
|
if (!pixels) return NULL;
|
||||||
|
|
||||||
if (o->engine_data)
|
o->engine_data = pixels;
|
||||||
|
if (ENFN->image_stride_get)
|
||||||
|
ENFN->image_stride_get(ENDT, o->engine_data, &stride);
|
||||||
|
else
|
||||||
|
stride = o->cur->image.w * 4;
|
||||||
|
|
||||||
|
if (o->cur->image.stride != stride)
|
||||||
{
|
{
|
||||||
int stride = 0;
|
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
|
||||||
|
state_write->image.stride = stride;
|
||||||
if (ENFN->image_stride_get)
|
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
|
||||||
ENFN->image_stride_get(ENDT, o->engine_data, &stride);
|
|
||||||
else
|
|
||||||
stride = o->cur->image.w * 4;
|
|
||||||
|
|
||||||
if (o->cur->image.stride != stride)
|
|
||||||
{
|
|
||||||
EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
|
|
||||||
state_write->image.stride = stride;
|
|
||||||
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
o->pixels_checked_out++;
|
o->pixels_checked_out++;
|
||||||
if (for_writing)
|
if (for_writing)
|
||||||
{
|
{
|
||||||
|
@ -1628,8 +1629,8 @@ _evas_image_efl_file_save(const Eo *eo_obj, Evas_Image_Data *o, const char *file
|
||||||
DATA32 *data = NULL;
|
DATA32 *data = NULL;
|
||||||
int quality = 80, compress = 9, ok = 0;
|
int quality = 80, compress = 9, ok = 0;
|
||||||
char *encoding = NULL;
|
char *encoding = NULL;
|
||||||
RGBA_Image *im;
|
Image_Entry *ie;
|
||||||
Eina_Bool putback = EINA_FALSE;
|
Eina_Bool putback = EINA_FALSE, tofree = EINA_FALSE;
|
||||||
int imagew, imageh;
|
int imagew, imageh;
|
||||||
void *pixels;
|
void *pixels;
|
||||||
|
|
||||||
|
@ -1679,7 +1680,7 @@ _evas_image_efl_file_save(const Eo *eo_obj, Evas_Image_Data *o, const char *file
|
||||||
o->proxyrendering = EINA_FALSE;
|
o->proxyrendering = EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pixels = ENFN->image_data_get(ENDT, pixels, 0, &data, &o->load_error);
|
pixels = ENFN->image_data_get(ENDT, pixels, 0, &data, &o->load_error, &tofree);
|
||||||
|
|
||||||
if (!pixels)
|
if (!pixels)
|
||||||
{
|
{
|
||||||
|
@ -1706,11 +1707,12 @@ _evas_image_efl_file_save(const Eo *eo_obj, Evas_Image_Data *o, const char *file
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
im = (RGBA_Image*) evas_cache_image_data(evas_common_image_cache_get(),
|
ie = evas_cache_image_data(evas_common_image_cache_get(),
|
||||||
imagew, imageh, data, o->cur->has_alpha,
|
imagew, imageh, data, o->cur->has_alpha,
|
||||||
EVAS_COLORSPACE_ARGB8888);
|
EVAS_COLORSPACE_ARGB8888);
|
||||||
if (im)
|
if (ie)
|
||||||
{
|
{
|
||||||
|
RGBA_Image *im = (RGBA_Image *) ie;
|
||||||
if (o->cur->cspace == EVAS_COLORSPACE_ARGB8888)
|
if (o->cur->cspace == EVAS_COLORSPACE_ARGB8888)
|
||||||
im->image.data = data;
|
im->image.data = data;
|
||||||
else
|
else
|
||||||
|
@ -1722,10 +1724,12 @@ _evas_image_efl_file_save(const Eo *eo_obj, Evas_Image_Data *o, const char *file
|
||||||
if (o->cur->cspace != EVAS_COLORSPACE_ARGB8888)
|
if (o->cur->cspace != EVAS_COLORSPACE_ARGB8888)
|
||||||
free(im->image.data);
|
free(im->image.data);
|
||||||
}
|
}
|
||||||
|
evas_cache_image_drop(ie);
|
||||||
evas_cache_image_drop(&im->cache_entry);
|
|
||||||
}
|
}
|
||||||
if (putback)
|
|
||||||
|
if (tofree)
|
||||||
|
ENFN->image_free(ENDT, pixels);
|
||||||
|
else if (putback)
|
||||||
o->engine_data = ENFN->image_data_put(ENDT, pixels, data);
|
o->engine_data = ENFN->image_data_put(ENDT, pixels, data);
|
||||||
|
|
||||||
free(encoding);
|
free(encoding);
|
||||||
|
@ -1737,6 +1741,8 @@ _evas_image_pixels_import(Eo *eo_obj, Evas_Image_Data *o, Evas_Pixel_Import_Sour
|
||||||
{
|
{
|
||||||
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
||||||
|
|
||||||
|
// FIXME: This function is not really useful, and can't work with GL.
|
||||||
|
|
||||||
evas_object_async_block(obj);
|
evas_object_async_block(obj);
|
||||||
_evas_object_image_cleanup(eo_obj, obj, o);
|
_evas_object_image_cleanup(eo_obj, obj, o);
|
||||||
if ((pixels->w != o->cur->image.w) || (pixels->h != o->cur->image.h)) return EINA_FALSE;
|
if ((pixels->w != o->cur->image.w) || (pixels->h != o->cur->image.h)) return EINA_FALSE;
|
||||||
|
@ -1776,7 +1782,7 @@ _evas_image_pixels_import(Eo *eo_obj, Evas_Image_Data *o, Evas_Pixel_Import_Sour
|
||||||
{
|
{
|
||||||
DATA32 *image_pixels = NULL;
|
DATA32 *image_pixels = NULL;
|
||||||
|
|
||||||
o->engine_data = ENFN->image_data_get(ENDT, o->engine_data, 1, &image_pixels,&o->load_error);
|
o->engine_data = ENFN->image_data_get(ENDT, o->engine_data, 1, &image_pixels,&o->load_error, NULL);
|
||||||
if (image_pixels)
|
if (image_pixels)
|
||||||
evas_common_convert_yuv_422p_601_rgba((DATA8 **) pixels->rows, (DATA8 *) image_pixels, o->cur->image.w, o->cur->image.h);
|
evas_common_convert_yuv_422p_601_rgba((DATA8 **) pixels->rows, (DATA8 *) image_pixels, o->cur->image.w, o->cur->image.h);
|
||||||
if (o->engine_data)
|
if (o->engine_data)
|
||||||
|
|
|
@ -1301,7 +1301,7 @@ struct _Evas_Func
|
||||||
void *(*image_size_set) (void *data, void *image, int w, int h);
|
void *(*image_size_set) (void *data, void *image, int w, int h);
|
||||||
void (*image_stride_get) (void *data, void *image, int *stride);
|
void (*image_stride_get) (void *data, void *image, int *stride);
|
||||||
void *(*image_dirty_region) (void *data, void *image, int x, int y, int w, int h);
|
void *(*image_dirty_region) (void *data, void *image, int x, int y, int w, int h);
|
||||||
void *(*image_data_get) (void *data, void *image, int to_write, DATA32 **image_data, int *err);
|
void *(*image_data_get) (void *data, void *image, int to_write, DATA32 **image_data, int *err, Eina_Bool *tofree);
|
||||||
void *(*image_data_put) (void *data, void *image, DATA32 *image_data);
|
void *(*image_data_put) (void *data, void *image, DATA32 *image_data);
|
||||||
void (*image_data_preload_request) (void *data, void *image, const Eo *target);
|
void (*image_data_preload_request) (void *data, void *image, const Eo *target);
|
||||||
void (*image_data_preload_cancel) (void *data, void *image, const Eo *target);
|
void (*image_data_preload_cancel) (void *data, void *image, const Eo *target);
|
||||||
|
|
|
@ -53,8 +53,11 @@ static int _evas_engine_GL_log_dom = -1;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int eng_gl_image_direct_get(void *data EINA_UNUSED, void *image);
|
static int eng_gl_image_direct_get(void *data, void *image);
|
||||||
static int eng_gl_surface_destroy(void *data, void *surface);
|
static int eng_gl_surface_destroy(void *data, void *surface);
|
||||||
|
static Eina_Bool eng_gl_surface_lock(void *data, void *surface);
|
||||||
|
static Eina_Bool eng_gl_surface_unlock(void *data, void *surface);
|
||||||
|
static Eina_Bool eng_gl_surface_read_pixels(void *data, void *surface, int x, int y, int w, int h, Evas_Colorspace cspace, void *pixels);
|
||||||
|
|
||||||
static void
|
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)
|
eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED)
|
||||||
|
@ -573,23 +576,20 @@ eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Evas_GL_Image *
|
static Evas_GL_Image *
|
||||||
_rotate_image_data(void *data, void *img)
|
_rotate_image_data(Render_Engine_GL_Generic *re, Evas_GL_Image *im1)
|
||||||
{
|
{
|
||||||
int alpha;
|
int alpha;
|
||||||
Evas_GL_Image *im1, *im2;
|
Evas_GL_Image *im2;
|
||||||
Evas_Engine_GL_Context *gl_context;
|
Evas_Engine_GL_Context *gl_context;
|
||||||
Render_Engine_GL_Generic *re = data;
|
|
||||||
RGBA_Draw_Context *dc;
|
RGBA_Draw_Context *dc;
|
||||||
DATA32 *pixels;
|
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
re->window_use(re->software.ob);
|
re->window_use(re->software.ob);
|
||||||
gl_context = re->window_gl_context_get(re->software.ob);
|
gl_context = re->window_gl_context_get(re->software.ob);
|
||||||
im1 = img;
|
|
||||||
|
|
||||||
w = im1->w;
|
w = im1->w;
|
||||||
h = im1->h;
|
h = im1->h;
|
||||||
alpha = eng_image_alpha_get(data, img);
|
alpha = eng_image_alpha_get(re, im1);
|
||||||
|
|
||||||
if (im1->orient == EVAS_IMAGE_ORIENT_90 ||
|
if (im1->orient == EVAS_IMAGE_ORIENT_90 ||
|
||||||
im1->orient == EVAS_IMAGE_ORIENT_270 ||
|
im1->orient == EVAS_IMAGE_ORIENT_270 ||
|
||||||
|
@ -614,71 +614,51 @@ _rotate_image_data(void *data, void *img)
|
||||||
0, 0, w, h,
|
0, 0, w, h,
|
||||||
0, 0, im2->w, im2->h,
|
0, 0, im2->w, im2->h,
|
||||||
0);
|
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;
|
gl_context->dc = NULL;
|
||||||
evas_common_draw_context_free(dc);
|
evas_common_draw_context_free(dc);
|
||||||
|
|
||||||
glsym_glBindFramebuffer(GL_FRAMEBUFFER, im2->tex->pt->fb);
|
// flush everything
|
||||||
|
eng_gl_surface_lock(re, im2);
|
||||||
|
|
||||||
// Rely on Evas_GL_Image infrastructure to allocate pixels
|
// Rely on Evas_GL_Image infrastructure to allocate pixels
|
||||||
im2->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
|
im2->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
|
||||||
if (!im2->im) return NULL;
|
if (!im2->im) return NULL;
|
||||||
im2->im->cache_entry.flags.alpha = !!alpha;
|
im2->im->cache_entry.flags.alpha = !!alpha;
|
||||||
evas_gl_common_image_alloc_ensure(im2);
|
evas_gl_common_image_alloc_ensure(im2);
|
||||||
pixels = im2->im->image.data;
|
|
||||||
|
|
||||||
if (im2->tex->pt->format == GL_BGRA)
|
eng_gl_surface_read_pixels(re, im2, 0, 0, im2->w, im2->h,
|
||||||
{
|
EVAS_COLORSPACE_ARGB8888, im2->im->image.data);
|
||||||
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);
|
|
||||||
|
|
||||||
|
eng_gl_surface_unlock(re, im2);
|
||||||
return im2;
|
return im2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
|
eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err, Eina_Bool *tofree)
|
||||||
{
|
{
|
||||||
Render_Engine_GL_Generic *re = data;
|
Render_Engine_GL_Generic *re = data;
|
||||||
Evas_GL_Image *im;
|
Evas_GL_Image *im_new = NULL;
|
||||||
|
Evas_GL_Image *im = image;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
*image_data = NULL;
|
*image_data = NULL;
|
||||||
|
if (tofree) tofree = EINA_FALSE;
|
||||||
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
||||||
|
|
||||||
if (!image)
|
if (!im)
|
||||||
{
|
{
|
||||||
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
im = image;
|
|
||||||
if (im->native.data)
|
|
||||||
{
|
|
||||||
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
|
||||||
return im;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (im->orient != EVAS_IMAGE_ORIENT_NONE)
|
if (im->native.data)
|
||||||
|
return im;
|
||||||
|
|
||||||
|
if (im->im &&
|
||||||
|
im->orient != EVAS_IMAGE_ORIENT_NONE)
|
||||||
{
|
{
|
||||||
Evas_GL_Image *im_new = _rotate_image_data(data, image);
|
im_new = _rotate_image_data(data, image);
|
||||||
if (!im_new)
|
if (!im_new)
|
||||||
{
|
{
|
||||||
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
|
@ -694,13 +674,14 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
re->window_use(re->software.ob);
|
re->window_use(re->software.ob);
|
||||||
|
|
||||||
if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) &&
|
if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) &&
|
||||||
(im->cs.space == EVAS_COLORSPACE_ARGB8888))
|
(im->cs.space == EVAS_COLORSPACE_ARGB8888) &&
|
||||||
|
secsym_tbm_surface_map &&
|
||||||
|
secsym_eglMapImageSEC)
|
||||||
{
|
{
|
||||||
if (im->tex->pt->dyn.checked_out > 0)
|
if (im->tex->pt->dyn.checked_out > 0)
|
||||||
{
|
{
|
||||||
im->tex->pt->dyn.checked_out++;
|
im->tex->pt->dyn.checked_out++;
|
||||||
*image_data = im->tex->pt->dyn.data;
|
*image_data = im->tex->pt->dyn.data;
|
||||||
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
if (im->gc->shared->info.sec_tbm_surface)
|
if (im->gc->shared->info.sec_tbm_surface)
|
||||||
|
@ -734,22 +715,73 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
|
if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
|
||||||
{
|
{
|
||||||
*image_data = im->tex->pt->dyn.data;
|
*image_data = im->tex->pt->dyn.data;
|
||||||
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
|
|
||||||
re->window_use(re->software.ob);
|
re->window_use(re->software.ob);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* use glReadPixels for FBOs (assume fbo > 0) */
|
||||||
|
if (!im->im && im->tex && im->tex->pt && im->tex->pt->fb)
|
||||||
|
{
|
||||||
|
Eina_Bool ok;
|
||||||
|
|
||||||
|
if (to_write)
|
||||||
|
{
|
||||||
|
// This could be implemented, but can't be efficient at all.
|
||||||
|
// Apps should avoid this situation.
|
||||||
|
ERR("Can not retrieve image data from FBO to write it back.");
|
||||||
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tofree)
|
||||||
|
{
|
||||||
|
ERR("FBO image must be freed after image_data_get.");
|
||||||
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = eng_gl_surface_lock(data, im);
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
im_new = evas_gl_common_image_new_from_copied_data
|
||||||
|
(im->gc, im->tex->w, im->tex->h, NULL,
|
||||||
|
eng_image_alpha_get(data, image), EVAS_COLORSPACE_ARGB8888);
|
||||||
|
if (!im_new)
|
||||||
|
{
|
||||||
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = eng_gl_surface_read_pixels
|
||||||
|
(data, im, 0, 0, im_new->w, im_new->h,
|
||||||
|
EVAS_COLORSPACE_ARGB8888, im_new->im->image.data);
|
||||||
|
eng_gl_surface_unlock(data, im);
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*image_data = im_new->im->image.data;
|
||||||
|
if (tofree) *tofree = EINA_TRUE;
|
||||||
|
return im_new;
|
||||||
|
}
|
||||||
|
|
||||||
/* Engine can be fail to create texture after cache drop like eng_image_content_hint_set function,
|
/* Engine can be fail to create texture after cache drop like eng_image_content_hint_set function,
|
||||||
so it is need to add code which check im->im's NULL value*/
|
so it is need to add code which check im->im's NULL value*/
|
||||||
|
|
||||||
if (!im->im)
|
if (!im->im)
|
||||||
{
|
{
|
||||||
*image_data = NULL;
|
// FIXME: Should we create an FBO and draw the texture there, to then read it back?
|
||||||
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
ERR("GL image has no source data, failed to get pixel data");
|
||||||
return NULL;
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
}
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef EVAS_CSERVE2
|
#ifdef EVAS_CSERVE2
|
||||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->im->cache_entry))
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->im->cache_entry))
|
||||||
|
@ -767,8 +799,6 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
{
|
{
|
||||||
if (im->references > 1)
|
if (im->references > 1)
|
||||||
{
|
{
|
||||||
Evas_GL_Image *im_new;
|
|
||||||
|
|
||||||
im_new = evas_gl_common_image_new_from_copied_data
|
im_new = evas_gl_common_image_new_from_copied_data
|
||||||
(im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
|
(im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
|
||||||
im->im->image.data,
|
im->im->image.data,
|
||||||
|
@ -776,7 +806,6 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
eng_image_colorspace_get(data, image));
|
eng_image_colorspace_get(data, image));
|
||||||
if (!im_new)
|
if (!im_new)
|
||||||
{
|
{
|
||||||
*image_data = NULL;
|
|
||||||
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -801,7 +830,6 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
case EVAS_COLORSPACE_ETC1_ALPHA:
|
case EVAS_COLORSPACE_ETC1_ALPHA:
|
||||||
ERR("This image is encoded in ETC1 or ETC2, not returning any data");
|
ERR("This image is encoded in ETC1 or ETC2, not returning any data");
|
||||||
error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
||||||
*image_data = NULL;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
|
@ -1599,7 +1627,7 @@ eng_gl_surface_lock(void *data EINA_UNUSED, void *surface)
|
||||||
{
|
{
|
||||||
Evas_GL_Image *im = surface;
|
Evas_GL_Image *im = surface;
|
||||||
|
|
||||||
if (!im->tex || !im->tex->pt)
|
if (!im || !im->tex || !im->tex->pt)
|
||||||
{
|
{
|
||||||
ERR("Can not lock image that is not a surface!");
|
ERR("Can not lock image that is not a surface!");
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
@ -1625,7 +1653,7 @@ eng_gl_surface_read_pixels(void *data EINA_UNUSED, void *surface,
|
||||||
Evas_Colorspace cspace, void *pixels)
|
Evas_Colorspace cspace, void *pixels)
|
||||||
{
|
{
|
||||||
Evas_GL_Image *im = surface;
|
Evas_GL_Image *im = surface;
|
||||||
GLint fmt = GL_BGRA;
|
GLint fmt = GL_BGRA, fbo = 0;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(pixels, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pixels, EINA_FALSE);
|
||||||
|
@ -1647,7 +1675,9 @@ eng_gl_surface_read_pixels(void *data EINA_UNUSED, void *surface,
|
||||||
* But some devices don't support GL_BGRA, so we still need to convert.
|
* But some devices don't support GL_BGRA, so we still need to convert.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
glsym_glBindFramebuffer(GL_FRAMEBUFFER, im->tex->pt->fb);
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
|
||||||
|
if (fbo != (GLint) im->tex->pt->fb)
|
||||||
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, im->tex->pt->fb);
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||||
|
|
||||||
// With GLX we will try to read BGRA even if the driver reports RGBA
|
// With GLX we will try to read BGRA even if the driver reports RGBA
|
||||||
|
@ -1676,7 +1706,8 @@ eng_gl_surface_read_pixels(void *data EINA_UNUSED, void *surface,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
if (fbo != (GLint) im->tex->pt->fb)
|
||||||
|
glsym_glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1212,17 +1212,20 @@ eng_image_dirty_region(void *data EINA_UNUSED, void *image, int x, int y, int w,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
eng_image_data_get(void *data EINA_UNUSED, void *image, int to_write, DATA32 **image_data, int *err)
|
eng_image_data_get(void *data EINA_UNUSED, void *image, int to_write, DATA32 **image_data, int *err, Eina_Bool *tofree)
|
||||||
{
|
{
|
||||||
RGBA_Image *im;
|
RGBA_Image *im = image;
|
||||||
int error = EVAS_LOAD_ERROR_NONE;
|
int error = EVAS_LOAD_ERROR_NONE;
|
||||||
|
|
||||||
if (!image)
|
*image_data = NULL;
|
||||||
|
if (err) *err = EVAS_LOAD_ERROR_NONE;
|
||||||
|
if (tofree) *tofree = EINA_FALSE;
|
||||||
|
|
||||||
|
if (!im)
|
||||||
{
|
{
|
||||||
*image_data = NULL;
|
if (err) *err = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
im = image;
|
|
||||||
|
|
||||||
#ifdef EVAS_CSERVE2
|
#ifdef EVAS_CSERVE2
|
||||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
||||||
|
@ -1235,7 +1238,7 @@ eng_image_data_get(void *data EINA_UNUSED, void *image, int to_write, DATA32 **i
|
||||||
im = (RGBA_Image *)evas_cache2_image_writable(&im->cache_entry);
|
im = (RGBA_Image *)evas_cache2_image_writable(&im->cache_entry);
|
||||||
if (!im)
|
if (!im)
|
||||||
{
|
{
|
||||||
*image_data = NULL;
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue