From: Jiyoun Park <jy0703.park@samsung.com>
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 25 Aug 2011 04:48:45 +0000 (04:48 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 25 Aug 2011 04:48:45 +0000 (04:48 +0000)
Subject: [E-devel] [Patch] evas gl engine's texture creation

Hello.

1. _pool_tex_dynamic_new function, it didn\92t set pt to NULL when secsym_eglCreateImage function failed.
In this case, it returns wrong pt pointer and it has possibility to make crash.
So I add free pt code and return NULL code into _pool_tex_dynamic_new function.

2. I modified eng_image_data_get of gl engine.

If Evas_GL_Image's texture creation failed and evas_gl_image's cache image was droped,
Im->im can be NULL. So I add check code.
Example: evas_gl_common_image_content_hint_set
     1) EVAS_IMAGE_CONTENT_HINT_DYNAMIC , it drop cache image
     2) if evas_gl_common_texture_dynamic_new failed
     3) then, im->im =NULL, im->tex=NULL
        In this situation, if application call's evas_object_image_data_get function,
It make crash in evas_cache_image_load_data function.

3. I think function's related with evas_object's engine data have to be return NULL if it failed.
If function's returns null, evas object code can handle error more easily.
But evas object's code was implemented differently each case. Does my suggestion right?
I add engine data null check code to evas_object_image based on upper consumtion.
If it is wrong , the patch code related with evas object image have to be removed.
If it is right , I will survey other evas object type also.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@62775 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/canvas/evas_object_image.c
src/modules/engines/gl_common/evas_gl_texture.c
src/modules/engines/gl_x11/evas_engine.c

index c06fbbc..937a0c4 100644 (file)
@@ -965,6 +965,10 @@ evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing)
                                                                  for_writing,
                                                                  &data,
                                                                   &o->load_error);
+
+   /* if we fail to get engine_data, we have to return NULL */
+   if (!o->engine_data) return NULL;
+
    if (o->engine_data)
      {
         int stride = 0;
index c0b3f56..0a3bc82 100644 (file)
@@ -524,73 +524,37 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
                                        0, attr);
    if (!pt->dyn.img)
      {
+        glBindTexture(GL_TEXTURE_2D, 0);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        return pt;
+        glDeleteTextures(1, &(pt->texture));
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        free(pt);
+        return NULL;
      }
    if (secsym_eglGetImageAttribSEC(egldisplay,
                                    pt->dyn.img,
                                    EGL_MAP_GL_TEXTURE_WIDTH_SEC,
-                                   &(pt->dyn.w)) != EGL_TRUE)
-     {
-        secsym_eglDestroyImage(egldisplay, pt->dyn.img);
-        pt->dyn.img = NULL;
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        return pt;
-     }
+                                   &(pt->dyn.w)) != EGL_TRUE) goto error;
    if (secsym_eglGetImageAttribSEC(egldisplay,
                                    pt->dyn.img,
                                    EGL_MAP_GL_TEXTURE_HEIGHT_SEC,
-                                   &(pt->dyn.h)) != EGL_TRUE)
-     {
-        secsym_eglDestroyImage(egldisplay, pt->dyn.img);
-        pt->dyn.img = NULL;
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        return pt;
-     }
+                                   &(pt->dyn.h)) != EGL_TRUE) goto error;
    if (secsym_eglGetImageAttribSEC(egldisplay,
                                    pt->dyn.img,
                                    EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC,
-                                   &(pt->dyn.stride)) != EGL_TRUE)
-     {
-        secsym_eglDestroyImage(egldisplay, pt->dyn.img);
-        pt->dyn.img = NULL;
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        return pt;
-     }
+                                   &(pt->dyn.stride)) != EGL_TRUE) goto error;
    if (secsym_eglGetImageAttribSEC(egldisplay,
                                    pt->dyn.img,
                                    EGL_MAP_GL_TEXTURE_FORMAT_SEC,
-                                   &(fmt)) != EGL_TRUE)
-     {
-        secsym_eglDestroyImage(egldisplay, pt->dyn.img);
-        pt->dyn.img = NULL;
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        return pt;
-     }
-   if (fmt != EGL_MAP_GL_TEXTURE_RGBA_SEC)
-     {
-        secsym_eglDestroyImage(egldisplay, pt->dyn.img);
-        pt->dyn.img = NULL;
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        return pt;
-     }
+                                   &(fmt)) != EGL_TRUE) goto error;
+   if (fmt != EGL_MAP_GL_TEXTURE_RGBA_SEC) goto error;
+
    if (secsym_eglGetImageAttribSEC(egldisplay,
                                    pt->dyn.img,
                                    EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC,
-                                   &(pixtype)) != EGL_TRUE)
-     {
-        secsym_eglDestroyImage(egldisplay, pt->dyn.img);
-        pt->dyn.img = NULL;
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        return pt;
-     }
-   if (pixtype != EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC)
-     {
-        secsym_eglDestroyImage(egldisplay, pt->dyn.img);
-        pt->dyn.img = NULL;
-        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        return pt;
-     }
+                                   &(pixtype)) != EGL_TRUE) goto error;
+
+   if (pixtype != EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC) goto error;
 
    glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -602,6 +566,19 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
    format = 0;
 #endif
    return pt;
+
+/* ERROR HANDLING */
+error:
+  secsym_eglDestroyImage(egldisplay, pt->dyn.img);
+  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+  pt->dyn.img = NULL;
+
+  glBindTexture(GL_TEXTURE_2D, 0);
+  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+  glDeleteTextures(1, &(pt->texture));
+  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+  free(pt);
+  return NULL;
 }
 
 void
index edde055..d766aac 100644 (file)
@@ -1797,6 +1797,16 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
    eng_window_use(re->win);
 #endif
 
+   /* 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*/ 
+
+   if (!im->im)
+    {
+       *image_data = NULL;
+       if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+       return NULL;
+    }
+
    error = evas_cache_image_load_data(&im->im->cache_entry);
    switch (im->cs.space)
      {
@@ -1816,7 +1826,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
                    {
                       *image_data = NULL;
                        if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
-                      return im;
+                      return NULL;
                    }
                  evas_gl_common_image_free(im);
                  im = im_new;