Mercurial > MadButterfly
changeset 582:dd546c4da180 openvg
deal with EGL surface, context for OpenVG GE
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 30 Jun 2010 01:32:47 +0800 |
parents | 953acea89f76 |
children | ca57132020e4 |
files | include/mb_graph_engine_openvg.h src/graph_engine_openvg.c |
diffstat | 2 files changed, 244 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/include/mb_graph_engine_openvg.h Sat Jun 19 11:43:53 2010 +0800 +++ b/include/mb_graph_engine_openvg.h Wed Jun 30 01:32:47 2010 +0800 @@ -2,7 +2,9 @@ #define __MB_GE_OPENVG_H_ #include <stdio.h> -#include <GL/glut.h> +#include <stdlib.h> +#include <EGL/egl.h> +#include <VG/openvg.h> #include "mb_basic_types.h" #include "mb_img_ldr.h" @@ -24,22 +26,17 @@ #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_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) @@ -51,9 +48,10 @@ #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_set_source(canvas, pattern) \ + do { (canvas)->src = (pattern); } while(0) #define mbe_reset_clip(canvas) -#define mbe_get_target(canvas) ((mbe_surface_t *)NULL) +#define mbe_get_target(canvas) ((mbe_surface_t *)(canvas)->tgt) #define mbe_close_path(canvas) #define mbe_text_path(canvas, utf8) #define mbe_transform(canvas, mtx) @@ -67,7 +65,6 @@ #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) @@ -94,7 +91,7 @@ struct _ge_openvg_mbe { mbe_pattern_t *src; mbe_surface_t *tgt; - void *ctx; + EGLContext ctx; }; struct _ge_openvg_surface { @@ -119,6 +116,239 @@ (vgmtx)[8] = 1; \ } while(0) +extern EGLNativeDisplayType _ge_openvg_disp_id; + +#define _VG_DISPLAY() eglGetDisplay(_ge_openvg_disp_id) + +static int +_openvg_find_confg(mb_img_fmt_t fmt, int w, int h, + EGLConfig *config) { + EGLDisplay display; + EGLint attrib_list[16]; + 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_NONE; + + display = _VG_DISPLAY(); + r = eglChooseConfig(display, attrib_list, configs, 1, &nconfigs); + if(!r) + return -1; + + *config = configs[0]; + + return 0; +} + +#define EGL_GLX 1 +#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. + */ +static mbe_surface_t * +mbe_xlib_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_confg(fmt, width, height, &config); + if(r != 0) + return NULL; + + egl_disp = eglGetDisplay(display); + if(egl_disp == EGL_NO_DISPLAY) + return NULL; + + egl_surface = eglCreateWindowSurface(egl_disp, config, drawable, + attrib_list); + + surface = (mbe_surface_t *)malloc(sizeof(mbe_surface_t)); + if(surface == NULL) { + eglDestroySurface(egl_disp, egl_surface); + return NULL; + } + + surface->surface = egl_surface; + + return surface; +} + +#endif + +static 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[2] = {EGL_NONE}; + mbe_surface_t *mbe_surface; + int r; + + + r = _openvg_find_confg(fmt, w, h, &config); + if(r != 0) + return NULL; + + display = _VG_DISPLAY(); + /* 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) + return NULL; + + mbe_surface = (mbe_surface_t *)malloc(sizeof(mbe_surface_t)); + if(mbe_surface == NULL) + return NULL; + mbe_surface->surface = surface; + mbe_surface->asso_mbe = NULL; + + return mbe_surface; +} + +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; + + free(surface); +} + +static mbe_t * +mbe_create(mbe_surface_t *surface) { + EGLDisplay display; + EGLConfig config; + EGLContext ctx, shared; + EGLint attrib_list[2] = {EGL_NONE}; + mbe_t *canvas; + + display = _VG_DISPLAY(); + ctx = eglCreateContext(display, config, shared, attrib_list); + if(ctx == EGL_NO_CONTEXT) + return NULL; + + canvas = (mbe_t *)malloc(sizeof(mbe_t)); + if(canvas == NULL) + return NULL; + + canvas->src = NULL; + canvas->tgt = surface; + canvas->ctx = ctx; + + return canvas; +} /* @} */