Mercurial > MadButterfly
changeset 618:35a67a837a53 openvg
Use reference count to trace life of _ge_openvg_img_t objects
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Thu, 08 Jul 2010 13:51:47 +0800 |
parents | 89fee368e367 |
children | 7020ed3c3e37 |
files | include/mb_graph_engine_openvg.h src/graph_engine_openvg.c |
diffstat | 2 files changed, 119 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/include/mb_graph_engine_openvg.h Thu Jul 08 11:56:30 2010 +0800 +++ b/include/mb_graph_engine_openvg.h Thu Jul 08 13:51:47 2010 +0800 @@ -23,7 +23,6 @@ #define mbe_scaled_font_create(face, fnt_mtx, ctm) ((mbe_scaled_font_t *)NULL) #define mbe_font_face_destroy(face) #define mbe_set_scaled_font(canvas, scaled) -#define mbe_pattern_destroy(pattern) #define mbe_get_scaled_font(canvas) ((mbe_scaled_font_t *)NULL) #define mbe_query_font_face(family, slant, weight) ((mbe_font_face_t *)NULL) #define mbe_free_font_face(face) @@ -120,6 +119,7 @@ * \note This is type is for internal using of OpenVG graphic engine. */ struct _ge_openvg_img { + int ref; VGImage img; mbe_pattern_t *asso_pattern; mbe_surface_t *asso_surface; @@ -153,6 +153,7 @@ grad_stop_t *stops, int stop_cnt); extern mbe_pattern_t *mbe_pattern_create_image(mb_img_data_t *img); +extern void mbe_pattern_destroy(mbe_pattern_t *ptn); extern void mbe_pattern_set_matrix(mbe_pattern_t *ptn, co_aix *mtx); extern void mbe_set_source_rgba(mbe_t *canvas, co_comp_t r, co_comp_t g, co_comp_t b, co_comp_t a); @@ -203,22 +204,7 @@ extern mbe_surface_t *mbe_image_surface_create(mb_img_fmt_t fmt, int w, int h); - -static void -mbe_surface_destroy(mbe_surface_t *surface) { - EGLDisplay display; - - display = _VG_DISPLAY(); - eglDestroySurface(display, surface->surface); - - if(surface->asso_mbe) - surface->asso_mbe->tgt = NULL; - - if(surface->asso_img) - surface->asso_img->asso_surface = NULL; - - free(surface); -} +extern void mbe_surface_destroy(mbe_surface_t *surface); extern mbe_t *mbe_create(mbe_surface_t *surface); extern void mbe_destroy(mbe_t *canvas);
--- a/src/graph_engine_openvg.c Thu Jul 08 11:56:30 2010 +0800 +++ b/src/graph_engine_openvg.c Thu Jul 08 13:51:47 2010 +0800 @@ -26,6 +26,75 @@ (mtx)[8] = 1; \ } while(0) +/*! \brief Convert mb_img_fmt_t to VGImageFormat */ +static VGImageFormat +_mb_ifmt_2_vgifmt(mb_img_fmt_t fmt) { + VGImageFormat vgifmt; + + switch(fmt) { + case MB_IFMT_ARGB32: + vgifmt = VG_sARGB_8888; + break; + + case MB_IFMT_RGB24: + vgifmt = -1; + break; + + case MB_IFMT_A8: + vgifmt = VG_A_8; + break; + + case MB_IFMT_A1: + vgifmt = -1; + break; + + case MB_IFMT_RGB16_565: + vgifmt = VG_sRGB_565; + break; + + default: + return -1; + } + + return vgifmt; +} + +/*! \brief create image object for OpenVG */ +static _ge_openvg_img_t * +_alloc_vgimage(mb_img_fmt_t fmt, int w, int h) { + VGImage vg_img; + VGImageFormat vgifmt; + _ge_openvg_img_t *ge_img; + + vgifmt = _mb_ifmt_2_vgifmt(fmt); + if(vgifmt == -1) + return NULL; + vg_img = vgCreateImage(vgifmt, w, h, + VG_IMAGE_QUALITY_NONANTIALIASED); + if(vg_img == VG_INVALID_HANDLE) + return NULL; + ge_img = O_ALLOC(_ge_openvg_img_t); + if(ge_img == NULL) { + vgDestroyImage(vg_img); + return NULL; + } + ge_img->ref = 1; + ge_img->img = vg_img; + ge_img->asso_pattern = NULL; + ge_img->asso_surface = NULL; + + return ge_img; +} + +/*! \brief Free image object for OpenVG */ +static void +_free_vgimage(_ge_openvg_img_t *ge_img) { + if(--ge_img->ref > 0) + return; + vgDestroyImage(ge_img->img); + free(ge_img); +} + /* * This implementation supports only from image surface. */ @@ -47,6 +116,7 @@ ge_img = surface->asso_img; pattern = O_ALLOC(mbe_pattern_t); pattern->asso_img = ge_img; + ge_img->ref++; /* increase reference count */ pattern->paint = paint; mtx = pattern->mtx; @@ -166,34 +236,25 @@ if(img->fmt != MB_IFMT_ARGB32) return NULL; - /* Create and copy pixels into VGImage */ - vg_img = vgCreateImage(fmt, img->w, img->h, - VG_IMAGE_QUALITY_NONANTIALIASED); - if(vg_img == VG_INVALID_HANDLE) - return NULL; - vgImageSubData(vg_img, img->content, img->stride, fmt, - 0, 0, img->w, img->h); - /* Allocate objects */ - ge_img = O_ALLOC(_ge_openvg_img_t); + ge_img = _alloc_vgimage(MB_IFMT_ARGB32, img->w, img->h); pattern = O_ALLOC(mbe_pattern_t); paint = vgCreatePaint(); if(ge_img == NULL || pattern == NULL || paint == VG_INVALID_HANDLE) goto err; - - - /* Initialize objects */ - ge_img->img = vg_img; - ge_img->asso_pattern = NULL; - ge_img->asso_surface = NULL; - + + /* Create and copy pixels into VGImage */ + vg_img = ge_img->img; + vgImageSubData(vg_img, img->content, img->stride, fmt, + 0, 0, img->w, img->h); + pattern->paint = paint; pattern->asso_img = ge_img; return pattern; err: - if(ge_img) free(ge_img); + if(ge_img) _free_vgimage(ge_img); if(pattern) free(pattern); if(paint != VG_INVALID_HANDLE) vgDestroyPaint(paint); vgDestroyImage(vg_img); @@ -201,6 +262,12 @@ } void +mbe_pattern_destroy(mbe_pattern_t *ptn) { + if(ptn->asso_img) { + } +} + +void mbe_pattern_set_matrix(mbe_pattern_t *ptn, co_aix *mtx) { co_aix rev[6]; @@ -443,6 +510,7 @@ EGLDisplay display; EGLConfig config; EGLint attrib_list[5]; + _ge_openvg_img_t *ge_img; mbe_surface_t *mbe_surface; int r; @@ -450,7 +518,11 @@ r = _openvg_find_config(fmt, w, h, &config); if(r != 0) return NULL; - + + ge_img = _alloc_vgimage(fmt, w, h); + if(ge_img == NULL) + return NULL; + display = _VG_DISPLAY(); attrib_list[0] = EGL_WIDTH; attrib_list[1] = w; @@ -460,23 +532,47 @@ /* Some implementation does not support pbuffer. * We need use some other surface to replace this one. */ - surface = eglCreatePbufferSurface(display, config, attrib_list); - if(surface == EGL_NO_SURFACE) + surface = eglCreatePbufferFromClientBuffer(display, EGL_OPENVG_IMAGE, + (EGLClientBuffer)ge_img->img, + config, attrib_list); + if(surface == EGL_NO_SURFACE) { + _free_vgimage(ge_img); return NULL; + } mbe_surface = O_ALLOC(mbe_surface_t); if(mbe_surface == NULL) { + _free_vgimage(ge_img); eglDestroySurface(display, surface); return NULL; } mbe_surface->surface = surface; mbe_surface->asso_mbe = NULL; + mbe_surface->asso_img = ge_img; mbe_surface->w = w; mbe_surface->h = h; return mbe_surface; } +void +mbe_surface_destroy(mbe_surface_t *surface) { + EGLDisplay display; + + display = _VG_DISPLAY(); + eglDestroySurface(display, surface->surface); + + if(surface->asso_mbe) + surface->asso_mbe->tgt = NULL; + + if(surface->asso_img) { + surface->asso_img->asso_surface = NULL; + _free_vgimage(surface->asso_img); + } + + free(surface); +} + mbe_t * mbe_create(mbe_surface_t *surface) { EGLDisplay display;