Mercurial > MadButterfly
changeset 1067:7b4e80ab671a openvg
merge from default branch
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Wed, 01 Dec 2010 12:25:56 +0800 |
parents | bd18951b51d5 (diff) 292fbb86d8f3 (current diff) |
children | aed05ad5102d |
files | configure.ac examples/calculator/Makefile.am include/mb_basic_types.h include/mb_config.h.in include/mb_graph_engine.h include/mb_graph_engine_cairo.h include/mb_graph_engine_skia.h include/mb_types.h nodejs/X_supp_njs.c nodejs/X_supp_njs.h nodejs/testcase.js src/Makefile.am src/X_supp.c src/dfb_supp.c src/event.c src/graph_engine_cairo.c src/graph_engine_dfb.c src/graph_engine_skia.cpp src/img_ldr.c src/img_ldr_imlib2.c src/paint.c src/redraw_man.c |
diffstat | 10 files changed, 1496 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.ac Tue Nov 30 03:57:36 2010 +0800 +++ b/configure.ac Wed Dec 01 12:25:56 2010 +0800 @@ -26,6 +26,12 @@ AC_TYPE_UINT32_T AC_TYPE_UINT64_T +# Explicit initialize pkg-config for conditional PKG_CHECK_MODULE +# see http://www.flameeyes.eu/autotools-mythbuster/autoconf/macros.html +# and http://www.flameeyes.eu/autotools-mythbuster/ \ +# pkgconfig/pkg_check_modules.html +PKG_PROG_PKG_CONFIG + # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC @@ -64,23 +70,48 @@ AC_DEFINE([SH_STEXT]) [fi] +AC_ARG_ENABLE([mbaf], + [ --disable-mbaf Turn off mbaf], +[case "${enableval}" in + yes) mbaf=true ;; + no) mbaf=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --disable-mbaf]) ;; +esac],[mbaf=true]) + AC_ARG_WITH([backend], [AS_HELP_STRING([--with-backend=FOO],[Use FOO as display backend (default is 'X')])], [case "${withval}" in - ('X') backend='X' ;; - ('dfb') backend='dfb' ;; - ('no') backend='none' ;; + ('X') backend='X'; default_graphic_engine="cairo" ;; + ('dfb') backend='dfb'; default_graphic_engine="dfb" ;; + ('no') backend='none'; default_graphic_engine="cairo" ;; (*) AC_MSG_ERROR([bad value ${withval} for --with-backend]) ;; - esac],[backend='X']) + esac],[backend='X'; default_graphic_engine="cairo"]) -AC_ARG_ENABLE([skia], - [AS_HELP_STRING([--enable-skia],[Turn on Skia instead of Cairo])], - [case "${enableval}" in - (yes) skia=true ;; - (no) skia=false ;; - (*) AC_MSG_ERROR([bad value ${enableval} for --enable-skia]) ;; - esac],[skia=false]) +AC_ARG_WITH([graphic-engine], + [AS_HELP_STRING([--with-graphic-engine=FOO], + [Use FOO as graphic engine (default is '${default_graphic_engine}')])], + [case "${withval}" in + ('cairo') graphic_engine="cairo" ;; + ('skia') graphic_engine="skia" ;; + ('openvg') graphic_engine="openvg" ;; + ('dfb') graphic_engine="dfb" ;; + (*) AC_MSG_ERROR([bad value ${withval} for --with-graphic-engine]) + ;; + esac], [graphic_engine="${default_graphic_engine}"]) +AC_ARG_WITH([image-loader], + [AS_HELP_STRING([--with-image-loader=FOO], + [Use FOO as image loader (default is 'cairo')])], + [case "${withval}" in + ('cairo') image_loader="cairo" ;; + ('imlib2') image_loader="imlib2" ;; + ('no') image_loader="none" ;; + (*) AC_MSG_ERROR([bad value ${withval} for --with-image-loader]) + ;; + esac], [image_loader="cairo"]) + +xshm=false +[if [ x"${backend}" = x"X" ]; then ] AC_ARG_ENABLE([xshm], [AS_HELP_STRING([--disable-xshm],[Turn off XSHM supporting])], [case "${enableval}" in @@ -88,18 +119,24 @@ (no) xshm=false ;; (*) AC_MSG_ERROR([bad value ${enableval} for --disable-xshm]) ;; esac], [xshm=true]) - -AM_CONDITIONAL([SKIA_GRAPH_ENGINE], [test x$skia = xtrue]) -AM_CONDITIONAL([CAIRO_GRAPH_ENGINE], [test x$skia != xtrue]) +[fi] -[if [ x"${skia}" = xtrue ]; then ] +[if [ x"${graphic_engine}" = x"skia" ]; then ] AC_DEFINE([SKIA_GRAPH_ENGINE]) - cairo=false +[elif [ x"${graphic_engine}" = x"openvg" ]; then ] + AC_DEFINE([OPENVG_GRAPH_ENGINE]) +[elif [ x"${graphic_engine}" = x"dfb" ]; then ] + AC_DEFINE([DFB_GRAPH_ENGINE]) [else] AC_DEFINE([CAIRO_GRAPH_ENGINE]) - cairo=true [fi] +AM_CONDITIONAL([SKIA_GRAPH_ENGINE], [test x"${graphic_engine}" = x"skia"]) +AM_CONDITIONAL([OPENVG_GRAPH_ENGINE], [test x"${graphic_engine}" = x"openvg"]) +AM_CONDITIONAL([DFB_GRAPH_ENGINE], [test x"${graphic_engine}" = x"dfb"]) +AM_CONDITIONAL([CAIRO_GRAPH_ENGINE], [test x"${graphic_engine}" = x"cairo"]) +AM_CONDITIONAL([MBAF], [test x"$mbaf" = xtrue]) + AC_ARG_ENABLE([nodejs], [AS_HELP_STRING([--enable-nodejs],[Turn on nodejs support])], [case "${enableval}" in @@ -117,35 +154,63 @@ # Define AM and AC variable for sh_text -AM_CONDITIONAL([SH_TEXT], [test x$sh_text = xtrue -a x$cairo = xtrue]) +AM_CONDITIONAL([SH_TEXT], + [test x$sh_text = xtrue -a x"${graphic_engine}" = x"cairo"]) -[if [ x"${sh_text}" = xtrue -a x$cairo = xtrue ]; then] +[if [ x"${sh_text}" = xtrue -a x"${graphic_engine}" = x"cairo" ]; then] AC_DEFINE([SH_TEXT]) [fi] # Define AM and AC variable for display backend -AM_CONDITIONAL([X_BACKEND], [test x$backend = x'X' -a x$cairo = xtrue]) +AM_CONDITIONAL([X_BACKEND], + [test x$backend = x'X' -a x"${graphic_engine}" = x"cairo"]) -[if [ x"${backend}" = x'X' -a x"${cairo}" = xtrue ]; then] +[if [ x"${backend}" = x'X' -a x"${graphic_engine}" = x"cairo" ]; then] AC_DEFINE([X_BACKEND]) [fi] -AM_CONDITIONAL([DFB_BACKEND], [test x$backend = x'dfb' -a x$cairo = xtrue]) +AM_CONDITIONAL([DFB_BACKEND], + [test x$backend = x'dfb' -a x"${graphic_engine}" = x"cairo"]) -[if [ x"${backend}" = x'dfb' -a x"${cairo}" = xtrue ]; then] +[if [ x"${backend}" = x'dfb' -a x"${graphic_engine}" = x"cairo" ]; then] AC_DEFINE([DFB_BACKEND]) [fi] -AM_CONDITIONAL([XSHM], [test x"${xshm}" = xtrue -a x"${cairo}" = xtrue -a x$backend = x'X']) +AM_CONDITIONAL([CAIRO_IMG_LOADER], + [test x"${image_loader}" = x"cairo"]) + +[if [ x"${image_loader}" = x"cairo" ]; then] + AC_DEFINE([CAIRO_IMG_LOADER]) + [if [ x"${graphic_engine}" != x"cairo" ]; then] + AC_MSG_ERROR([bad value cairo for --with-image-loader while value of --with-graphic-engine is not cairo]) + [fi] +[fi] -[if [ x"${xshm}" = xtrue -a x"${cairo}" = xtrue -a x$backend = x'X' ]; then] +AM_CONDITIONAL([IMLIB2_IMG_LOADER], + [test x"${image_loader}" = x"imlib2"]) + +[if [ x"${image_loader}" = x"imlib2" ]; then] + AC_DEFINE([IMLIB2_IMG_LOADER]) +[fi] + +AM_CONDITIONAL([XSHM], + [test x"${xshm}" = xtrue -a x"${graphic_engine}" = x"cairo" -a x$backend = x'X']) + +[if [ x"${xshm}" = xtrue -a x"${graphic_engine}" = x"cairo" -a x$backend = x'X' ]; then] AC_DEFINE([XSHM]) [fi] # Checks for libraries. +[if [ x"${graphic_engine}" = x"openvg" ]; then] +AC_CHECK_HEADERS([GL/glut.h],, [AC_MSG_ERROR([can not find GL/glut.h])]) +[fi] -[if [ x"${cairo}" = xtrue ]; then] +[if [ x"${image_loader}" = x"imlib2" ]; then] +PKG_CHECK_MODULES([imlib2], [imlib2 >= 1.4.1], , AC_MSG_ERROR([imlib2 >= 1.4.1 not found])) +[fi] + +[if [ x"${graphic_engine}" = x"cairo" ]; then] PKG_CHECK_MODULES([cairo], [cairo >= 1.6], , AC_MSG_ERROR([cairo >= 1.6 not found])) #PKG_CHECK_MODULES([cairo2], [cairo2 >= 2.0], , AC_MSG_ERROR([cairo2 >= 2.0 not found])) [if [ x"${sh_text}" = xtrue ]; then] @@ -174,7 +239,11 @@ AH_TEMPLATE([SH_TEXT],[Enable sh_text object]) AH_TEMPLATE([SH_STEXT],[Enable sh_stext object]) AH_TEMPLATE([SKIA_GRAPH_ENGINE], [Enable Skia Graphic Engine]) +AH_TEMPLATE([OPENVG_GRAPH_ENGINE], [Enable OpenVG Graphic Engine]) AH_TEMPLATE([CAIRO_GRAPH_ENGINE], [Enable Cairo Graphic Engine]) +AH_TEMPLATE([DFB_GRAPH_ENGINE], [Enable DirectFB Graphic Engine]) +AH_TEMPLATE([CAIRO_IMG_LOADER], [Enable Cairo Image Loader]) +AH_TEMPLATE([IMLIB2_IMG_LOADER], [Enable Imlib2 Image Loader]) AH_TEMPLATE([X_BACKEND], [Enable X backend]) AH_TEMPLATE([DFB_BACKEND], [Enable DirectFB backend]) AH_TEMPLATE([XSHM], [Enable XSHM])
--- a/examples/menu/filebrowser.c Tue Nov 30 03:57:36 2010 +0800 +++ b/examples/menu/filebrowser.c Wed Dec 01 12:25:56 2010 +0800 @@ -51,14 +51,14 @@ if (strcmp(data->titles[select],"..")==0) { strcpy(path, data->curDir); len = strlen(path); - for(i=len-1;i>0;i--) { + for(i=len-2;i>0;i--) { if (path[i] == '/') { path[i] = 0; break; } } } else { - snprintf(path,1024,"%s/%s", data->curDir,data->titles[select]); + snprintf(path,1024,"%s%s", data->curDir,data->titles[select]); } MyApp_fillDirInfo(app, path); @@ -112,7 +112,8 @@ printf("check %s\n",s); - if (endWith(s,".png")) { + if (endWith(s,".png") || endWith(s, ".jpg") || + endWith(s, ".PNG") || endWith(s, ".JPG")) { snprintf(path,1024,"%s%s", data->curDir,data->titles[select]); mypreview(data,path); } @@ -146,6 +147,8 @@ DIR *dir; struct dirent *e; struct fileinfo *f; + char *path; + int sz; int i; dir = opendir(curdir); @@ -156,7 +159,14 @@ if (data->curDir) free(data->curDir); - data->curDir = strdup(curdir); + + sz = strlen(curdir); + if(curdir[sz - 1] != '/') + sz++; + data->curDir = (char *)malloc(sz + 1); + strcpy(data->curDir, curdir); + if(curdir[sz - 1] == '\0') + strcat(data->curDir, "/"); if (data->files) { for(i=0;i<data->nFiles;i++) {
--- a/include/mb_config.h.in Tue Nov 30 03:57:36 2010 +0800 +++ b/include/mb_config.h.in Wed Dec 01 12:25:56 2010 +0800 @@ -9,6 +9,18 @@ /* Enable Skia Graphic Engine */ #undef SKIA_GRAPH_ENGINE +/* Enable OpenVG Graphic Engine */ +#undef OPENVG_GRAPH_ENGINE + +/* Enable DirectFB Graphic Engine */ +#undef DFB_GRAPH_ENGINE + +/* Enable Cairo Image Loader */ +#undef CAIRO_IMG_LOADER + +/* Enable Imlib2 Image Loader */ +#undef IMLIB2_IMG_LOADER + /* Enable sh_text */ #undef SH_TEXT
--- a/include/mb_graph_engine.h Tue Nov 30 03:57:36 2010 +0800 +++ b/include/mb_graph_engine.h Wed Dec 01 12:25:56 2010 +0800 @@ -1,3 +1,15 @@ +/*! \page create_graph_engine Create a Graphic Engine. + * + * To create a graphic engine, you need to declare and define types + * and functions that had been declared in + * include/mb_graph_engine_cairo.h in a separated header an c file. + * Likes what mb_graph_engine_skia.h does. + * + * You should also add options in configure.ac to enable the graphic + * engine. You also need to add lines in include/mb_config.h.in and + * include/mb_graph_engine.h to include correct header for the graphic + * engine enabled by the user. + */ // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- // vim: sw=4:ts=8:sts=4 #ifndef __MBE_H_ @@ -12,4 +24,8 @@ #include <mb_graph_engine_skia.h> #endif +#ifdef OPENVG_GRAPH_ENGINE +#include <mb_graph_engine_openvg.h> +#endif + #endif /* __MBE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mb_graph_engine_dummy.h Wed Dec 01 12:25:56 2010 +0800 @@ -0,0 +1,99 @@ +/* This is a dummy Graphic Engine to consume all graphic operators. + */ +#ifndef __MB_GE_OPENVG_H_ +#define __MB_GE_OPENVG_H_ + +#include <stdio.h> +#include <GL/glut.h> +#include "mb_basic_types.h" +#include "mb_img_ldr.h" + +/*! \defgroup mb_ge_dummy Dummy Implementation of MadButterfly Graphic Engine + * @{ + */ +#define mbe_pattern_create_for_surface(surface) ((mbe_pattern_t *)NULL) +#define mbe_scaled_font_text_extents(scaled, utf8, extents) +#define mbe_image_surface_get_stride(surface) (20) +#define mbe_image_surface_get_format(surface) ((mb_img_fmt_t)0) +#define mbe_image_surface_get_height(surface) (1) +#define mbe_image_surface_get_width(surface) (1) +#define mbe_image_surface_get_data(surface) ((unsigned char *)NULL) +#define mbe_scaled_font_reference(scaled) ((mbe_scaled_font_t *)NULL) +/* For OpenVG backend, never invoke xlib surface. + * #define mbe_xlib_surface_create cairo_xlib_surface_create + */ +#define mbe_pattern_create_radial(cx0, cy0, radius0, \ + cx1, cy1, radius1, stops, stop_cnt) \ + ((mbe_pattern_t *)NULL) +#define mbe_pattern_create_linear(x0, y0, x1, y1, stops, stop_cnt) \ + ((mbe_pattern_t *)NULL) +#define mbe_pattern_create_image(img) ((mbe_pattern_t *)NULL) +#define mbe_image_surface_create(fmt, w, h) ((mbe_surface_t *)NULL) +#define mbe_scaled_font_destroy(scaled) +#define mbe_font_face_reference(face) ((mbe_font_face_t *)NULL) +#define mbe_scaled_font_create(face, fnt_mtx, ctm) ((mbe_scaled_font_t *)NULL) +#define mbe_pattern_set_matrix(ptn, mtx) +#define mbe_font_face_destroy(face) +#define mbe_paint_with_alpha(canvas, alpha) +#define mbe_surface_destroy(surface) +#define mbe_set_source_rgba(canvas, r, g, b, a) +#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) +#define mbe_set_line_width(canvas, w) +#define mbe_set_source_rgb(canvas, r, g, b) +#define mbe_get_font_face(canvas) ((mbe_font_face_t *)NULL) +#define mbe_fill_preserve(canvas) +#define mbe_copy_source(src_canvas, dst_canvas) +#define mbe_set_source(canvas, pattern) +#define mbe_reset_scissoring(canvas) +#define mbe_get_target(canvas) ((mbe_surface_t *)NULL) +#define mbe_close_path(canvas) +#define mbe_text_path(canvas, utf8) +#define mbe_transform(canvas, mtx) +#define mbe_rectangle(canvas, x, y, w, h) +#define mbe_in_stroke(canvas, x, y) (0) +#define mbe_new_path(canvas) +#define mbe_curve_to(canvas, x1, y1, x2, y2, x3, y3) +#define mbe_restore(canvas) +#define mbe_move_to(canvas, x, y) +#define mbe_line_to(canvas, x, y) +#define mbe_in_fill(canvas, x, y) (0) +#define mbe_destroy(canvas) +#define mbe_stroke(canvas) +#define mbe_create(surface) ((mbe_t *)NULL) +#define mbe_clear(canvas) +#define mbe_paint(canvas) +#define mbe_save(canvas) +#define mbe_fill(canvas) +/*! \brief Make scissoring rectangles. + * + * It would reset all previous pathes. + */ +#define mbe_scissoring(canvas, n_areas, areas) +#define mbe_arc(canvas, x, y, radius, angle_start, angle_stop) + +/*! \brief Initialize graphic engine */ +#define mbe_init() + +typedef struct _mbe_text_extents_t mbe_text_extents_t; +typedef int mbe_scaled_font_t; +typedef int mbe_font_face_t; +typedef int mbe_surface_t; +typedef int mbe_pattern_t; +typedef int mbe_t; + +struct _mbe_text_extents_t { + co_aix x_bearing; + co_aix y_bearing; + co_aix width; + co_aix height; + co_aix x_advance; + co_aix y_advance; +}; + +/* @} */ + +#endif /* __MB_GE_OPENVG_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mb_graph_engine_openvg.h Wed Dec 01 12:25:56 2010 +0800 @@ -0,0 +1,279 @@ +#ifndef __MB_GE_OPENVG_H_ +#define __MB_GE_OPENVG_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <EGL/egl.h> +#include <VG/openvg.h> +#include "mb_basic_types.h" +#include "mb_img_ldr.h" + +/*! \defgroup mb_ge_openvg MadButterfly Graphic Engine with OpenVG + * @{ + */ +#define mbe_scaled_font_text_extents(scaled, utf8, extents) +#define mbe_image_surface_get_stride(surface) (20) +#define mbe_image_surface_get_format(surface) ((mb_img_fmt_t)0) +#define mbe_image_surface_get_height(surface) (surface)->h +#define mbe_image_surface_get_width(surface) (surface)->w +#define mbe_image_surface_get_data(surface) ((unsigned char *)NULL) +#define mbe_scaled_font_reference(scaled) ((mbe_scaled_font_t *)NULL) +#define mbe_scaled_font_destroy(scaled) +#define mbe_font_face_reference(face) ((mbe_font_face_t *)NULL) +#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_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) +#define mbe_set_line_width(canvas, w) \ + do { \ + _MK_CURRENT_CTX(canvas); \ + vgSetf(VG_STROKE_LINE_WIDTH, w); \ + } while(0) +#define mbe_set_source_rgb(canvas, r, g, b) \ + mbe_set_source_rgba(canvas, r, g, b, 1) +#define mbe_get_font_face(canvas) ((mbe_font_face_t *)NULL) +#define mbe_set_source(canvas, pattern) \ + do { \ + (canvas)->src = (pattern); \ + (canvas)->paint = (pattern)->paint; \ + (canvas)->paint_installed = 0; \ + } while(0) +#define mbe_reset_scissoring(canvas) \ + do { \ + _MK_CURRENT_CTX(canvas); \ + vgSeti(VG_SCISSORING, VG_FALSE); \ + } while(0) +#define mbe_get_target(canvas) ((mbe_surface_t *)(canvas)->tgt) +#define mbe_close_path(canvas) \ + do { \ + char _vg_cmd = VG_CLOSE_PATH; \ + vgAppendPathData((canvas)->path, 1, &_vg_cmd, NULL); \ + } while(0) +#define mbe_text_path(canvas, utf8) +#define mbe_rectangle(canvas, x, y, w, h) +#define mbe_in_stroke(canvas, x, y) (0) +#define mbe_new_path(canvas) \ + vgClearPath((canvas)->path, VG_PATH_CAPABILITY_ALL) +#define mbe_curve_to(canvas, x1, y1, x2, y2, x3, y3) +#define mbe_move_to(canvas, x, y) \ + do { \ + VGfloat _vg_data[2] = {x, y}; \ + char _vg_cmd = VG_MOVE_TO_ABS; \ + vgAppendPathData((canvas)->path, 1, &_vg_cmd, _vg_data); \ + } while(0) +#define mbe_line_to(canvas, x, y) \ + do { \ + VGfloat _vg_data[2] = {x, y}; \ + char _vg_cmd = VG_LINE_TO_ABS; \ + vgAppendPathData((canvas)->path, 1, &_vg_cmd, _vg_data); \ + } while(0) +#define mbe_in_fill(canvas, x, y) (0) +/* TODO: change prototype of mbe_arc() to remove mbe_save() and + * mbe_restore(). + */ +#define mbe_save(canvas) +#define mbe_restore(canvas) +#define mbe_arc(canvas, x, y, radius, angle_start, angle_stop) + +typedef struct _mbe_text_extents_t mbe_text_extents_t; +typedef int mbe_scaled_font_t; +typedef int mbe_font_face_t; +typedef struct _ge_openvg_surface mbe_surface_t; +typedef struct _ge_openvg_pattern mbe_pattern_t; +typedef struct _ge_openvg_mbe mbe_t; +typedef struct _ge_openvg_img _ge_openvg_img_t; + +struct _mbe_text_extents_t { + co_aix x_bearing; + co_aix y_bearing; + co_aix width; + co_aix height; + co_aix x_advance; + co_aix y_advance; +}; + +struct _ge_openvg_mbe { + mbe_pattern_t *src; + VGPaint paint; /*!< \brief The paint associated with + * the src pattern */ + int paint_installed; + mbe_surface_t *tgt; + EGLContext ctx; + VGPath path; + + VGfloat mtx[9]; +}; + +struct _ge_openvg_surface { + void *surface; + mbe_t *asso_mbe; /* There is a association between + * surface and mbe */ + _ge_openvg_img_t *asso_img; + int w, h; +}; + +struct _ge_openvg_pattern { + _ge_openvg_img_t *asso_img; + VGfloat mtx[9]; + VGPaint paint; +}; + +/*! \brief Information associated with VGImage. + * + * A VGImage can associated one of pattern or surface. This type is + * used to make sure previous associated pattern or surface being + * released before new association. + * + * 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. + */ +struct _ge_openvg_img { + int ref; + VGImage img; + void *activated_for; + void (*deactivate_func)(void *obj); +}; + +#define MB_MATRIX_2_OPENVG(vgmtx, mtx) do { \ + (vgmtx)[0] = (mtx)[0]; \ + (vgmtx)[1] = (mtx)[1]; \ + (vgmtx)[2] = (mtx)[2]; \ + (vgmtx)[3] = (mtx)[3]; \ + (vgmtx)[4] = (mtx)[4]; \ + (vgmtx)[5] = (mtx)[5]; \ + (vgmtx)[6] = 0; \ + (vgmtx)[7] = 0; \ + (vgmtx)[8] = 1; \ + } while(0) + +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, + co_aix radius0, + co_aix cx1, co_aix cy1, + co_aix radius1, + grad_stop_t *stops, + int stop_cnt); +extern mbe_pattern_t *mbe_pattern_create_linear(co_aix x0, co_aix y0, + co_aix x1, co_aix y1, + 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); +/* TODO: rename n_areas to areas_cnt and make it after areas */ +extern void mbe_scissoring(mbe_t *canvas, int n_areas, area_t **areas); + + +#define _VG_DISPLAY() eglGetDisplay(_ge_openvg_disp_id) + +/* \brief Make the context of a canvas to be current context. + * + * TODO: swtich VGImage between VGPaint and Surface. + */ +#define _MK_CURRENT_CTX(canvas) do { \ + if(_ge_openvg_current_canvas != (canvas)) { \ + _ge_openvg_current_canvas = canvas; \ + eglMakeCurrent(_VG_DISPLAY(), \ + (canvas)->tgt->surface, \ + (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) \ + 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 { \ + _MK_CURRENT_CTX(canvas); \ + MB_MATRIX_2_OPENVG((canvas)->mtx, _mtx); \ + _mbe_load_pattern_mtx(_mtx, NULL, \ + VG_MATRIX_PATH_USER_TO_SURFACE); \ + } while(0) + + +#define EGL_GLX 1 +#ifdef EGL_GLX +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +extern mbe_surface_t *mbe_vg_win_surface_create(Display *display, + Drawable drawable, + Visual *visual, + int width, int height); +#endif + +extern mbe_surface_t *mbe_image_surface_create(mb_img_fmt_t fmt, + int w, int h); +extern void mbe_surface_destroy(mbe_surface_t *surface); + +extern void mbe_copy_source(mbe_t *src_canvas, mbe_t *dst_canvas); +extern mbe_t *mbe_create(mbe_surface_t *surface); +extern void mbe_destroy(mbe_t *canvas); +extern void mbe_paint_with_alpha(mbe_t *canvas, co_comp_t alpha); +extern void mbe_paint(mbe_t *canvas); +extern void mbe_clear(mbe_t *canvas); +extern void mbe_init(); + +static void +mbe_stroke(mbe_t *canvas) { + _MK_CURRENT_CTX(canvas); + _MK_CURRENT_PAINT(canvas); + if(canvas->src) + _mbe_load_pattern_mtx(canvas->src->mtx, NULL, + VG_MATRIX_STROKE_PAINT_TO_USER); + + vgDrawPath(canvas->path, VG_STROKE_PATH); + vgClearPath(canvas->path, VG_PATH_CAPABILITY_ALL); +} + +static void +mbe_fill_preserve(mbe_t *canvas) { + _MK_CURRENT_CTX(canvas); + _MK_CURRENT_PAINT(canvas); + if(canvas->src) + _mbe_load_pattern_mtx(canvas->src->mtx, NULL, + VG_MATRIX_FILL_PAINT_TO_USER); + + vgDrawPath(canvas->path, VG_FILL_PATH); +} + +static void +mbe_fill(mbe_t *canvas) { + mbe_fill_preserve(canvas); + vgClearPath(canvas->path, VG_PATH_CAPABILITY_ALL); +} +/* @} */ + +#endif /* __MB_GE_OPENVG_H_ */
--- a/src/Makefile.am Tue Nov 30 03:57:36 2010 +0800 +++ b/src/Makefile.am Wed Dec 01 12:25:56 2010 +0800 @@ -14,7 +14,7 @@ noinst_PROGRAMS += testcase endif -if X_BACKEND +if MBAF MBAF_SOURCES=mbaf/mbapp.c mbaf/mbbutton.c mbaf/mbobject.c mbaf/animated_menu.c else MBAF_SOURCES= @@ -24,7 +24,9 @@ observer.c paint.c redraw_man.c rotate.c shape_path.c \ shape_rect.c shift.c subtree_free.c timer.c \ timertool.c tools.c visibility.c prop.c sprite.c \ - mouse.c shape_image.c img_ldr.c $(MBAF_SOURCES) + mouse.c shape_image.c $(MBAF_SOURCES) +libmbfly_la_CPPFLAGS = @imlib2_CFLAGS@ +libmbfly_la_LDFLAGS = @imlib2_LIBS@ if SH_TEXT libmbfly_la_SOURCES += shape_text.c @@ -42,12 +44,20 @@ libmbfly_la_SOURCES += dfb_supp.c endif +if CAIRO_IMG_LOADER +libmbfly_la_SOURCES += img_ldr.c +endif + +if IMLIB2_IMG_LOADER +libmbfly_la_SOURCES += img_ldr_imlib2.c +endif + libmbfly_la_LDFLAGS = if CAIRO_GRAPH_ENGINE libmbfly_la_SOURCES += graph_engine_cairo.c -libmbfly_la_CPPFLAGS = @cairo_CFLAGS@ @pangocairo_CFLAGS@ +libmbfly_la_CPPFLAGS += @cairo_CFLAGS@ @pangocairo_CFLAGS@ libmbfly_la_LDFLAGS += @cairo_LIBS@ @pangocairo_LIBS@ endif @@ -59,6 +69,15 @@ libmbfly_la_SOURCES += graph_engine_skia.cpp endif +if DFB_GRAPH_ENGINE +libmbfly_la_SOURCES += graph_engine_dfb.c +endif + +if OPENVG_GRAPH_ENGINE +libmbfly_la_SOURCES += graph_engine_openvg.c +libmbfly_la_LDFLAGS += -lOpenVG -lEGL +endif + X_main_SOURCES = X_main.c X_main_LDADD = $(top_builddir)/src/libmbfly.la X_main_CPPFLAGS = @pangocairo_CFLAGS@ -I$(top_builddir)/include
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/graph_engine_dfb.c Wed Dec 01 12:25:56 2010 +0800 @@ -0,0 +1,1 @@ +/* Keep Me */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/graph_engine_openvg.c Wed Dec 01 12:25:56 2010 +0800 @@ -0,0 +1,841 @@ +#include "mb_graph_engine_openvg.h" +#include "mb_tools.h" + +EGLNativeDisplayType _ge_openvg_disp_id = EGL_DEFAULT_DISPLAY; +mbe_t *_ge_openvg_current_canvas = NULL; + +#ifndef ASSERT +#define ASSERT(x) +#endif + +#define MB_2_VG_COLOR(r, g, b, a) ((((int)(0xf * r) & 0xf) << 24) | \ + (((int)(0xf * g) & 0xf) << 16) | \ + (((int)(0xf * b) & 0xf) << 16) | \ + ((int)(0xf * a) & 0xf)) + +#define MK_ID(mtx) \ + do { \ + (mtx)[0] = 1; \ + (mtx)[1] = 0; \ + (mtx)[2] = 0; \ + (mtx)[3] = 0; \ + (mtx)[4] = 1; \ + (mtx)[5] = 0; \ + (mtx)[6] = 0; \ + (mtx)[7] = 0; \ + (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->activated_for = NULL; + ge_img->deactivate_func = 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) { + 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. + */ +mbe_pattern_t * +mbe_pattern_create_for_surface(mbe_surface_t *surface) { + mbe_pattern_t *pattern; + _ge_openvg_img_t *ge_img; + VGfloat *mtx; + VGPaint paint; + + /* Support only from image surface */ + if(surface->asso_img == NULL) + return NULL; + + paint = vgCreatePaint(); + if(paint == VG_INVALID_HANDLE) + return NULL; + + 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; + MK_ID(mtx); + + return pattern; +} + +void +_mbe_load_pattern_mtx(VGfloat *mtx1, VGfloat *mtx2, int mode) { + VGfloat affine; + + vgSeti(VG_MATRIX_MODE, mode); + vgLoadMatrix(mtx1); + if(mtx2) + vgMultMatrix(mtx2); +} + +static mbe_pattern_t * +_mbe_pattern_create_gradient(VGfloat *gradient, int grad_len, + int grad_type, + grad_stop_t *stops, int stop_cnt) { + VGPaint paint; + mbe_pattern_t *pattern; + static VGfloat *ov_stops = 0; + static int max_stop_cnt = 0; + VGfloat *cur_ov_stop; + grad_stop_t *cur_stop; + int i; + + /* Make sure there is enough space */ + if(max_stop_cnt < stop_cnt) { + max_stop_cnt = (stop_cnt + 0xf) & ~0xf; + cur_ov_stop = (VGfloat *)realloc(stops, + max_stop_cnt * sizeof(VGfloat) * 5); + if(cur_ov_stop == NULL) { + max_stop_cnt = 0; + return NULL; + } + ov_stops = cur_ov_stop; + } + cur_ov_stop = ov_stops; + + cur_stop = stops; + for(i = 0; i < stop_cnt; i++) { + *cur_ov_stop++ = cur_stop->offset; + *cur_ov_stop++ = cur_stop->r; + *cur_ov_stop++ = cur_stop->g; + *cur_ov_stop++ = cur_stop->b; + *cur_ov_stop++ = cur_stop->a; + } + + paint = vgCreatePaint(); + if(paint == VG_INVALID_HANDLE) + return NULL; + vgSetParameteri(paint, VG_PAINT_TYPE, grad_type); + vgSetParameterfv(paint, VG_PAINT_RADIAL_GRADIENT, grad_len, gradient); + vgSetParameterfv(paint, VG_PAINT_COLOR_RAMP_STOPS, 5 * stop_cnt, ov_stops); + + pattern = O_ALLOC(mbe_pattern_t); + if(pattern == NULL) { + vgDestroyPaint(paint); + return NULL; + } + + pattern->paint = paint; + pattern->asso_img = NULL; + + MK_ID(pattern->mtx); + + return pattern; +} + +/* + * \note OpenVG does not support start circle, it supports only focal + * point. It means radius0 is not working. + */ +mbe_pattern_t * +mbe_pattern_create_radial(co_aix cx0, co_aix cy0, + co_aix radius0, + co_aix cx1, co_aix cy1, + co_aix radius1, grad_stop_t *stops, + int stop_cnt) { + mbe_pattern_t *pattern; + VGfloat gradient[] = {cx0, cy0, cx1, cy1, radius1}; + + pattern = _mbe_pattern_create_gradient(gradient, 5, + VG_PAINT_TYPE_RADIAL_GRADIENT, + stops, stop_cnt); + return pattern; +} + +mbe_pattern_t * +mbe_pattern_create_linear(co_aix x0, co_aix y0, + co_aix x1, co_aix y1, + grad_stop_t *stops, int stop_cnt) { + mbe_pattern_t *pattern; + VGfloat gradient[] = {x0, y0, x1, y1}; + + pattern = _mbe_pattern_create_gradient(gradient, 4, + VG_PAINT_TYPE_LINEAR_GRADIENT, + stops, stop_cnt); + return pattern; +} + +mbe_pattern_t * +mbe_pattern_create_image(mb_img_data_t *img) { + VGPaint paint; + mbe_pattern_t *pattern; + _ge_openvg_img_t *ge_img; + VGImage vg_img; + VGImageFormat fmt = VG_sARGB_8888; + + /* \note OpenVG implementation supports one \ref MB_IFMT_ARGB32 + * image. + */ + if(img->fmt != MB_IFMT_ARGB32) + return NULL; + + /* Allocate objects */ + 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; + + /* 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_vgimage(ge_img); + if(pattern) free(pattern); + if(paint != VG_INVALID_HANDLE) vgDestroyPaint(paint); + vgDestroyImage(vg_img); + return NULL; +} + +void +mbe_pattern_destroy(mbe_pattern_t *ptn) { + if(ptn->asso_img) + _free_vgimage(ptn->asso_img); + vgDestroyPaint(ptn->paint); + free(ptn); +} + +void +mbe_pattern_set_matrix(mbe_pattern_t *ptn, co_aix *mtx) { + co_aix rev[6]; + + compute_reverse(mtx, rev); + ptn->mtx[0] = rev[0]; + ptn->mtx[1] = rev[3]; + ptn->mtx[2] = 0; + ptn->mtx[3] = rev[1]; + ptn->mtx[4] = rev[4]; + ptn->mtx[5] = 0; + ptn->mtx[6] = rev[2]; + ptn->mtx[7] = rev[5]; + ptn->mtx[8] = 1; +} + +void +mbe_set_source_rgba(mbe_t *canvas, co_comp_t r, co_comp_t g, + co_comp_t b, co_comp_t a) { + VGPaint paint; + VGuint color; + + if(paint != VG_INVALID_HANDLE && canvas->src == NULL) + paint = canvas->paint; /* previous one is also a color paint */ + else { + paint = vgCreatePaint(); + ASSERT(paint != VG_INVALID_HANDLE); + canvas->paint = paint; + canvas->src = NULL; + } + + color = MB_2_VG_COLOR(r, g, b, a); + vgSetColor(paint, color); + canvas->paint_installed = 0; +} + +void +mbe_scissoring(mbe_t *canvas, int n_areas, area_t **areas) { + static VGint *scissors = NULL; + static int n_scissors = 0; + VGint *coord; + area_t *area; + int i; + + _MK_CURRENT_CTX(canvas); + + if(n_areas > n_scissors) { + if(scissors) free(scissors); + n_scissors = (n_areas + 0xf) & ~0xf; + scissors = (VGint *)malloc(sizeof(VGint) * n_scissors * 4); + ASSERT(scissors != NULL); + } + + coord = scissors; + for(i = 0; i < n_areas; i++) { + area = areas[i]; + *coord++ = area->x; + *coord++ = area->y; + *coord++ = area->w; + *coord++ = area->h; + } + + vgSeti(VG_SCISSORING, VG_TRUE); + vgSetiv(VG_SCISSOR_RECTS, n_areas * 4, scissors); +} + +static int +_openvg_find_config(mb_img_fmt_t fmt, int w, int h, + EGLConfig *config) { + EGLDisplay display; + EGLint attrib_list[32]; + EGLConfig configs[1]; + EGLint nconfigs; + int i = 0; + EGLBoolean r; + + switch(fmt) { + case MB_IFMT_ARGB32: + attrib_list[i++] = EGL_RED_SIZE; + attrib_list[i++] = 8; + attrib_list[i++] = EGL_GREEN_SIZE; + attrib_list[i++] = 8; + attrib_list[i++] = EGL_BLUE_SIZE; + attrib_list[i++] = 8; + attrib_list[i++] = EGL_ALPHA_SIZE; + attrib_list[i++] = 8; + break; + + case MB_IFMT_RGB24: + attrib_list[i++] = EGL_RED_SIZE; + attrib_list[i++] = 8; + attrib_list[i++] = EGL_GREEN_SIZE; + attrib_list[i++] = 8; + attrib_list[i++] = EGL_BLUE_SIZE; + attrib_list[i++] = 8; + break; + + case MB_IFMT_A8: + attrib_list[i++] = EGL_ALPHA_SIZE; + attrib_list[i++] = 8; + break; + + case MB_IFMT_A1: + attrib_list[i++] = EGL_ALPHA_SIZE; + attrib_list[i++] = 1; + break; + + case MB_IFMT_RGB16_565: + attrib_list[i++] = EGL_RED_SIZE; + attrib_list[i++] = 5; + attrib_list[i++] = EGL_GREEN_SIZE; + attrib_list[i++] = 6; + attrib_list[i++] = EGL_BLUE_SIZE; + attrib_list[i++] = 5; + break; + + default: + return -1; + } + + attrib_list[i++] = EGL_SURFACE_TYPE; + attrib_list[i++] = EGL_PBUFFER_BIT; +#if 0 + attrib_list[i++] = EGL_MAX_PBUFFER_WIDTH; + attrib_list[i++] = w; + attrib_list[i++] = EGL_MAX_PBUFFER_HEIGHT; + attrib_list[i++] = h; +#endif + + attrib_list[i++] = EGL_RENDERABLE_TYPE; + attrib_list[i++] = EGL_OPENVG_BIT; + + attrib_list[i++] = EGL_NONE; + + display = _VG_DISPLAY(); + r = eglChooseConfig(display, attrib_list, configs, 1, &nconfigs); + if(!r) + return -1; + + *config = configs[0]; + + return 0; +} + +#ifdef EGL_GLX +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +static int +_get_img_fmt_from_xvisual(Display *display, Visual *visual) { + VisualID visual_id; + XVisualInfo temp; + XVisualInfo *infos; + int n; + int fmt = -1; + + visual_id = XVisualIDFromVisual(visual); + temp.visualid = visual_id; + infos = XGetVisualInfo(display, VisualIDMask, &temp, &n); + if(n != 1) + return -1; + + switch(infos->depth) { + case 32: + fmt = MB_IFMT_ARGB32; + break; + + case 24: + fmt = MB_IFMT_RGB24; + break; + + case 16: + fmt = MB_IFMT_RGB16_565; + break; + + case 8: + fmt = MB_IFMT_A8; + break; + + case 1: + fmt = MB_IFMT_A1; + break; + } + + return fmt; +} + +/*! \brief Create an EGL window surface for X11. + * + * This function is compiled only for GLX enabled. + */ +mbe_surface_t * +mbe_vg_win_surface_create(Display *display, Drawable drawable, + Visual *visual, int width, int height) { + EGLDisplay egl_disp; + EGLSurface egl_surface; + mbe_surface_t *surface; + EGLConfig config; + EGLint attrib_list[2] = {EGL_NONE}; + int fmt; + int r; + + fmt = _get_img_fmt_from_xvisual(display, visual); + if(fmt == -1) + return NULL; + + r = _openvg_find_config(fmt, width, height, &config); + if(r != 0) + return NULL; + + egl_disp = eglGetDisplay(display); + if(egl_disp == EGL_NO_DISPLAY || egl_disp != _VG_DISPLAY()) + return NULL; + + egl_surface = eglCreateWindowSurface(egl_disp, config, drawable, + attrib_list); + + surface = O_ALLOC(mbe_surface_t); + if(surface == NULL) { + eglDestroySurface(egl_disp, egl_surface); + return NULL; + } + + surface->surface = egl_surface; + surface->asso_img = NULL; + + return surface; +} + +#endif + +mbe_surface_t * +mbe_image_surface_create(mb_img_fmt_t fmt, int w, int h) { + EGLSurface surface; + EGLDisplay display; + EGLConfig config; + EGLint attrib_list[5]; + _ge_openvg_img_t *ge_img; + mbe_surface_t *mbe_surface; + int r; + + + 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; + attrib_list[2] = EGL_HEIGHT; + attrib_list[3] = h; + attrib_list[4] = EGL_NONE; + /* Some implementation does not support pbuffer. + * We need use some other surface to replace this one. + */ + 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) + _free_vgimage(surface->asso_img); + + free(surface); +} + +void +mbe_copy_source(mbe_t *src_canvas, mbe_t *dst_canvas) { + VGImage vg_img; + + ASSERT(src_canvas->tgt->asso_img != NULL); + + _MK_CURRENT_CTX(dst_canvas); + + vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); + vgLoadIdentity(); + + vg_img = src_canvas->tgt->asso_img; + vgDrawImage(vg_img); +} + +mbe_t * +mbe_create(mbe_surface_t *surface) { + EGLDisplay display; + EGLConfig config; + EGLContext ctx, shared; + VGPath path; + EGLint attrib_list[2] = {EGL_NONE}; + static VGfloat clear_color[4] = {0, 0, 0, 1}; + mbe_t *canvas; + + display = _VG_DISPLAY(); + ctx = eglCreateContext(display, config, shared, attrib_list); + if(ctx == EGL_NO_CONTEXT) + return NULL; + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); + if(path == VG_INVALID_HANDLE) { + eglDestroyContext(display, ctx); + return NULL; + } + + canvas = O_ALLOC(mbe_t); + if(canvas == NULL) { + eglDestroyContext(display, ctx); + vgDestroyPath(path); + return NULL; + } + + canvas->src = NULL; + canvas->paint = VG_INVALID_HANDLE; + canvas->paint_installed = 0; + canvas->tgt = surface; + canvas->ctx = ctx; + canvas->path = path; + + /* Set clear color for the context */ + _MK_CURRENT_CTX(canvas); + vgSetfv(VG_CLEAR_COLOR, 4, clear_color); + + return canvas; +} + +void +mbe_destroy(mbe_t *canvas) { + EGLDisplay display; + + display = _VG_DISPLAY(); + + vgDestroyPath(canvas->path); + eglDestroyContext(display, canvas->ctx); + canvas->tgt->asso_mbe = NULL; /* remove association */ + free(canvas); +} + +void +mbe_paint_with_alpha(mbe_t *canvas, co_comp_t alpha) { + VGfloat color_trans[8] = {1, 1, 1, alpha, 0, 0, 0, 0}; + EGLDisplay display; + EGLint w, h; + EGLBoolean r; + + _MK_CURRENT_CTX(canvas); + + display = _VG_DISPLAY(); + + r = eglQuerySurface(display, canvas->tgt, EGL_WIDTH, &w); + ASSERT(r == EGL_TRUE); + r = eglQuerySurface(display, canvas->tgt, EGL_HEIGHT, &h); + ASSERT(r == EGL_TRUE); + + /* Setup color transform for alpha */ +#ifdef OPENVG_1_1 + vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, color_trans); + vgSeti(VG_COLOR_TRANSFORM, VG_TRUE); +#endif + + mbe_paint(canvas); + +#ifdef OPENVG_1_1 + vgSeti(VG_COLOR_TRANSFORM, VG_FALSE); +#endif +} + +void +mbe_paint(mbe_t *canvas) { + EGLDisplay display; + EGLint w, h; + EGLBoolean r; + VGPath path; + + _MK_CURRENT_CTX(canvas); + _MK_CURRENT_PAINT(canvas); + if(canvas->src) + _mbe_load_pattern_mtx(canvas->src->mtx, NULL, + VG_MATRIX_FILL_PAINT_TO_USER); + + display = _VG_DISPLAY(); + + r = eglQuerySurface(display, canvas->tgt, EGL_WIDTH, &w); + ASSERT(r == EGL_TRUE); + r = eglQuerySurface(display, canvas->tgt, EGL_HEIGHT, &h); + ASSERT(r == EGL_TRUE); + + /* + * Disable scissoring and identity transform matrix. + * + * Transform matrix from path to surface is assigned by + * mbe_transform(). Here, we temporary set it to identity, and + * restore it after paint. + */ + vgSeti(VG_SCISSORING, VG_FALSE); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + vgLoadIdentity(); + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); + vguRect(path, 0, 0, w, h); + vgDrawPath(path, VG_FILL_PATH); + vgDestroyPath(path); + + /* re-enable scissoring and restore transform matrix */ + vgLoadMatrix(canvas->mtx); + vgSeti(VG_SCISSORING, VG_TRUE); +} + +void +mbe_clear(mbe_t *canvas) { + EGLDisplay display; + EGLint w, h; + EGLBoolean r; + + _MK_CURRENT_CTX(canvas); + + display = _VG_DISPLAY(); + + r = eglQuerySurface(display, canvas->tgt, EGL_WIDTH, &w); + ASSERT(r == EGL_TRUE); + r = eglQuerySurface(display, canvas->tgt, EGL_HEIGHT, &h); + ASSERT(r == EGL_TRUE); + + /* Clear regions to the color specified by mbe_create() */ + vgClear(0, 0, w, h); +} + +void mbe_init() { + static EGLContext init_ctx; + static EGLSurface init_surf; + EGLDisplay display; + EGLConfig config; + EGLint nconfigs; + EGLint attrib_list[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, + EGL_NONE}; + EGLint surf_attribs[] = { + EGL_WIDTH, 1, + EGL_HEIGHT, 1, + EGL_NONE}; + EGLBoolean r; + + display = _VG_DISPLAY(); + eglInitialize(display, NULL, NULL); + + r = eglChooseConfig(display, attrib_list, &config, 1, &nconfigs); + ASSERT(r); + + eglBindAPI(EGL_OPENVG_API); + + init_ctx = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL); + ASSERT(init_ctx != EGL_NO_CONTEXT); + + init_surf = eglCreatePbufferSurface(display, config, surf_attribs); + ASSERT(init_surf != EGL_NO_SURFACE); + + eglMakeCurrent(display, init_surf, init_surf, init_ctx); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/img_ldr_imlib2.c Wed Dec 01 12:25:56 2010 +0800 @@ -0,0 +1,117 @@ +// -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- +// vim: sw=4:ts=8:sts=4 +#include <stdio.h> +#include <string.h> +#include <Imlib2.h> +#include "mb_graph_engine.h" +#include "mb_tools.h" +#include "mb_paint.h" +#include "mb_img_ldr.h" + +/*! \brief Simple image loader. + * + */ +struct _simple_mb_img_ldr { + mb_img_ldr_t ldr; + const char *repo; /*!< \brief The directory of repository. */ +}; +typedef struct _simple_mb_img_ldr simple_mb_img_ldr_t; + +struct _simple_mb_img_data { + mb_img_data_t img; + Imlib_Image img_hdl; +}; +typedef struct _simple_mb_img_data simple_mb_img_data_t; + +static void simple_mb_img_ldr_img_free(mb_img_data_t *img); + +static +mb_img_data_t *simple_mb_img_ldr_load(mb_img_ldr_t *ldr, const char *img_id) { + simple_mb_img_ldr_t *sldr = (simple_mb_img_ldr_t *)ldr; + simple_mb_img_data_t *img; + Imlib_Image img_hdl; + int w, h; + void *data; + char *fname; + int sz; + + sz = strlen(sldr->repo); + sz += strlen(img_id); + fname = (char *)malloc(sz + 2); + if (img_id[0] != '/') + strcpy(fname, sldr->repo); + else + fname[0] = 0; + strcat(fname, img_id); + + img_hdl = imlib_load_image(fname); + if(!img_hdl) + return NULL; + imlib_context_set_image(img_hdl); + w = imlib_image_get_width(); + h = imlib_image_get_height(); + data = imlib_image_get_data_for_reading_only(); + + img = O_ALLOC(simple_mb_img_data_t); + if(img == NULL) { + imlib_free_image(); + return NULL; + } + img->img.content = data; + img->img.w = w; + img->img.h = h; + img->img.stride = w * 4; + img->img.fmt = MB_IFMT_ARGB32; + img->img.free = simple_mb_img_ldr_img_free; + img->img_hdl = img_hdl; + + return (mb_img_data_t *)img; +} + +static +void simple_mb_img_ldr_img_free(mb_img_data_t *img) { + simple_mb_img_data_t *simg = (simple_mb_img_data_t *)img; + + imlib_context_set_image(simg->img_hdl); + imlib_free_image(); + free(img); +} + +static +void simple_mb_img_ldr_free(mb_img_ldr_t *ldr) { + simple_mb_img_ldr_t *defldr = (simple_mb_img_ldr_t *)ldr; + + free((void *)defldr->repo); +} + +mb_img_ldr_t *simple_mb_img_ldr_new(const char *img_repository) { + simple_mb_img_ldr_t *ldr; + int sz; + + if(img_repository == NULL) + return NULL; + + ldr = O_ALLOC(simple_mb_img_ldr_t); + if(ldr == NULL) + return NULL; + + /* + * Copy and formalize path of image repository. + */ + sz = strlen(img_repository); + ldr->repo = (const char *)malloc(sz + 2); + if(ldr->repo == NULL) { + free(ldr); + return NULL; + } + strcpy((char *)ldr->repo, img_repository); + if(img_repository[sz - 1] != '/' && strlen(img_repository) != 0) { + ((char *)ldr->repo)[sz] = '/'; + ((char *)ldr->repo)[sz + 1] = 0; + } + + ldr->ldr.load = simple_mb_img_ldr_load; + ldr->ldr.free = simple_mb_img_ldr_free; + + return (mb_img_ldr_t *)ldr; +}