Mercurial > MadButterfly
changeset 619:7020ed3c3e37 openvg
Actiavte a VGImage before using a pattern paint or image surface.
- A VGImage can only activated for a pattern or an image in any instance.
- _ge_openvg_img trace the object activated for currently and its
deactivation function.
- everytime a pattern paint or image surface will be used, the
current activated one will be deactivated, and activate a new one.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Thu, 08 Jul 2010 18:44:26 +0800 |
parents | 35a67a837a53 |
children | 3f544e876939 |
files | include/mb_graph_engine_openvg.h src/graph_engine_openvg.c |
diffstat | 2 files changed, 111 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/include/mb_graph_engine_openvg.h Thu Jul 08 13:51:47 2010 +0800 +++ b/include/mb_graph_engine_openvg.h Thu Jul 08 18:44:26 2010 +0800 @@ -110,10 +110,16 @@ * used to make sure previous associated pattern or surface being * released before new association. * - * Functions must release assocation specified by - * _ge_openvg_img::asso_pattern or _ge_openvg_img::asso_surface before - * new association, and record new association as one of thes two - * vairables. + * A _ge_openvg_img can be associated by mutltiple patterns and + * surfaces. But, at most one of associated patterns or surfaces, the + * _ge_openvg_img can be activated for at any instant. + * _ge_openvg_img::activated_for trace the object it being activated + * for. When a context will be current, the _ge_openvg_img associated + * with its surface would be activated for the surface. When a paint + * wil be used, the _ge_openvg_img associated must be activated for + * the paint. Before activated, the old activation must be + * deactivated. _ge_openvg_img::deactivate_func is a pointer to + * deactivation function of activated pattern or surface. * * \sa _ge_openvg_img_t * \note This is type is for internal using of OpenVG graphic engine. @@ -121,8 +127,8 @@ struct _ge_openvg_img { int ref; VGImage img; - mbe_pattern_t *asso_pattern; - mbe_surface_t *asso_surface; + void *activated_for; + void (*deactivate_func)(void *obj); }; #define MB_MATRIX_2_OPENVG(vgmtx, mtx) do { \ @@ -140,6 +146,8 @@ extern EGLNativeDisplayType _ge_openvg_disp_id; extern mbe_t *_ge_openvg_current_canvas; extern void _mbe_load_pattern_mtx(VGfloat *mtx1, VGfloat *mtx2, int mode); +extern void _ge_vg_img_activate_for_pattern(mbe_pattern_t *ptn); +extern void _ge_vg_img_activate_for_surface(mbe_surface_t *surf); extern mbe_pattern_t *mbe_pattern_create_for_surface(mbe_surface_t *surface); extern mbe_pattern_t *mbe_pattern_create_radial(co_aix cx0, co_aix cy0, @@ -175,12 +183,20 @@ (canvas)->tgt->surface, \ (canvas)->ctx); \ } \ + /* \sa _ge_openvg_img_t */ \ + _ge_vg_img_activate_for_surface((canvas)->tgt); \ } while(0) /* TODO: switch VGImage between VGPaint and surface. */ #define _MK_CURRENT_PAINT(canvas) \ - if((canvas)->paint_installed) { \ - vgSetPaint((canvas)->paint, VG_FILL_PATH|VG_STROKE_PATH); \ - } + do { \ + if((canvas)->paint_installed == 0) { \ + vgSetPaint((canvas)->paint, VG_FILL_PATH|VG_STROKE_PATH); \ + (canvas)->paint_installed = 1; \ + } \ + /* \sa _ge_openvg_img_t */ \ + if((canvas)->src) \ + _ge_vg_img_activate_for_pattern((canvas)->src); \ + } while(0) #define mbe_transform(canvas, _mtx) \ do { \
--- a/src/graph_engine_openvg.c Thu Jul 08 13:51:47 2010 +0800 +++ b/src/graph_engine_openvg.c Thu Jul 08 18:44:26 2010 +0800 @@ -80,8 +80,8 @@ } ge_img->ref = 1; ge_img->img = vg_img; - ge_img->asso_pattern = NULL; - ge_img->asso_surface = NULL; + ge_img->activated_for = NULL; + ge_img->deactivate_func = NULL; return ge_img; } @@ -89,12 +89,89 @@ /*! \brief Free image object for OpenVG */ static void _free_vgimage(_ge_openvg_img_t *ge_img) { - if(--ge_img->ref > 0) + if(--ge_img->ref > 0) { + if(ge_img->activated_for) { + ge_img->deactivate_func(ge_img->activated_for); + ge_img->activated_for = NULL; + } return; + } + vgDestroyImage(ge_img->img); free(ge_img); } +static void +_ge_vg_img_deactivate_for_pattern(void *obj) { + mbe_pattern_t *ptn = (mbe_pattern_t *)obj; + VGPaint vg_paint; + + vg_paint = ptn->paint; + vgPaintPattern(vg_paint, VG_INVALID_HANDLE); +} + +/*! \brief Activate a VGImage for a pattern paint. + * + * \sa _ge_openvg_img + */ +void +_ge_vg_img_activate_for_pattern(mbe_pattern_t *ptn) { + _ge_openvg_img_t *ge_img; + VGPaint vg_paint; + VGImage vg_img; + + ge_img = ptn->asso_img; + if(ge_img == NULL) + return; + + if(ge_img->activated_for == (void *)ptn) + return; + + if(ge_img->activated_for) + ge_img->deactivate_func(ge_img->activated_for); + + ge_img->activated_for = ptn; + ge_img->deactivate_func = _ge_vg_img_deactivate_for_pattern; + + vg_img = ge_img->img; + vg_paint = ptn->paint; + + vgPaintPattern(vg_paint, vg_img); +} + +/*! \brief Deactivate a VGImage for a VGSurface. + * + * A VGImage can not deatached from VGSurface. But, it is not clear + * in the document of EGL. We assume that a VGImage can be used as + * pattern of a paint, once associated surface is not current + * rendering context. + */ +static void +_ge_vg_img_deactivate_for_surface(void *obj) { +} + +/*! \brief Activate a VGImage for a surface + * + * \sa _ge_openvg_img + */ +void +_ge_vg_img_activate_for_surface(mbe_surface_t *surf) { + _ge_openvg_img_t *ge_img; + + ge_img = surf->asso_img; + if(ge_img == NULL) + return; + + if(ge_img->activated_for == (void *)surf) + return; + + if(ge_img->activated_for) + ge_img->deactivate_func(ge_img->activated_for); + + ge_img->activated_for = surf; + ge_img->deactivate_func = _ge_vg_img_deactivate_for_surface; +} + /* * This implementation supports only from image surface. */ @@ -263,8 +340,10 @@ void mbe_pattern_destroy(mbe_pattern_t *ptn) { - if(ptn->asso_img) { - } + if(ptn->asso_img) + _free_vgimage(ptn->asso_img); + vgDestroyPaint(ptn->paint); + free(ptn); } void @@ -498,6 +577,7 @@ } surface->surface = egl_surface; + surface->asso_img = NULL; return surface; } @@ -565,10 +645,8 @@ if(surface->asso_mbe) surface->asso_mbe->tgt = NULL; - if(surface->asso_img) { - surface->asso_img->asso_surface = NULL; + if(surface->asso_img) _free_vgimage(surface->asso_img); - } free(surface); }