From 37b66e806b098e545bc9d545cc452f64d7a64fda Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Fri, 9 Oct 2009 12:10:27 +0000 Subject: [PATCH] new gl engine. no one uses it anyway. not 100% complete, but much better than the old. and it ALSO does GLES2.0 as well asn GL. SVN revision: 42982 --- legacy/evas/configure.ac | 8 +- legacy/evas/m4/evas_check_engine.m4 | 44 +- legacy/evas/src/lib/Evas.h | 3 +- .../src/lib/engines/common/evas_font_draw.c | 2 + .../src/lib/engines/common/evas_font_load.c | 24 + legacy/evas/src/lib/include/evas_common.h | 2 + .../src/modules/engines/gl_common/Makefile.am | 39 +- .../engines/gl_common/evas_gl_common.h | 267 +++--- .../engines/gl_common/evas_gl_context.c | 845 ++++++++--------- .../modules/engines/gl_common/evas_gl_font.c | 366 +++----- .../modules/engines/gl_common/evas_gl_image.c | 174 ++-- .../engines/gl_common/evas_gl_private.h | 85 -- .../engines/gl_common/evas_gl_rectangle.c | 51 +- .../engines/gl_common/evas_gl_texture.c | 879 ++++++------------ .../gl_common/shader/compile-s3c6410.sh | 34 + .../engines/gl_common/shader/compile-sgx.sh | 12 + .../engines/gl_common/shader/font_frag.h | 7 + .../engines/gl_common/shader/font_frag.shd | 7 + .../gl_common/shader/font_frag_s3c6410.asm | 26 + .../engines/gl_common/shader/font_vert.h | 12 + .../engines/gl_common/shader/font_vert.shd | 12 + .../engines/gl_common/shader/img_frag.h | 7 + .../engines/gl_common/shader/img_frag.shd | 7 + .../gl_common/shader/img_frag_s3c6410.asm | 26 + .../engines/gl_common/shader/img_vert.h | 12 + .../engines/gl_common/shader/img_vert.shd | 12 + .../engines/gl_common/shader/make-c-bin.sh | 3 + .../engines/gl_common/shader/make-c-str.sh | 3 + .../engines/gl_common/shader/rect_frag.h | 6 + .../engines/gl_common/shader/rect_frag.shd | 6 + .../gl_common/shader/rect_frag_s3c6410.asm | 24 + .../engines/gl_common/shader/rect_vert.h | 10 + .../engines/gl_common/shader/rect_vert.shd | 10 + .../src/modules/engines/gl_x11/evas_engine.c | 245 +++-- .../src/modules/engines/gl_x11/evas_engine.h | 71 +- .../src/modules/engines/gl_x11/evas_x_main.c | 206 +++- 36 files changed, 1721 insertions(+), 1826 deletions(-) create mode 100755 legacy/evas/src/modules/engines/gl_common/shader/compile-s3c6410.sh create mode 100755 legacy/evas/src/modules/engines/gl_common/shader/compile-sgx.sh create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/font_frag.h create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/font_frag.shd create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/font_frag_s3c6410.asm create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/font_vert.h create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/font_vert.shd create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/img_frag.h create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/img_frag.shd create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/img_frag_s3c6410.asm create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/img_vert.h create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/img_vert.shd create mode 100755 legacy/evas/src/modules/engines/gl_common/shader/make-c-bin.sh create mode 100755 legacy/evas/src/modules/engines/gl_common/shader/make-c-str.sh create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/rect_frag.h create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/rect_frag.shd create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/rect_frag_s3c6410.asm create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/rect_vert.h create mode 100644 legacy/evas/src/modules/engines/gl_common/shader/rect_vert.shd diff --git a/legacy/evas/configure.ac b/legacy/evas/configure.ac index b80d837cd9..3ff1063318 100644 --- a/legacy/evas/configure.ac +++ b/legacy/evas/configure.ac @@ -435,15 +435,11 @@ have_evas_engine_gl_common="no" if test "x$have_evas_engine_gl_x11" = "xyes" -o "x$have_evas_engine_gl_glew" = "xyes"; then AC_DEFINE(BUILD_ENGINE_GL_COMMON, 1, [Generic OpenGL Rendering Support]) have_evas_engine_gl_common="yes" - evas_engine_gl_common_libs="-lglu32" -fi - -if test "x$have_evas_engine_gl_x11" = "xyes" ; then - evas_engine_gl_common_libs="-lGL -lGLU -lpthread" + evas_engine_gl_common_libs="" fi if test "x$have_evas_engine_gl_glew" = "xyes" ; then - evas_engine_gl_common_libs="-lglu32" + evas_engine_gl_common_libs="" fi AC_SUBST([evas_engine_gl_common_libs]) diff --git a/legacy/evas/m4/evas_check_engine.m4 b/legacy/evas/m4/evas_check_engine.m4 index 2eb44b1e5f..55c1fcb838 100644 --- a/legacy/evas/m4/evas_check_engine.m4 +++ b/legacy/evas/m4/evas_check_engine.m4 @@ -125,7 +125,7 @@ evas_engine_[]$1[]_libs="" AC_PATH_X AC_PATH_XTRA -AC_CHECK_HEADERS([GL/gl.h GL/glu.h GL/glx.h X11/X.h], +AC_CHECK_HEADERS([GL/gl.h GL/glx.h X11/X.h], [have_dep="yes"], [have_dep="no"]) @@ -137,9 +137,8 @@ if test "x${have_dep}" = "xyes" ; then AC_CHECK_LIB([GL], [glXCreateContext], [have_dep="yes"], [have_dep="no"]) fi -if test "x${have_dep}" = "xyes" ; then - AC_CHECK_LIB([GLU], [gluNewTess], [have_dep="yes"], [have_dep="no"]) -fi +## HACK: force gles build on systems that have glx +#have_dep=no if test "x${have_dep}" = "xyes" ; then if test "x$2" = "xyes" ; then @@ -150,12 +149,43 @@ if test "x${have_dep}" = "xyes" ; then x_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} -lX11" fi evas_engine_[]$1[]_cflags="-I/usr/include ${x_cflags}" - evas_engine_[]$1[]_libs="${x_libs} -lGL -lGLU -lpthread" + evas_engine_[]$1[]_libs="${x_libs} -lGL -lpthread" + evas_engine_gl_common_libs="-lGL -lpthread" +else + if test "x$2" = "xyes" ; then + x_libs="${x_libs} -lX11 -lXext" + else + x_dir=${x_dir:-/usr/X11R6} + x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}} + x_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} -lX11" + fi + AC_CHECK_HEADERS([EGL/egl.h X11/X.h X11/Xlib.h], [have_egl="yes"]) + if test "x${have_egl}" = "xyes" ; then + have_gles20="no" + AC_CHECK_LIB(gles20, glTexImage2D, [have_gles20="yes"], , -lEGL) + if test "x${have_gles20}" = "xyes" ; then + evas_engine_[]$1[]_cflags="${x_cflags}" + evas_engine_[]$1[]_libs="${x_libs} -lgles20 -lEGL" + AC_DEFINE(GLES_VARIETY_S3C6410, 1, [Samsung S3c6410 GLES2 support]) + evas_engine_gl_common_libs="-lgles20" + have_dep="yes" + fi + have_glesv2="no" + AC_CHECK_LIB(GLESv2, glTexImage2D, [have_glesv2="yes"], , -lEGL ${x_libs} -lpthread -lm) + if test "x${have_glesv2}" = "xyes" ; then + evas_engine_[]$1[]_cflags="${x_cflags}" + evas_engine_[]$1[]_libs="${x_libs} -lGLESv2 -lpthread -lm -lEGL" + AC_DEFINE(GLES_VARIETY_SGX, 1, [Imagination SGX GLES2 support]) + evas_engine_gl_common_libs="-lGLESv2 -lpthread -lm" + have_dep="yes" + fi + fi fi AC_SUBST([evas_engine_$1_cflags]) AC_SUBST([evas_engine_$1_libs]) + if test "x${have_dep}" = "xyes" ; then m4_default([$4], [:]) else @@ -394,10 +424,10 @@ AC_DEFUN([EVAS_CHECK_ENGINE_DEP_GL_GLEW], evas_engine_[]$1[]_cflags="" evas_engine_[]$1[]_libs="" -AC_CHECK_HEADERS([GL/gl.h GL/glu.h GL/glew.h], +AC_CHECK_HEADERS([GL/gl.h GL/glew.h], [ have_dep="yes" - evas_engine_[]$1[]_libs="-lglu32 -lglew32 -lopengl32 -lgdi32" + evas_engine_[]$1[]_libs="-lglew32 -lopengl32 -lgdi32" ], [have_dep="no"] ) diff --git a/legacy/evas/src/lib/Evas.h b/legacy/evas/src/lib/Evas.h index 853a11295c..2d2ade4385 100644 --- a/legacy/evas/src/lib/Evas.h +++ b/legacy/evas/src/lib/Evas.h @@ -870,7 +870,8 @@ extern "C" { EAPI void evas_object_smart_need_recalculate_set(Evas_Object *obj, Eina_Bool value) EINA_ARG_NONNULL(1); EAPI Eina_Bool evas_object_smart_need_recalculate_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE; EAPI void evas_object_smart_calculate (Evas_Object *obj) EINA_ARG_NONNULL(1); - + + EAPI void evas_smart_objects_calculate (Evas *e); /* events */ EAPI void evas_event_freeze (Evas *e) EINA_ARG_NONNULL(1); diff --git a/legacy/evas/src/lib/engines/common/evas_font_draw.c b/legacy/evas/src/lib/engines/common/evas_font_draw.c index 1cc2cfb406..684c0fa186 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_draw.c +++ b/legacy/evas/src/lib/engines/common/evas_font_draw.c @@ -51,6 +51,8 @@ evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index) fg->glyph_out = (FT_BitmapGlyph)fg->glyph; fg->index = hindex; + fg->fi = fi; + eina_hash_direct_add(fi->glyphs, &fg->index, fg); return fg; } diff --git a/legacy/evas/src/lib/engines/common/evas_font_load.c b/legacy/evas/src/lib/engines/common/evas_font_load.c index 93d65430a8..60c98ab2a0 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_load.c +++ b/legacy/evas/src/lib/engines/common/evas_font_load.c @@ -356,6 +356,8 @@ evas_common_font_int_load_init(RGBA_Font_Int *fi) EAPI RGBA_Font_Int * evas_common_font_int_load_complete(RGBA_Font_Int *fi) { + int val, dv; + int ret; int error; error = FT_New_Size(fi->src->ft.face, &(fi->ft.size)); @@ -402,6 +404,28 @@ evas_common_font_int_load_complete(RGBA_Font_Int *fi) } fi->src->current_size = fi->size; + fi->max_h = 0; + + val = (int)fi->src->ft.face->bbox.yMax; + if (fi->src->ft.face->units_per_EM != 0) + { + dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM; + ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv); + } + else + ret = val; + fi->max_h += ret; + + val = -(int)fi->src->ft.face->bbox.yMin; + if (fi->src->ft.face->units_per_EM != 0) + { + dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM; + ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv); + } + else + ret = val; + fi->max_h += ret; + return fi; } diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index ab321f968f..8898207181 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -876,6 +876,7 @@ struct _RGBA_Font_Int int size; int real_size; + int max_h; struct { FT_Size size; @@ -923,6 +924,7 @@ struct _RGBA_Font_Glyph /* this is a problem - only 1 engine at a time can extend such a font... grrr */ void *ext_dat; void (*ext_dat_free) (void *ext_dat); + RGBA_Font_Int *fi; }; struct _RGBA_Gfx_Compositor diff --git a/legacy/evas/src/modules/engines/gl_common/Makefile.am b/legacy/evas/src/modules/engines/gl_common/Makefile.am index ddce59921f..a2086b8aa6 100644 --- a/legacy/evas/src/modules/engines/gl_common/Makefile.am +++ b/legacy/evas/src/modules/engines/gl_common/Makefile.am @@ -12,19 +12,40 @@ if BUILD_ENGINE_GL_COMMON noinst_LTLIBRARIES = libevas_engine_gl_common.la libevas_engine_gl_common_la_SOURCES = \ +evas_gl_private.h \ +evas_gl_common.h \ evas_gl_context.c \ -evas_gl_font.c \ -evas_gl_gradient.c \ -evas_gl_image.c \ -evas_gl_line.c \ -evas_gl_misc.c \ -evas_gl_polygon.c \ +evas_gl_shader.c \ +shader/img_frag.h \ +shader/img_vert.h \ +shader/rect_frag.h \ +shader/rect_vert.h \ evas_gl_rectangle.c \ -evas_gl_texture.c +evas_gl_texture.c \ +evas_gl_image.c \ +evas_gl_font.c + + +#evas_gl_gradient.c \ +#evas_gl_line.c \ +#evas_gl_misc.c \ +#evas_gl_polygon.c \ +# libevas_engine_gl_common_la_LIBADD = @EINA_LIBS@ @evas_engine_gl_common_libs@ endif EXTRA_DIST = \ -evas_gl_private.h \ -evas_gl_common.h +shader/compile-s3c6410.sh \ +shader/compile-sgx.sh \ +shader/make-c-bin.sh \ +shader/make-c-str.sh \ +shader/img_frag.shd \ +shader/img_frag_s3c6410.asm \ +shader/img_vert.shd \ +shader/rect_frag.shd \ +shader/rect_frag_s3c6410.asm \ +shader/rect_vert.shd \ +shader/font_frag.shd \ +shader/font_frag_s3c6410.asm \ +shader/font_vert.shd diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h b/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h index a7e62d6f05..8fca47786d 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_common.h @@ -1,15 +1,6 @@ #ifndef EVAS_GL_COMMON_H #define EVAS_GL_COMMON_H -#define EVAS_GL_COMMON_NOCUTOUTS 1 - -/* FIXME: need to handle memory errors */ -/* FIXME: need to handle list errors */ -/* FIXME: need to handle gl errors */ -/* FIXME: need to free textures is texture ream runs out */ -/* FIXME: need to break image textures into meshes if too big */ -/* FIXME: need to page mesh textures if texture alloc fails */ - #include "evas_common.h" #include "evas_private.h" #include "config.h" @@ -26,100 +17,120 @@ # include #else # define GL_GLEXT_PROTOTYPES -#endif /* BUILD_ENGINE_GL_GLEW */ +#endif #ifdef BUILD_ENGINE_GL_QUARTZ # include -# include #else -# include -# include -#endif /* BUILD_ENGINE_GL_QUARTZ */ +# if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) +# if defined(GLES_VARIETY_S3C6410) +# include +# elif defined(GLES_VARIETY_SGX) +# include +# endif +# else +# include +# endif +#endif +#ifndef GL_TEXTURE_RECTANGLE_NV +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#endif + + +#define SHAD_VERTEX 0 +#define SHAD_COLOR 1 +#define SHAD_TEXUV 2 + +typedef struct _Evas_GL_Program Evas_GL_Program; +typedef struct _Evas_GL_Program_Source Evas_GL_Program_Source; typedef struct _Evas_GL_Context Evas_GL_Context; +typedef struct _Evas_GL_Texture_Pool Evas_GL_Texture_Pool; typedef struct _Evas_GL_Texture Evas_GL_Texture; typedef struct _Evas_GL_Image Evas_GL_Image; +typedef struct _Evas_GL_Font_Texture Evas_GL_Font_Texture; + + + typedef struct _Evas_GL_Polygon Evas_GL_Polygon; typedef struct _Evas_GL_Polygon_Point Evas_GL_Polygon_Point; typedef struct _Evas_GL_Gradient Evas_GL_Gradient; -typedef struct _Evas_GL_Font_Texture Evas_GL_Font_Texture; typedef struct _Evas_GL_Font_Texture_Pool Evas_GL_Font_Texture_Pool; typedef struct _Evas_GL_Font_Texture_Pool_Allocation Evas_GL_Font_Texture_Pool_Allocation; +struct _Evas_GL_Program +{ + GLuint vert, frag, prog; +}; + +struct _Evas_GL_Program_Source +{ + const char *src; + const unsigned int *bin; + int bin_size; +}; + struct _Evas_GL_Context { - int w, h; - - unsigned char dither : 1; - unsigned char blend : 1; - unsigned char blend_alpha : 1; - unsigned char r, g, b, a; - - struct { - unsigned char size : 1; - unsigned char dither : 1; - unsigned char blend : 1; - unsigned char color : 1; - unsigned char texture : 1; - unsigned char clip : 1; - unsigned char buf : 1; - unsigned char other : 1; - } change; - - struct { - unsigned char active : 1; - int x, y, w, h; - } clip; - - struct { - int checked : 1; - int sgis_generate_mipmap : 1; - int nv_texture_rectangle : 1; - int arb_texture_non_power_of_two : 1; - int arb_program : 1; - } ext; - - GLenum read_buf; - GLenum write_buf; - - Evas_GL_Texture *texture; - GLuint font_texture; - unsigned char font_texture_rectangle : 1; - unsigned char texture_program : 1; - - int max_texture_depth; - int max_texture_size; - - int references; - - Eina_List *images; - Eina_List *tex_pool; - + int references; + int w, h; RGBA_Draw_Context *dc; + Eina_List *images; + struct { - GLhandleARB prog, fshad; - } yuv422p; + Eina_List *whole; + Eina_List *atlas[33][3]; + } tex; + + struct { + GLint max_texture_units; + GLint max_texture_size; + Eina_Bool tex_npo2 : 1; + Eina_Bool tex_rect : 1; + } info; + struct { + int x, y, w, h; + Eina_Bool active : 1; + } clip; + struct { + Evas_GL_Program rect, img, font, yuv; + GLuint cur_prog; + GLuint cur_tex; + Eina_Bool smooth : 1; + Eina_Bool blend : 1; + } shader; + struct { + int num; + int alloc; + GLint *vertex; + GLfloat *color; + GLfloat *texuv; + } array; + struct { + Eina_Bool size : 1; + } change; + Eina_Bool checked : 1; +}; + +struct _Evas_GL_Texture_Pool +{ + Evas_GL_Context *gc; + GLuint texture; + GLuint format; + int w, h; + int references; + int slot, fslot; + Eina_List *allocations; + Eina_Bool whole : 1; }; struct _Evas_GL_Texture { Evas_GL_Context *gc; - int w, h; - int tw, th; - int uw, uh; - - GLuint texture, texture2, texture3; - - unsigned char smooth : 1; - unsigned char changed : 1; - unsigned char have_mipmaps : 1; - unsigned char rectangle : 1; - unsigned char not_power_of_two : 1; - unsigned char opt : 1; - + Evas_GL_Texture_Pool *pt; + int x, y, w, h; int references; - GLhandleARB prog; }; struct _Evas_GL_Image @@ -128,7 +139,6 @@ struct _Evas_GL_Image RGBA_Image *im; Evas_GL_Texture *tex; RGBA_Image_Loadopts load_opts; - int putcount; int references; struct { int space; @@ -139,6 +149,16 @@ struct _Evas_GL_Image unsigned char cached : 1; }; +struct _Evas_GL_Font_Texture +{ + Evas_GL_Texture *tex; +}; + + + + + + struct _Evas_GL_Polygon { Eina_List *points; @@ -159,17 +179,6 @@ struct _Evas_GL_Gradient unsigned char changed : 1; }; -struct _Evas_GL_Font_Texture -{ - Evas_GL_Context *gc; - int x, y, w, h; - double tx1, ty1, tx2, ty2; - int aw, ah; - GLuint texture; - Evas_GL_Font_Texture_Pool *pool; - Eina_Rectangle *alloc; -}; - struct _Evas_GL_Font_Texture_Pool { Evas_GL_Context *gc; @@ -178,25 +187,47 @@ struct _Evas_GL_Font_Texture_Pool unsigned char rectangle : 1; }; +extern Evas_GL_Program_Source shader_rect_frag_src; +extern Evas_GL_Program_Source shader_rect_vert_src; +extern Evas_GL_Program_Source shader_img_frag_src; +extern Evas_GL_Program_Source shader_img_vert_src; +extern Evas_GL_Program_Source shader_font_frag_src; +extern Evas_GL_Program_Source shader_font_vert_src; + +void glerr(const char *file, const char *func, int line, const char *op); + Evas_GL_Context *evas_gl_common_context_new(void); void evas_gl_common_context_free(Evas_GL_Context *gc); void evas_gl_common_context_use(Evas_GL_Context *gc); void evas_gl_common_context_resize(Evas_GL_Context *gc, int w, int h); -void evas_gl_common_context_color_set(Evas_GL_Context *gc, int r, int g, int b, int a); -void evas_gl_common_context_blend_set(Evas_GL_Context *gc, int blend); -void evas_gl_common_context_dither_set(Evas_GL_Context *gc, int dither); -void evas_gl_common_context_texture_set(Evas_GL_Context *gc, Evas_GL_Texture *tex, int smooth, int w, int h); -void evas_gl_common_context_font_texture_set(Evas_GL_Context *gc, Evas_GL_Font_Texture *ft); -void evas_gl_common_context_clip_set(Evas_GL_Context *gc, int on, int x, int y, int w, int h); -void evas_gl_common_context_read_buf_set(Evas_GL_Context *gc, GLenum buf); -void evas_gl_common_context_write_buf_set(Evas_GL_Context *gc, GLenum buf); -Evas_GL_Texture *evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im, int smooth); -void evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im, int smooth); +void evas_gl_common_context_rectangle_push(Evas_GL_Context *gc, + int x, int y, int w, int h, + int r, int g, int b, int a); +void evas_gl_common_context_image_push(Evas_GL_Context *gc, + Evas_GL_Texture *tex, + double sx, double sy, double sw, double sh, + int x, int y, int w, int h, + int r, int g, int b, int a, + Eina_Bool smooth); +void evas_gl_common_context_font_push(Evas_GL_Context *gc, + Evas_GL_Texture *tex, + double sx, double sy, double sw, double sh, + int x, int y, int w, int h, + int r, int g, int b, int a); +void evas_gl_common_context_flush(Evas_GL_Context *gc); + +void evas_gl_common_shader_program_init(Evas_GL_Program *p, + Evas_GL_Program_Source *vert, + Evas_GL_Program_Source *frag); + +void evas_gl_common_rect_draw(Evas_GL_Context *gc, int x, int y, int w, int h); + +Evas_GL_Texture *evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im); +void evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im); void evas_gl_common_texture_free(Evas_GL_Texture *tex); -void evas_gl_common_texture_mipmaps_build(Evas_GL_Texture *tex, RGBA_Image *im, int smooth); -Evas_GL_Texture *evas_gl_common_ycbcr601pl_texture_new(Evas_GL_Context *gc, unsigned char **rows, int w, int h, int smooth); -void evas_gl_common_ycbcr601pl_texture_update(Evas_GL_Texture *tex, unsigned char **rows, int w, int h, int smooth); +Evas_GL_Texture *evas_gl_common_texture_alpha_new(Evas_GL_Context *gc, DATA8 *pixels, int w, int h, int fh); +void evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels, int w, int h, int fh); Evas_GL_Image *evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo); Evas_GL_Image *evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, DATA32 *data, int alpha, int cspace); @@ -204,6 +235,31 @@ Evas_GL_Image *evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, Evas_GL_Image *evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h, int alpha, int cspace); void evas_gl_common_image_free(Evas_GL_Image *im); void evas_gl_common_image_dirty(Evas_GL_Image *im); +void evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth); + +Evas_GL_Texture *evas_gl_font_texture_new(Evas_GL_Context *gc, RGBA_Font_Glyph *fg); +void evas_gl_font_texture_free(Evas_GL_Texture *ft); +void evas_gl_font_texture_draw(Evas_GL_Context *gc, void *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y); + + + + + + + + + + + + + + + + + + + + Evas_GL_Polygon *evas_gl_common_poly_point_add(Evas_GL_Polygon *poly, int x, int y); Evas_GL_Polygon *evas_gl_common_poly_points_clear(Evas_GL_Polygon *poly); @@ -231,14 +287,9 @@ void evas_gl_common_gradient_draw(Evas_GL_Context *gc, Evas_GL_Grad void evas_gl_common_swap_rect(Evas_GL_Context *gc, int x, int y, int w, int h); -void evas_gl_common_rect_draw(Evas_GL_Context *gc, int x, int y, int w, int h); -void evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth); void evas_gl_common_line_draw(Evas_GL_Context *gc, int x1, int y1, int x2, int y2); void evas_gl_common_poly_draw(Evas_GL_Context *gc, Evas_GL_Polygon *poly); -Evas_GL_Font_Texture *evas_gl_font_texture_new(Evas_GL_Context *gc, RGBA_Font_Glyph *fg); -void evas_gl_font_texture_free(Evas_GL_Font_Texture *ft); -void evas_gl_font_texture_draw(Evas_GL_Context *gc, void *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y); /* FIXME: * diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c index 2f616df570..480f5f19a6 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_context.c @@ -1,16 +1,37 @@ #include "evas_gl_private.h" static void _evas_gl_common_viewport_set(Evas_GL_Context *gc); -static void _evas_gl_common_dither_set(Evas_GL_Context *gc); -static void _evas_gl_common_blend_set(Evas_GL_Context *gc); -static void _evas_gl_common_color_set(Evas_GL_Context *gc); -static void _evas_gl_common_texture_set(Evas_GL_Context *gc); -static void _evas_gl_common_clip_set(Evas_GL_Context *gc); -static void _evas_gl_common_buf_set(Evas_GL_Context *gc); -static void _evas_gl_common_other_set(Evas_GL_Context *gc); +static void shader_array_flush(Evas_GL_Context *gc); static Evas_GL_Context *_evas_gl_common_context = NULL; +void +glerr(const char *file, const char *func, int line, const char *op) +{ + GLenum err = glGetError(); + if (err != GL_NO_ERROR) + { + fprintf(stderr, "GLERR: %s:%i %s(), %s: ", file, line, func, op); + switch (err) + { + case GL_INVALID_ENUM: + fprintf(stderr, "GL_INVALID_ENUM\n"); + break; + case GL_INVALID_VALUE: + fprintf(stderr, "GL_INVALID_VALUE\n"); + break; + case GL_INVALID_OPERATION: + fprintf(stderr, "GL_INVALID_OPERATION\n"); + break; + case GL_OUT_OF_MEMORY: + fprintf(stderr, "GL_OUT_OF_MEMORY\n"); + break; + default: + fprintf(stderr, "0x%x\n", err); + } + } +} + Evas_GL_Context * evas_gl_common_context_new(void) { @@ -23,22 +44,72 @@ evas_gl_common_context_new(void) } gc = calloc(1, sizeof(Evas_GL_Context)); if (!gc) return NULL; - gc->max_texture_depth = 32; - gc->max_texture_size = 2048; - gc->read_buf = GL_BACK; - gc->write_buf = GL_BACK; - gc->dither = 1; - gc->blend = 0; - gc->references = 1; - gc->change.size = 1; - gc->change.dither = 1; - gc->change.blend = 1; - gc->change.color = 1; - gc->change.texture = 1; - gc->change.clip = 1; - gc->change.buf = 1; - gc->change.other = 1; + gc->references = 1; + + _evas_gl_common_context = gc; + + if (!gc->checked) + { + GLint linked; + unsigned int pixel = 0xffffffff; + const GLubyte *ext; + + ext = glGetString(GL_EXTENSIONS); + if (ext) + { + fprintf(stderr, "EXT:\n%s\n", ext); + if ((strstr(ext, "GL_ARB_texture_non_power_of_two")) || + (strstr(ext, "OES_texture_npot"))) + gc->info.tex_npo2 = 1; + if ((strstr(ext, "GL_NV_texture_rectangle")) || + (strstr(ext, "GL_EXT_texture_rectangle"))) + gc->info.tex_rect = 1; + } + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, + &(gc->info.max_texture_units)); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, + &(gc->info.max_texture_size)); + + fprintf(stderr, "max tex size %ix%i\n" + "max units %i\n" + "non-power-2 tex %i\n" + "rect tex %i\n" + , + gc->info.max_texture_size, gc->info.max_texture_size, + gc->info.max_texture_units, + (int)gc->info.tex_npo2, + (int)gc->info.tex_rect + ); + + glDisable(GL_DEPTH_TEST); + glEnable(GL_DITHER); + glDisable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); +// for dest alpha +// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(GL_FALSE); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); +#endif + + evas_gl_common_shader_program_init(&(gc->shader.rect), + &(shader_rect_vert_src), + &(shader_rect_frag_src)); + evas_gl_common_shader_program_init(&(gc->shader.img), + &(shader_img_vert_src), + &(shader_img_frag_src)); + evas_gl_common_shader_program_init(&(gc->shader.font), + &(shader_font_vert_src), + &(shader_font_frag_src)); + _evas_gl_common_viewport_set(gc); + gc->checked = 1; + } return gc; } @@ -48,14 +119,8 @@ evas_gl_common_context_free(Evas_GL_Context *gc) { gc->references--; if (gc->references > 0) return; - if (gc->yuv422p.fshad) - { - glDeleteObjectARB(gc->yuv422p.fshad); - } - if (gc->yuv422p.prog) - { - glDeleteObjectARB(gc->yuv422p.prog); - } + + // free all textures... if (gc == _evas_gl_common_context) _evas_gl_common_context = NULL; free(gc); @@ -65,471 +130,329 @@ void evas_gl_common_context_use(Evas_GL_Context *gc) { if (_evas_gl_common_context == gc) return; - if (!gc->ext.checked) - { - const GLubyte *ext; - - ext = glGetString(GL_EXTENSIONS); - if (ext) - { -// if (strstr(ext, "GL_SGIS_generate_mipmap")) gc->ext.sgis_generate_mipmap = 1; -// if (strstr(ext, "GL_NV_texture_rectangle")) gc->ext.nv_texture_rectangle = 1; -// if (strstr(ext, "GL_EXT_texture_rectangle")) gc->ext.nv_texture_rectangle = 1; - if (strstr(ext, "GL_ARB_texture_non_power_of_two")) gc->ext.arb_texture_non_power_of_two = 1; - if (strstr(ext, "GL_ARB_shader_objects") && strstr(ext, "GL_ARB_vertex_shader") - && strstr(ext, "GL_ARB_fragment_shader") && strstr(ext, "GL_ARB_shading_language")) - gc->ext.arb_program = 1; -// printf("GL EXT supported: GL_SGIS_generate_mipmap = %x\n", gc->ext.sgis_generate_mipmap); -// printf("GL EXT supported: GL_NV_texture_rectangle = %x\n", gc->ext.nv_texture_rectangle); -// printf("GL EXT supported: GL_ARB_texture_non_power_of_two = %x\n", gc->ext.arb_texture_non_power_of_two); -// this causes at least nvidia's drivers to go into pathological pain when -// changing textures a lot (doing video). so we wont do anything with this -// for now, but it does work. -// gc->ext.arb_texture_non_power_of_two = 0; printf("DISABLE GL_ARB_texture_non_power_of_two\n"); -// gc->ext.nv_texture_rectangle = 0; printf("DISABLE GL_NV_texture_rectangle\n"); - } - else - { -// printf("GL EXT supported: No extensions!!!!!\n"); - } - - if (gc->ext.arb_program) - { - gc->yuv422p.prog = glCreateProgramObjectARB(); - // on an nv 6600gt this is fast - but on a 5500fx its DEAD SLOW!!!!! - // if (!gc->ext.arb_texture_non_power_of_two) return NULL; - /* BEGIN LEAK */ - gc->yuv422p.fshad = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); - { - const char *code = - "uniform sampler2D ytex, utex, vtex;\n" - "void main(void) {\n" - " float r, g, b, y, u, v;\n" - " y = texture2D(ytex, gl_TexCoord[0].st).r;\n" - " u = texture2D(utex, gl_TexCoord[0].st).r;\n" - " v = texture2D(vtex, gl_TexCoord[0].st).r;\n" - " y = (y - 0.0625) * 1.164;\n" - " u = u - 0.5;\n" - " v = v - 0.5;\n" - " r = y + (1.402 * v);\n" - " g = y - (0.34414 * u) - (0.71414 * v);\n" - " b = y + (1.772 * u);\n" - " gl_FragColor = vec4(r * gl_Color.r * gl_Color.a, g * gl_Color.g * gl_Color.a, b * gl_Color.b * gl_Color.a, gl_Color.a);\n" - "}\n"; - glShaderSourceARB(gc->yuv422p.fshad, 1, &code, NULL); - } - glCompileShaderARB(gc->yuv422p.fshad); - glAttachObjectARB(gc->yuv422p.prog, gc->yuv422p.fshad); - /* END LEAK - something in the above leaks... beats me what. */ - glLinkProgramARB(gc->yuv422p.prog); - - glUseProgramObjectARB(gc->yuv422p.prog); - glUniform1iARB(glGetUniformLocationARB(gc->yuv422p.prog, "ytex"), 0); - glUniform1iARB(glGetUniformLocationARB(gc->yuv422p.prog, "utex"), 1); - glUniform1iARB(glGetUniformLocationARB(gc->yuv422p.prog, "vtex"), 2); - glUseProgramObjectARB(0); - } - - gc->ext.checked = 1; - } - _evas_gl_common_context = gc; - _evas_gl_common_viewport_set(gc); - _evas_gl_common_dither_set(gc); - _evas_gl_common_blend_set(gc); - _evas_gl_common_color_set(gc); - _evas_gl_common_texture_set(gc); - _evas_gl_common_texture_set(gc); - _evas_gl_common_clip_set(gc); - _evas_gl_common_buf_set(gc); - _evas_gl_common_other_set(gc); +// _evas_gl_common_context = gc; } void evas_gl_common_context_resize(Evas_GL_Context *gc, int w, int h) { - //if ((gc->w == w) && (gc->h == h)) return; + if ((gc->w == w) && (gc->h == h)) return; gc->change.size = 1; gc->w = w; gc->h = h; if (_evas_gl_common_context == gc) _evas_gl_common_viewport_set(gc); } -void -evas_gl_common_context_color_set(Evas_GL_Context *gc, int r, int g, int b, int a) +#define PUSH_VERTEX(x, y, z) \ + gc->array.vertex[nv++] = x; \ + gc->array.vertex[nv++] = y; \ + gc->array.vertex[nv++] = z +#define PUSH_COLOR(r, g, b, a) \ + gc->array.color[nc++] = r; \ + gc->array.color[nc++] = g; \ + gc->array.color[nc++] = b; \ + gc->array.color[nc++] = a +#define PUSH_TEXUV(u, v) \ + gc->array.texuv[nu++] = u; \ + gc->array.texuv[nu++] = v +#define COLOR_FLOAT(r, g, b, a, fr, fg, fb, fa) \ + fr = ((GLfloat)(r)) / 255.0; \ + fg = ((GLfloat)(g)) / 255.0; \ + fb = ((GLfloat)(b)) / 255.0; \ + fa = ((GLfloat)(a)) / 255.0 + +static void +_evas_gl_common_context_array_alloc(Evas_GL_Context *gc) { - if (r < 0) r = 0; - else if (r > 255) r = 255; - if (g < 0) g = 0; - else if (g > 255) g = 255; - if (b < 0) b = 0; - else if (b > 255) b = 255; - if (a < 0) a = 0; - else if (a > 255) a = 255; - if ((gc->r == r) && (gc->g == g) && (gc->b == b) && (gc->a == a)) return; - gc->change.color = 1; - gc->r = r; - gc->g = g; - gc->b = b; - gc->a = a; - if (_evas_gl_common_context == gc) _evas_gl_common_color_set(gc); + if (gc->array.num <= gc->array.alloc) return; + gc->array.alloc += 1024; + gc->array.vertex = realloc(gc->array.vertex, + gc->array.alloc * sizeof(GLint) * 3); + gc->array.color = realloc(gc->array.color, + gc->array.alloc * sizeof(GLfloat) * 4); + gc->array.texuv = realloc(gc->array.texuv, + gc->array.alloc * sizeof(GLfloat) * 2); } void -evas_gl_common_context_blend_set(Evas_GL_Context *gc, int blend) +evas_gl_common_context_rectangle_push(Evas_GL_Context *gc, + int x, int y, int w, int h, + int r, int g, int b, int a) { - if (blend == 1) + int pnum, nv, nc, nu, nt, i; + GLfloat rr, gg, bb, aa; + Eina_Bool blend = 0; + + if (a < 255) blend = 1; + if ((gc->shader.cur_tex != 0) + || (gc->shader.cur_prog != gc->shader.rect.prog) + || (gc->shader.blend != blend) + ) { - if (gc->blend) return; - gc->change.blend = 1; - gc->blend = 1; - gc->blend_alpha = 0; + shader_array_flush(gc); + gc->shader.cur_tex = 0; + gc->shader.cur_prog = gc->shader.rect.prog; + gc->shader.blend = blend; } - else if (blend == 2) + + pnum = gc->array.num; + nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4; + gc->array.num += 6; + _evas_gl_common_context_array_alloc(gc); + + PUSH_VERTEX(x , y , 0); + PUSH_VERTEX(x + w, y , 0); + PUSH_VERTEX(x , y + h, 0); + + PUSH_VERTEX(x + w, y , 0); + PUSH_VERTEX(x + w, y + h, 0); + PUSH_VERTEX(x , y + h, 0); + + for (i = 0; i < 6; i++) { - if (gc->blend_alpha) return; - gc->change.blend = 1; - gc->blend = 0; - gc->blend_alpha = 1; + PUSH_TEXUV(0.0, 0.0); + } + COLOR_FLOAT(r, g, b, a, rr, gg, bb, aa); + for (i = 0; i < 6; i++) + { + PUSH_COLOR(rr, gg, bb, aa); + } +} + +void +evas_gl_common_context_image_push(Evas_GL_Context *gc, + Evas_GL_Texture *tex, + double sx, double sy, double sw, double sh, + int x, int y, int w, int h, + int r, int g, int b, int a, + Eina_Bool smooth) +{ + int pnum, nv, nc, nu, nt, i; + GLfloat rr, gg, bb, aa, tx1, tx2, ty1, ty2; + Eina_Bool blend = 1; + + if (tex->pt->format == GL_RGB) blend = 0; + if (a < 255) blend = 1; + + if ((gc->shader.cur_tex != tex->pt->texture) + || (gc->shader.cur_prog != gc->shader.img.prog) + || (gc->shader.smooth != smooth) + || (gc->shader.blend != blend) + ) + { + shader_array_flush(gc); + gc->shader.cur_tex = tex->pt->texture; + gc->shader.cur_prog = gc->shader.img.prog; + gc->shader.smooth = smooth; + gc->shader.blend = blend; + } + + pnum = gc->array.num; + nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4; + gc->array.num += 6; + _evas_gl_common_context_array_alloc(gc); + + tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w; + ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h; + tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w; + ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h; + + PUSH_VERTEX(x , y , 0); + PUSH_VERTEX(x + w, y , 0); + PUSH_VERTEX(x , y + h, 0); + + PUSH_TEXUV(tx1, ty1); + PUSH_TEXUV(tx2, ty1); + PUSH_TEXUV(tx1, ty2); + + PUSH_VERTEX(x + w, y , 0); + PUSH_VERTEX(x + w, y + h, 0); + PUSH_VERTEX(x , y + h, 0); + + PUSH_TEXUV(tx2, ty1); + PUSH_TEXUV(tx2, ty2); + PUSH_TEXUV(tx1, ty2); + + COLOR_FLOAT(r, g, b, a, rr, gg, bb, aa); + for (i = 0; i < 6; i++) + { + PUSH_COLOR(rr, gg, bb, aa); + } +} + +void +evas_gl_common_context_font_push(Evas_GL_Context *gc, + Evas_GL_Texture *tex, + double sx, double sy, double sw, double sh, + int x, int y, int w, int h, + int r, int g, int b, int a) +{ + int pnum, nv, nc, nu, nt, i; + GLfloat rr, gg, bb, aa, tx1, tx2, ty1, ty2; + + if ((gc->shader.cur_tex != tex->pt->texture) + || (gc->shader.cur_prog != gc->shader.font.prog) + || (gc->shader.smooth != 0) + || (gc->shader.blend != 1) + ) + { + shader_array_flush(gc); + gc->shader.cur_tex = tex->pt->texture; + gc->shader.cur_prog = gc->shader.font.prog; + gc->shader.smooth = 0; + gc->shader.blend = 1; + } + + pnum = gc->array.num; + nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4; + gc->array.num += 6; + _evas_gl_common_context_array_alloc(gc); + + tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w; + ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h; + tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w; + ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h; + + PUSH_VERTEX(x , y , 0); + PUSH_VERTEX(x + w, y , 0); + PUSH_VERTEX(x , y + h, 0); + + PUSH_TEXUV(tx1, ty1); + PUSH_TEXUV(tx2, ty1); + PUSH_TEXUV(tx1, ty2); + + PUSH_VERTEX(x + w, y , 0); + PUSH_VERTEX(x + w, y + h, 0); + PUSH_VERTEX(x , y + h, 0); + + PUSH_TEXUV(tx2, ty1); + PUSH_TEXUV(tx2, ty2); + PUSH_TEXUV(tx1, ty2); + + COLOR_FLOAT(r, g, b, a, rr, gg, bb, aa); + for (i = 0; i < 6; i++) + { + PUSH_COLOR(rr, gg, bb, aa); + } +} + +void +evas_gl_common_context_flush(Evas_GL_Context *gc) +{ + shader_array_flush(gc); +// fprintf(stderr, "------------FRAME: done\n"); +} + +static void +shader_array_flush(Evas_GL_Context *gc) +{ + if (gc->array.num <= 0) return; + +// fprintf(stderr, " flush array %i\n", gc->array.num); + glUseProgram(gc->shader.cur_prog); + + if (gc->shader.cur_tex) + { + glBindTexture(GL_TEXTURE_2D, gc->shader.cur_tex); } else { - if ((!gc->blend) && (!gc->blend_alpha)) return; - gc->change.blend = 1; - gc->blend = 0; - gc->blend_alpha = 0; + glBindTexture(GL_TEXTURE_2D, gc->shader.cur_tex); } - if (_evas_gl_common_context == gc) _evas_gl_common_blend_set(gc); + if (gc->shader.blend) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); + if (gc->shader.smooth) + { +#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); +#endif + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + else + { +#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); +#endif + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + glEnableVertexAttribArray(SHAD_VERTEX); + glVertexAttribPointer(SHAD_VERTEX, 3, GL_INT, GL_FALSE, 0, gc->array.vertex); + + glEnableVertexAttribArray(SHAD_COLOR); + glVertexAttribPointer(SHAD_COLOR, 4, GL_FLOAT, GL_FALSE, 0, gc->array.color); + + glEnableVertexAttribArray(SHAD_TEXUV); + glVertexAttribPointer(SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0, gc->array.texuv); + + glDrawArrays(GL_TRIANGLES, 0, gc->array.num); + + gc->shader.cur_prog = 0; + gc->shader.cur_tex = 0; + + free(gc->array.vertex); + free(gc->array.color); + free(gc->array.texuv); + + gc->array.vertex = NULL; + gc->array.color = NULL; + gc->array.texuv = NULL; + + gc->array.num = 0; + gc->array.alloc = 0; } -void -evas_gl_common_context_dither_set(Evas_GL_Context *gc, int dither) +static void +matrix_ident(GLfloat *m) { - if (((dither) && (gc->dither)) || ((!dither) && (!gc->dither))) return; - gc->change.dither = 1; - gc->dither = dither; - if (_evas_gl_common_context == gc) _evas_gl_common_dither_set(gc); + memset(m, 0, 16 * sizeof(GLfloat)); + m[0] = m[5] = m[10] = m[15] = 1.0; } -void -evas_gl_common_context_texture_set(Evas_GL_Context *gc, Evas_GL_Texture *tex, int smooth, int w, int h) +static void +matrix_ortho(GLfloat *m, GLfloat l, GLfloat r, GLfloat t, GLfloat b, GLfloat near, GLfloat far) { - if (gc->font_texture > 0) - { - gc->font_texture = 0; - gc->change.texture = 1; - } - if (gc->texture != tex) - { - if (gc->texture) gc->texture->references--; - gc->texture = tex; - gc->change.texture = 1; - if (tex) tex->references++; - } - if (tex) - { - if (((smooth) && (!tex->smooth)) || - ((!smooth) && (tex->smooth))) - { - tex->smooth = smooth; - tex->changed = 1; - } - tex->uw = w; - tex->uh = h; - } - if (_evas_gl_common_context == gc) _evas_gl_common_texture_set(gc); -} - -void -evas_gl_common_context_font_texture_set(Evas_GL_Context *gc, Evas_GL_Font_Texture *ft) -{ - if (gc->texture) - { - if (gc->texture) gc->texture->references--; - gc->texture = NULL; - gc->change.texture = 1; - } - if (gc->font_texture != ft->texture) - { - gc->font_texture = ft->texture; - gc->font_texture_rectangle = ft->pool->rectangle; - gc->change.texture = 1; - } - if (!gc->change.texture) return; - if (_evas_gl_common_context == gc) _evas_gl_common_texture_set(gc); -} - -void -evas_gl_common_context_clip_set(Evas_GL_Context *gc, int on, int x, int y, int w, int h) -{ - if (x < 0) - { - w += x; - x = 0; - } - if (y < 0) - { - h += y; - y = 0; - } - if (w < 0) w = 0; - if (h < 0) h = 0; - if (((!on) && (!gc->clip.active)) || - ((on) && (gc->clip.active) && - (x == gc->clip.x) && (y == gc->clip.y) && - (w == gc->clip.w) && (h == gc->clip.h))) - return; - gc->change.clip = 1; - gc->clip.active = on; - gc->clip.x = x; - gc->clip.y = y; - gc->clip.w = w; - gc->clip.h = h; - if (_evas_gl_common_context == gc) _evas_gl_common_clip_set(gc); -} - -void -evas_gl_common_context_read_buf_set(Evas_GL_Context *gc, GLenum buf) -{ - if (gc->read_buf == buf) return; - gc->change.buf = 1; - gc->read_buf = buf; - if (_evas_gl_common_context == gc) _evas_gl_common_buf_set(gc); -} - -void -evas_gl_common_context_write_buf_set(Evas_GL_Context *gc, GLenum buf) -{ - if (gc->write_buf == buf) return; - gc->change.buf = 1; - gc->write_buf = buf; - if (_evas_gl_common_context == gc) _evas_gl_common_buf_set(gc); + m[0] = 2.0 / (r - l); + m[1] = m[2] = m[3] = 0.0; + + m[4] = 0.0; + m[5] = 2.0 / (t - b); + m[6] = m[7] = 0.0; + + m[8] = m[9] = 0.0; + m[10] = -(2.0 / (far - near)); + m[11] = 0.0; + + m[12] = -((r + l)/(r - l)); + m[13] = -((t + b)/(t - b)); + m[14] = -((near + far)/(far - near)); + m[15] = 1.0; } static void _evas_gl_common_viewport_set(Evas_GL_Context *gc) { + GLfloat proj[16]; + if (!gc->change.size) return; - glViewport(0, 0, gc->w, gc->h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, gc->w, 0, gc->h, -1, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glScalef(1, -1, 1); - glTranslatef(0, - gc->h, 0); gc->change.size = 0; -} - -static void -_evas_gl_common_dither_set(Evas_GL_Context *gc) -{ - if (!gc->change.dither) return; - if (gc->dither) - glEnable(GL_DITHER); - else - glDisable(GL_DITHER); - gc->change.dither = 0; -} - -static void -_evas_gl_common_blend_set(Evas_GL_Context *gc) -{ - if (!gc->change.blend) return; - if (gc->blend_alpha) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else if (gc->blend) - { - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - else - glDisable(GL_BLEND); - gc->change.blend = 0; -} - -static void -_evas_gl_common_color_set(Evas_GL_Context *gc) -{ - if (!gc->change.color) return; - glColor4d((double)gc->r / 255.0, - (double)gc->g / 255.0, - (double)gc->b / 255.0, - (double)gc->a / 255.0); - gc->change.color = 0; -} - -static void -_evas_gl_common_texture_set(Evas_GL_Context *gc) -{ - if (!gc->change.texture) return; - if (gc->font_texture > 0) - { - if (gc->texture_program) - { - glUseProgramObjectARB(0); - - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE2); - glDisable(GL_TEXTURE_2D); - gc->texture_program = 0; - } - if (gc->font_texture_rectangle) - { - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_RECTANGLE_NV); - glBindTexture(GL_TEXTURE_RECTANGLE_NV, gc->font_texture); - } - else - { - glActiveTexture(GL_TEXTURE0); - if (gc->ext.nv_texture_rectangle) - glDisable(GL_TEXTURE_RECTANGLE_NV); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, gc->font_texture); - } - } - else if (gc->texture) - { - if (gc->texture->rectangle) - { - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_RECTANGLE_NV); - glBindTexture(GL_TEXTURE_RECTANGLE_NV, gc->texture->texture); - } - else - { - if (gc->ext.nv_texture_rectangle) glDisable(GL_TEXTURE_RECTANGLE_NV); - if ((gc->texture->prog) && - (gc->texture->texture2) && (gc->texture->texture3)) - { - gc->texture_program = 1; - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, gc->texture->texture); - - glActiveTexture(GL_TEXTURE1); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, gc->texture->texture2); - - glActiveTexture(GL_TEXTURE2); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, gc->texture->texture3); - glUseProgramObjectARB(gc->texture->prog); - } - else - { - if (gc->texture_program) - { - glUseProgramObjectARB(0); - - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE2); - glDisable(GL_TEXTURE_2D); - gc->texture_program = 0; - } - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, gc->texture->texture); - glEnable(GL_TEXTURE_2D); - } - } - if (gc->texture->rectangle) - { - if (gc->texture->changed) - { - gc->texture->changed = 0; - } - } - else - { - if (gc->texture->changed) - { - if (gc->texture->rectangle) - { - if (gc->texture->smooth) - { - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - } - else - { - if (gc->texture->smooth) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -// if (gc->texture->have_mipmaps) -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); -// else - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - } - gc->texture->changed = 0; - } - } - } - else if (gc->font_texture == 0) - { - glDisable(GL_TEXTURE_2D); - if (gc->ext.nv_texture_rectangle) glDisable(GL_TEXTURE_RECTANGLE_NV); - } - gc->change.texture = 0; -} - -static void -_evas_gl_common_clip_set(Evas_GL_Context *gc) -{ - if (!gc->change.clip) return; - /* might be faster using clip planes ??? glClipPlane() */ - if (gc->clip.active) - { - glEnable(GL_SCISSOR_TEST); - glScissor(gc->clip.x, - gc->h - gc->clip.y - gc->clip.h, - gc->clip.w, - gc->clip.h); - } - else - glDisable(GL_SCISSOR_TEST); - gc->change.clip = 0; -} - -static void -_evas_gl_common_buf_set(Evas_GL_Context *gc) -{ - if (!gc->change.buf) return; - glDrawBuffer(gc->write_buf); - glReadBuffer(gc->read_buf); - gc->change.buf = 0; -} - -static void -_evas_gl_common_other_set(Evas_GL_Context *gc) -{ - if (!gc->change.other) return; - glShadeModel(GL_FLAT); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); -// glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - glDisable(GL_LINE_SMOOTH); - glDisable(GL_CULL_FACE); - glDepthMask(GL_FALSE); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - gc->change.other = 0; + + glViewport(0, 0, gc->w, gc->h); + + matrix_ident(proj); + matrix_ortho(proj, 0, gc->w, 0, gc->h, -1.0, 1.0); + + glUseProgram(gc->shader.rect.prog); + glUniformMatrix4fv(glGetUniformLocation(gc->shader.rect.prog, "mvp"), 1, + GL_FALSE, proj); + glUseProgram(gc->shader.img.prog); + glUniformMatrix4fv(glGetUniformLocation(gc->shader.img.prog, "mvp"), 1, + GL_FALSE, proj); + glUseProgram(gc->shader.font.prog); + glUniformMatrix4fv(glGetUniformLocation(gc->shader.font.prog, "mvp"), 1, + GL_FALSE, proj); } diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_font.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_font.c index e895b00983..439a72db33 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_font.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_font.c @@ -1,42 +1,28 @@ #include "evas_gl_private.h" -static Eina_Rectangle *_evas_gl_font_texture_pool_request(Evas_GL_Context *gc, int w, int h); -static void _evas_gl_font_texture_pool_relinquish(Eina_Rectangle *er); -static int _evas_gl_font_texture_pool_rect_find(Evas_GL_Font_Texture_Pool *fp, int w, int h, int *x, int *y); - -Evas_GL_Font_Texture * +Evas_GL_Texture * evas_gl_font_texture_new(Evas_GL_Context *gc, RGBA_Font_Glyph *fg) { - Evas_GL_Font_Texture *ft; + Evas_GL_Texture *tex; DATA8 *data; - int w, h, j; - - int nw; + int w, h, j, nw; DATA8 *ndata; + int fh; - if (fg->ext_dat) return fg->ext_dat; + if (fg->ext_dat) return fg->ext_dat; // FIXME: one engine at a time can do this :( w = fg->glyph_out->bitmap.width; h = fg->glyph_out->bitmap.rows; - if ((w == 0) || (h == 0)) return NULL; - ft = calloc(1, sizeof(Evas_GL_Font_Texture)); - if (!ft) return NULL; data = fg->glyph_out->bitmap.buffer; j = fg->glyph_out->bitmap.pitch; if (j < w) j = w; - ft->gc = gc; - /* bug bug! glTexSubImage2D need a multiple of 4 pixels horizontally! :( */ nw = ((w + 3) / 4 ) * 4; - ndata = malloc(nw *h); - if (!ndata) - { - free(ft); - return NULL; - } + ndata = alloca(nw *h); + if (!ndata) return NULL; if (fg->glyph_out->bitmap.num_grays == 256) { int x, y; @@ -60,7 +46,7 @@ evas_gl_font_texture_new(Evas_GL_Context *gc, RGBA_Font_Glyph *fg) int bi, bj, end; const DATA8 bitrepl[2] = {0x0, 0xff}; - tmpbuf = malloc(w); + tmpbuf = alloca(w); if (tmpbuf) { int x, y; @@ -91,252 +77,118 @@ evas_gl_font_texture_new(Evas_GL_Context *gc, RGBA_Font_Glyph *fg) p2++; } } - free(tmpbuf); } } - - /* where in pool texture does this live */ - ft->w = w; - ft->h = h; - ft->aw = nw; - ft->ah = h; - - ft->alloc = _evas_gl_font_texture_pool_request(gc, ft->aw, ft->ah); - if (!ft->alloc) - { - free(ndata); - free(ft); - return NULL; - } - ft->x = ft->alloc->x; - ft->y = ft->alloc->y; - ft->pool = eina_rectangle_pool_data_get(eina_rectangle_pool_get(ft->alloc)); - ft->texture = ft->pool->texture; - if (ft->pool->rectangle) - { - glEnable(GL_TEXTURE_RECTANGLE_NV); - glBindTexture(GL_TEXTURE_RECTANGLE_NV, ft->texture); - glTexSubImage2D(GL_TEXTURE_RECTANGLE_NV, 0, - ft->x, ft->y, nw, ft->h, - GL_ALPHA, GL_UNSIGNED_BYTE, ndata); - } - else - { - glBindTexture(GL_TEXTURE_2D, ft->texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, - ft->x, ft->y, nw, ft->h, - GL_ALPHA, GL_UNSIGNED_BYTE, ndata); - } - if (ndata) free(ndata); - if (gc->texture) - { - if (gc->texture) gc->texture->references--; - gc->texture = NULL; - } - gc->font_texture = ft->texture; - gc->font_texture_rectangle = ft->pool->rectangle; - gc->change.texture = 1; - if (ft->pool->rectangle) - { - ft->tx1 = ft->x; - ft->ty1 = ft->y; - ft->tx2 = ft->x + ft->w; - ft->ty2 = ft->y + ft->h; - } - else - { - ft->tx1 = (double)(ft->x ) / (double)(ft->pool->w); - ft->ty1 = (double)(ft->y ) / (double)(ft->pool->h); - ft->tx2 = (double)(ft->x + ft->w) / (double)(ft->pool->w); - ft->ty2 = (double)(ft->y + ft->h) / (double)(ft->pool->h); - } - - return ft; +// fh = h; + fh = fg->fi->max_h; + tex = evas_gl_common_texture_alpha_new(gc, ndata, w, h, fh); + return tex; } void -evas_gl_font_texture_free(Evas_GL_Font_Texture *ft) +evas_gl_font_texture_free(Evas_GL_Texture *tex) { - if (!ft) return; - if (ft->gc->font_texture == ft->texture) - { - ft->gc->font_texture = 0; - ft->gc->change.texture = 1; - } - _evas_gl_font_texture_pool_relinquish(ft->alloc); - free(ft); + if (!tex) return; + evas_gl_common_texture_free(tex); } void evas_gl_font_texture_draw(Evas_GL_Context *gc, void *surface __UNUSED__, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y) { - Evas_GL_Font_Texture *ft; - - if (dc != gc->dc) - return; - - /* 35 */ - ft = fg->ext_dat; - if (!ft) return; -// if (surface == 0) + Evas_GL_Texture *tex; + Cutout_Rects *rects; + Cutout_Rect *rct; + int r, g, b, a; + double ssx, ssy, ssw, ssh; + int c, cx, cy, cw, ch; + int i; + int sx, sy, sw, sh; + + if (dc != gc->dc) return; + tex = fg->ext_dat; + if (!tex) return; + a = (dc->col.col >> 24) & 0xff; + if (a == 0) return; + r = (dc->col.col >> 16) & 0xff; + g = (dc->col.col >> 8 ) & 0xff; + b = (dc->col.col ) & 0xff; + sx = 0; sy = 0; sw = tex->w, sh = tex->h; + if ((!gc->dc->cutout.rects) +// || (gc->dc->cutout.active > 32) + ) { - int r, g, b, a; - - a = (dc->col.col >> 24) & 0xff; - if (a == 0) return; - r = (dc->col.col >> 16) & 0xff; - g = (dc->col.col >> 8 ) & 0xff; - b = (dc->col.col ) & 0xff; - /* have to un-premul the color - as we are using blend mode 2 (non-premul blend) */ - r = (r * 255) / a; - g = (g * 255) / a; - b = (b * 255) / a; - evas_gl_common_context_color_set(gc, r, g, b, a); - if (dc->clip.use) - evas_gl_common_context_clip_set(gc, 1, - dc->clip.x, dc->clip.y, - dc->clip.w, dc->clip.h); - else - evas_gl_common_context_clip_set(gc, 0, - 0, 0, 0, 0); - evas_gl_common_context_blend_set(gc, 2); - evas_gl_common_context_read_buf_set(gc, GL_BACK); - evas_gl_common_context_write_buf_set(gc, GL_BACK); + if (gc->dc->clip.use) + { + int nx, ny, nw, nh; + + nx = x; ny = y; nw = tex->w; nh = tex->h; + RECTS_CLIP_TO_RECT(nx, ny, nw, nh, + gc->dc->clip.x, gc->dc->clip.y, + gc->dc->clip.w, gc->dc->clip.h); + if ((nw < 1) || (nh < 1)) return; + if ((nx == x) && (ny == y) && (nw == tex->w) && (nh == tex->h)) + { + evas_gl_common_context_font_push(gc, tex, + sx, sy, sw, sh, + x, y, tex->w, tex->h, + r, g, b, a); + return; + } + ssx = (double)sx + ((double)(sw * (nx - x)) / (double)(tex->w)); + ssy = (double)sy + ((double)(sh * (ny - y)) / (double)(tex->h)); + ssw = ((double)sw * (double)(nw)) / (double)(tex->w); + ssh = ((double)sh * (double)(nh)) / (double)(tex->h); + evas_gl_common_context_font_push(gc, tex, + ssx, ssy, ssw, ssh, + nx, ny, nw, nh, + r, g, b, a); + } + else + { + evas_gl_common_context_font_push(gc, tex, + sx, sy, sw, sh, + x, y, tex->w, tex->h, + r, g, b, a); + } + return; } - /* 32 */ - evas_gl_common_context_font_texture_set(gc, ft); - /* 32 */ - glBegin(GL_QUADS); - glTexCoord2d(ft->tx1, ft->ty1); glVertex2i(x , y ); - glTexCoord2d(ft->tx2, ft->ty1); glVertex2i(x + ft->w, y ); - glTexCoord2d(ft->tx2, ft->ty2); glVertex2i(x + ft->w, y + ft->h); - glTexCoord2d(ft->tx1, ft->ty2); glVertex2i(x , y + ft->h); - glEnd(); - /* 28 */ + /* save out clip info */ + c = gc->dc->clip.use; cx = gc->dc->clip.x; cy = gc->dc->clip.y; cw = gc->dc->clip.w; ch = gc->dc->clip.h; + evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->w, gc->h); + evas_common_draw_context_clip_clip(gc->dc, x, y, tex->w, tex->h); + /* our clip is 0 size.. abort */ + if ((gc->dc->clip.w <= 0) || (gc->dc->clip.h <= 0)) + { + gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch; + return; + } + rects = evas_common_draw_context_apply_cutouts(dc); + for (i = 0; i < rects->active; ++i) + { + int nx, ny, nw, nh; + + rct = rects->rects + i; + nx = x; ny = y; nw = tex->w; nh = tex->h; + RECTS_CLIP_TO_RECT(nx, ny, nw, nh, rct->x, rct->y, rct->w, rct->h); + if ((nw < 1) || (nh < 1)) continue; + if ((nx == x) && (ny == y) && (nw == tex->w) && (nh == tex->h)) + { + evas_gl_common_context_font_push(gc, tex, + sx, sy, sw, sh, + x, y, tex->w, tex->h, + r, g, b, a); + continue; + } + ssx = (double)sx + ((double)(sw * (nx - x)) / (double)(tex->w)); + ssy = (double)sy + ((double)(sh * (ny - y)) / (double)(tex->h)); + ssw = ((double)sw * (double)(nw)) / (double)(tex->w); + ssh = ((double)sh * (double)(nh)) / (double)(tex->h); + evas_gl_common_context_font_push(gc, tex, + ssx, ssy, ssw, ssh, + nx, ny, nw, nh, + r, g, b, a); + } + evas_common_draw_context_apply_clear_cutouts(rects); + /* restore clip info */ + gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch; } - -static Eina_Rectangle * -_evas_gl_font_texture_pool_request(Evas_GL_Context *gc, int w, int h) -{ - Evas_GL_Font_Texture_Pool *fp; - Eina_Rectangle_Pool *rp; - Eina_Rectangle *er; - Eina_List *l; - int minw = 256; - int minh = 256; - int shift; - - EINA_LIST_FOREACH(gc->tex_pool, l, rp) - { - er = eina_rectangle_pool_request(rp, w, h); - if (er) return er; - } - - /* need new font texture pool entry */ - /* minimum size either minw x minh OR the size of glyph up to power 2 */ - if (w > minw) - { - minw = w; - shift = 1; while (minw > shift) shift = shift << 1; minw = shift; - } - if (h > minh) - { - minh = h; - shift = 1; while (minh > shift) shift = shift << 1; minh = shift; - } - - rp = eina_rectangle_pool_new(minw, minh); - if (!rp) return NULL; - - fp = calloc(1, sizeof(Evas_GL_Font_Texture_Pool)); - if (!fp) - { - eina_rectangle_pool_free(rp); - return NULL; - } - - gc->tex_pool = eina_list_append(gc->tex_pool, rp); - if (eina_error_get()) - { - eina_rectangle_pool_free(rp); - free(fp); - return NULL; - } - fp->gc = gc; - fp->w = minw; - fp->h = minh; - if (gc->ext.nv_texture_rectangle) fp->rectangle = 1; - - eina_rectangle_pool_data_set(rp, fp); - - /* we dont want this mipmapped if sgis_generate_mipmap will mipmap it */ - if (gc->ext.sgis_generate_mipmap) - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_FALSE); -// glEnable(GL_TEXTURE_2D); - if (fp->rectangle) - { - glEnable(GL_TEXTURE_RECTANGLE_NV); - glGenTextures(1, &(fp->texture)); - /* FIXME check gl error */ - - glBindTexture(GL_TEXTURE_RECTANGLE_NV, fp->texture); - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, - GL_ALPHA4, fp->w, fp->h, 0, - GL_ALPHA, GL_UNSIGNED_BYTE, NULL); - /* FIXME check gl error */ - } - else - { - glEnable(GL_TEXTURE_2D); - glGenTextures(1, &(fp->texture)); - /* FIXME check gl error */ - - glBindTexture(GL_TEXTURE_2D, fp->texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, - GL_ALPHA4, fp->w, fp->h, 0, - GL_ALPHA, GL_UNSIGNED_BYTE, NULL); - /* FIXME check gl error */ - } - - /* new allocation entirely */ - er = eina_rectangle_pool_request(rp, w, h); - if (!er) - { - gc->tex_pool = eina_list_remove(gc->tex_pool, rp); - eina_rectangle_pool_free(rp); - glDeleteTextures(1, &(fp->texture)); - free(fp); - return NULL; - } - - return er; -} - -static void -_evas_gl_font_texture_pool_relinquish(Eina_Rectangle *er) -{ - Evas_GL_Font_Texture_Pool *fp; - Eina_Rectangle_Pool *pool; - - pool = eina_rectangle_pool_get(er); - fp = eina_rectangle_pool_data_get(pool); - - eina_rectangle_pool_release(er); - - if (eina_rectangle_pool_count(pool) == 0) - { - fp->gc->tex_pool = eina_list_remove(fp->gc->tex_pool, pool); - eina_rectangle_pool_free(pool); - glDeleteTextures(1, &(fp->texture)); - free(fp); - } -} - diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c index 50f85fd758..435f5d07e9 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_image.c @@ -26,11 +26,6 @@ evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key if (!im) return NULL; im->references = 1; im->im = im_im; - if (!im->im) - { - free(im); - return NULL; - } im->gc = gc; im->references = 1; im->cached = 1; @@ -89,7 +84,6 @@ evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, DATA32 *da im->cached = 1; gc->images = eina_list_prepend(gc->images, im); */ - printf("new im cs = %i\n", im->cs.space); return im; } @@ -195,13 +189,12 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy { RGBA_Draw_Context *dc; int r, g, b, a; - double tx1, ty1, tx2, ty2; - int ow, oh; - int space; + double ssx, ssy, ssw, ssh; + int space; Cutout_Rects *rects; Cutout_Rect *rct; - int c, cx, cy, cw, ch; - int i; + int c, cx, cy, cw, ch; + int i; if (sw < 1) sw = 1; if (sh < 1) sh = 1; @@ -218,9 +211,10 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy r = g = b = a = 255; } - if (!gc->ext.arb_program && (im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL - || im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL)) + if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) || + (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL)) { + // SOFTWARE convert. do multi texture later if ((im->cs.data) && (*((unsigned char **)im->cs.data))) { if (im->dirty || !im->im->image.data) @@ -238,101 +232,73 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy else space = im->cs.space; -/* leak in this switch */ switch (space) { case EVAS_COLORSPACE_ARGB8888: evas_cache_image_load_data(&im->im->cache_entry); if ((im->tex) && (im->dirty)) { - evas_gl_common_texture_update(im->tex, im->im, im->tex->smooth); + evas_gl_common_texture_update(im->tex, im->im); im->dirty = 0; } if (!im->tex) - im->tex = evas_gl_common_texture_new(gc, im->im, smooth); - ow = (dw * im->tex->tw) / sw; - oh = (dh * im->tex->th) / sh; - if (im->tex->rectangle) - { - tx1 = sx; - ty1 = sy; - tx2 = sx + sw; - ty2 = sy + sh; - } - else - { - tx1 = (double)(sx ) / (double)(im->tex->w); - ty1 = (double)(sy ) / (double)(im->tex->h); - tx2 = (double)(sx + sw) / (double)(im->tex->w); - ty2 = (double)(sy + sh) / (double)(im->tex->h); - } - evas_gl_common_context_texture_set(gc, im->tex, smooth, ow, oh); + im->tex = evas_gl_common_texture_new(gc, im->im); break; case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P709_PL: - if ((im->tex) && (im->dirty)) - { - evas_gl_common_ycbcr601pl_texture_update(im->tex, im->cs.data, im->im->cache_entry.w, im->im->cache_entry.h, smooth); - im->dirty = 0; - } - if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data))) - { - im->tex = evas_gl_common_ycbcr601pl_texture_new(gc, im->cs.data, im->im->cache_entry.w, im->im->cache_entry.h, smooth); - } - if (!im->tex) return; - ow = (dw * im->tex->tw) / sw; - oh = (dh * im->tex->th) / sh; - if (im->tex->rectangle) - { - tx1 = sx; - ty1 = sy; - tx2 = sx + sw; - ty2 = sy + sh; - } - else - { - tx1 = (double)(sx ) / (double)(im->tex->w); - ty1 = (double)(sy ) / (double)(im->tex->h); - tx2 = (double)(sx + sw) / (double)(im->tex->w); - ty2 = (double)(sy + sh) / (double)(im->tex->h); - } - evas_gl_common_context_texture_set(gc, im->tex, smooth, ow, oh); - break; default: - abort(); + printf("unhandled img format\n"); break; } - -// if ((!im->tex->have_mipmaps) && (smooth) && -// ((im->tex->uw < im->tex->tw) || (im->tex->uh < im->tex->th)) && -// (!gc->ext.sgis_generate_mipmap)) -// evas_gl_common_texture_mipmaps_build(im->tex, im->im, smooth); - evas_gl_common_context_color_set(gc, r, g, b, a); - if ((a < 255) || im->im->cache_entry.flags.alpha) - evas_gl_common_context_blend_set(gc, 1); - else evas_gl_common_context_blend_set(gc, 0); - evas_gl_common_context_read_buf_set(gc, GL_BACK); - evas_gl_common_context_write_buf_set(gc, GL_BACK); - - if (!gc->dc->cutout.rects) + if ((!gc->dc->cutout.rects) +// || (gc->dc->cutout.active > 32) + ) { if (gc->dc->clip.use) - evas_gl_common_context_clip_set(gc, 1, - gc->dc->clip.x, gc->dc->clip.y, - gc->dc->clip.w, gc->dc->clip.h); + { + int nx, ny, nw, nh; + + nx = dx; ny = dy; nw = dw; nh = dh; + RECTS_CLIP_TO_RECT(nx, ny, nw, nh, + gc->dc->clip.x, gc->dc->clip.y, + gc->dc->clip.w, gc->dc->clip.h); + if ((nw < 1) || (nh < 1)) return; + if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh)) + { + evas_gl_common_context_image_push(gc, + im->tex, + sx, sy, sw, sh, + dx, dy, dw, dh, + r, g, b, a, + smooth); + return; + } + + ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw)); + ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh)); + ssw = ((double)sw * (double)(nw)) / (double)(dw); + ssh = ((double)sh * (double)(nh)) / (double)(dh); + evas_gl_common_context_image_push(gc, + im->tex, + ssx, ssy, ssw, ssh, + nx, ny, nw, nh, + r, g, b, a, + smooth); + } else - evas_gl_common_context_clip_set(gc, 0, - 0, 0, 0, 0); - glBegin(GL_QUADS); - glTexCoord2d(tx1, ty1); glVertex2i(dx , dy ); - glTexCoord2d(tx2, ty1); glVertex2i(dx + dw, dy ); - glTexCoord2d(tx2, ty2); glVertex2i(dx + dw, dy + dh); - glTexCoord2d(tx1, ty2); glVertex2i(dx , dy + dh); - glEnd(); + { + evas_gl_common_context_image_push(gc, + im->tex, + sx, sy, sw, sh, + dx, dy, dw, dh, + r, g, b, a, + smooth); + } return; } + /* save out clip info */ c = gc->dc->clip.use; cx = gc->dc->clip.x; cy = gc->dc->clip.y; cw = gc->dc->clip.w; ch = gc->dc->clip.h; evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->w, gc->h); @@ -346,18 +312,32 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy rects = evas_common_draw_context_apply_cutouts(dc); for (i = 0; i < rects->active; ++i) { + int nx, ny, nw, nh; + rct = rects->rects + i; - if (gc->dc->clip.use) - evas_gl_common_context_clip_set(gc, 1, rct->x, rct->y, rct->w, rct->h); - else - evas_gl_common_context_clip_set(gc, 0, - 0, 0, 0, 0); - glBegin(GL_QUADS); - glTexCoord2d(tx1, ty1); glVertex2i(dx , dy ); - glTexCoord2d(tx2, ty1); glVertex2i(dx + dw, dy ); - glTexCoord2d(tx2, ty2); glVertex2i(dx + dw, dy + dh); - glTexCoord2d(tx1, ty2); glVertex2i(dx , dy + dh); - glEnd(); + nx = dx; ny = dy; nw = dw; nh = dh; + RECTS_CLIP_TO_RECT(nx, ny, nw, nh, rct->x, rct->y, rct->w, rct->h); + if ((nw < 1) || (nh < 1)) continue; + if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh)) + { + evas_gl_common_context_image_push(gc, + im->tex, + sx, sy, sw, sh, + dx, dy, dw, dh, + r, g, b, a, + smooth); + continue; + } + ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw)); + ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh)); + ssw = ((double)sw * (double)(nw)) / (double)(dw); + ssh = ((double)sh * (double)(nh)) / (double)(dh); + evas_gl_common_context_image_push(gc, + im->tex, + ssx, ssy, ssw, ssh, + nx, ny, nw, nh, + r, g, b, a, + smooth); } evas_common_draw_context_apply_clear_cutouts(rects); /* restore clip info */ diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_private.h b/legacy/evas/src/modules/engines/gl_common/evas_gl_private.h index 8ad9f81a8b..7fd3af4f19 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_private.h +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_private.h @@ -1,90 +1,5 @@ #ifndef _EVAS_GL_PRIVATE_H #define _EVAS_GL_PRIVATE_H - #include "evas_gl_common.h" -#ifndef GL_TEXTURE_RECTANGLE_NV -#define GL_TEXTURE_RECTANGLE_NV 0x84f5 -#endif - -#if 0 -#ifndef GL_WRITE_PIXEL_DATA_RANGE_NV -/* nvidia extensions */ -extern void *glXAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -extern void glPixelDataRangeNV(GLenum target, GLsizei length, void *pointer); -extern void glFlushPixelDataRangeNV(GLenum target); -# define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 -#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 -#endif - -/* arb extensions */ -void glBindBufferARB(GLenum target, uint buffer); -void glDeleteBuffersARB(GLsizei n, const uint *buffers); -void glGenBuffersARB(GLsizei n, GLuint *buffers); -GLboolean glIsBufferARB(GLuint buffer); - -void glBufferDataARB(GLenum target, GLsizei size, const void *data, - GLenum usage); -void glBufferSubDataARB(GLenum target, int offset, GLsizei size, - const void *data); -void glGetBufferSubDataARB(GLenum target, int offset, - GLsizei size, void *data); - -void *glMapBufferARB(GLenum target, GLenum access); -GLboolean glUnmapBufferARB(GLenum target); - -void glGetBufferParameterivARB(GLenum target, GLenum pname, int *params); -void glGetBufferPointervARB(GLenum target, GLenum pname, void **params); - -#define GL_ARRAY_BUFFER_ARB 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 -#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 -#define GL_BNORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F -#define GL_STREAM_DRAW_ARB 0x88E0 -#define GL_STREAM_READ_ARB 0x88E1 -#define GL_STREAM_COPY_ARB 0x88E2 -#define GL_STATIC_DRAW_ARB 0x88E4 -#define GL_STATIC_READ_ARB 0x88E5 -#define GL_STATIC_COPY_ARB 0x88E6 -#define GL_DYNAMIC_DRAW_ARB 0x88E8 -#define GL_DYNAMIC_READ_ARB 0x88E9 -#define GL_DYNAMIC_COPY_ARB 0x88EA -#define GL_READ_ONLY_ARB 0x88B8 -#define GL_WRITE_ONLY_ARB 0x88B9 -#define GL_READ_WRITE_ARB 0x88BA -#define GL_BUFFER_SIZE_ARB 0x8764 -#define GL_BUFFER_USAGE_ARB 0x8765 -#define GL_BUFFER_ACCESS_ARB 0x88BB -#define GL_BUFFER_MAPPED_ARB 0x88BC -#define GL_BUFFER_MAP_POINTER_ARB 0x88BD -#endif - - - - - - -/* evas ARGB pixel config */ -#define NATIVE_PIX_FORMAT GL_BGRA - -/* Big endian systems require the texture know the byte order is reversed */ -#ifdef WORDS_BIGENDIAN -#define NATIVE_PIX_UNIT GL_UNSIGNED_INT_8_8_8_8_REV -#else -/* fast on vidia */ -/*#define NATIVE_PIX_UNIT GL_UNSIGNED_INT_8_8_8_8_REV*/ -/* fast on ati compared to GL_UNSIGNED_INT_8_8_8_8_REV */ -#define NATIVE_PIX_UNIT GL_UNSIGNED_BYTE -#endif - #endif diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_rectangle.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_rectangle.c index 96948c4df0..cd3368e17d 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_rectangle.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_rectangle.c @@ -1,54 +1,27 @@ #include "evas_gl_private.h" -static void -evas_gl_common_rect_draw_internal(Evas_GL_Context *gc, int x, int y, int w, int h) -{ - int r, g, b, a; - RGBA_Draw_Context *dc = gc->dc; - - a = (dc->col.col >> 24) & 0xff; - r = (dc->col.col >> 16) & 0xff; - g = (dc->col.col >> 8 ) & 0xff; - b = (dc->col.col ) & 0xff; - evas_gl_common_context_color_set(gc, r, g, b, a); - if (a < 255) evas_gl_common_context_blend_set(gc, 1); - else evas_gl_common_context_blend_set(gc, 0); - if (dc->clip.use) - evas_gl_common_context_clip_set(gc, 1, - dc->clip.x, dc->clip.y, - dc->clip.w, dc->clip.h); - else - evas_gl_common_context_clip_set(gc, 0, - 0, 0, 0, 0); - evas_gl_common_context_texture_set(gc, NULL, 0, 0, 0); - evas_gl_common_context_read_buf_set(gc, GL_BACK); - evas_gl_common_context_write_buf_set(gc, GL_BACK); - glBegin(GL_QUADS); - glVertex2i(x, y); - glVertex2i(x + w, y); - glVertex2i(x + w, y + h); - glVertex2i(x, y + h); - glEnd(); -} - void evas_gl_common_rect_draw(Evas_GL_Context *gc, int x, int y, int w, int h) { Cutout_Rects *rects; Cutout_Rect *r; - int c, cx, cy, cw, ch; - int i; + int c, cx, cy, cw, ch, cr, cg, cb, ca, i; if ((w <= 0) || (h <= 0)) return; - if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, gc->w, gc->h))) - return; + if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, gc->w, gc->h))) return; /* save out clip info */ c = gc->dc->clip.use; cx = gc->dc->clip.x; cy = gc->dc->clip.y; cw = gc->dc->clip.w; ch = gc->dc->clip.h; + + ca = (gc->dc->col.col >> 24) & 0xff; + if (ca <= 0) return; + cr = (gc->dc->col.col >> 16) & 0xff; + cg = (gc->dc->col.col >> 8 ) & 0xff; + cb = (gc->dc->col.col ) & 0xff; evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->w, gc->h); /* no cutouts - cut right to the chase */ if (!gc->dc->cutout.rects) { - evas_gl_common_rect_draw_internal(gc, x, y, w, h); + evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca); } else { @@ -60,8 +33,10 @@ evas_gl_common_rect_draw(Evas_GL_Context *gc, int x, int y, int w, int h) for (i = 0; i < rects->active; ++i) { r = rects->rects + i; - evas_common_draw_context_set_clip(gc->dc, r->x, r->y, r->w, r->h); - evas_gl_common_rect_draw_internal(gc, x, y, w, h); + if ((r->w > 0) && (r->h > 0)) + { + evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca); + } } evas_common_draw_context_apply_clear_cutouts(rects); } diff --git a/legacy/evas/src/modules/engines/gl_common/evas_gl_texture.c b/legacy/evas/src/modules/engines/gl_common/evas_gl_texture.c index 97d8fe7090..484c14d950 100644 --- a/legacy/evas/src/modules/engines/gl_common/evas_gl_texture.c +++ b/legacy/evas/src/modules/engines/gl_common/evas_gl_texture.c @@ -1,619 +1,350 @@ #include "evas_gl_private.h" +static int +_nearest_pow2(int num) +{ + unsigned int n = num - 1; + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + return n + 1; +} + +static void +_tex_adjust(Evas_GL_Context *gc, int *w, int *h) +{ + unsigned int n; + +// disable - has a bug somewhere +// if (gc->info.tex_npo2) return; + /*if (gc->info.tex_rect) return;*/ + *w = _nearest_pow2(*w); + *h = _nearest_pow2(*h); +} + +static int +_tex_round_slot(Evas_GL_Context *gc, int h) +{ +// disable. has a bug somewhere +// if (!gc->info.tex_npo2) + h = _nearest_pow2(h); + return (h + 15) >> 4; +} + +static int +_tex_format_index(GLuint format) +{ + switch (format) + { + case GL_RGBA: + return 0; + case GL_RGB: + return 1; + case GL_ALPHA: + return 2; + default: + break; + } + return 0; +} + +static Evas_GL_Texture_Pool * +_pool_tex_new(Evas_GL_Context *gc, int w, int h, GLuint format) +{ + Evas_GL_Texture_Pool *pt; + + pt = calloc(1, sizeof(Evas_GL_Texture_Pool)); + if (!pt) return NULL; + _tex_adjust(gc, &w, &h); + pt->gc = gc; + pt->w = w; + pt->h = h; + pt->format = format; + pt->references = 0; + glGenTextures(1, &(pt->texture)); + glBindTexture(GL_TEXTURE_2D, pt->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, + format, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, gc->shader.cur_tex); + return pt; +} + +static int +_pool_tex_alloc(Evas_GL_Texture_Pool *pt, GLuint format, int w, int h, int *u, int *v, Eina_List **l_after) +{ + Eina_List *l; + Evas_GL_Texture *tex, *tex2; + int nx, d, b; + + if (pt->allocations) + { + tex = pt->allocations->data; + // if firest tex is not at left edge... + if (tex->x > (0 + 1)) + { + if ((tex->x - 1) >= w) + { + *u = 0; + *v = 0; + *l_after = NULL; + return 1; + } + } + } + EINA_LIST_FOREACH(pt->allocations, l, tex) + { + b = tex->x + tex->w + 2; + if (l->next) + { + tex2 = l->next->data; + nx = tex2->x - 1; + } + else + nx = pt->w - 1; + d = nx - b; + if (d >= w) + { + *u = b; + *v = 0; + *l_after = l; + return 1; + } + } + *l_after = NULL; + return 0; +} + +static Evas_GL_Texture_Pool * +_pool_tex_find(Evas_GL_Context *gc, int w, int h, GLuint format, int *u, int *v, Eina_List **l_after, int atlas_w) +{ + Evas_GL_Texture_Pool *pt = NULL; + Eina_List *l; + int th, th2; + + if ((w > 512) || (h > 512)) + { + pt = _pool_tex_new(gc, w + 2, h + 1, format); + gc->tex.whole = eina_list_prepend(gc->tex.whole, pt); + pt->slot = -1; + pt->fslot = -1; + pt->whole = 1; + *u = 0; + *v = 0; + *l_after = NULL; + return pt; + } + + th = _tex_round_slot(gc, h); + th2 = _tex_format_index(format); + EINA_LIST_FOREACH(gc->tex.atlas[th][th2], l, pt) + { + if (_pool_tex_alloc(pt, format, w, h, u, v, l_after)) + { + gc->tex.atlas[th][th2] = + eina_list_remove_list(gc->tex.atlas[th][th2], l); + gc->tex.atlas[th][th2] = + eina_list_prepend(gc->tex.atlas[th][th2], pt); + return pt; + } + } + pt = _pool_tex_new(gc, atlas_w, h, format); + gc->tex.atlas[th][th2] = eina_list_prepend(gc->tex.atlas[th][th2], pt); + pt->slot = th; + pt->fslot = th2; + *u = 0; + *v = 0; + *l_after = NULL; + return pt; +} + Evas_GL_Texture * -evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im, int smooth) +evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im) { Evas_GL_Texture *tex; - DATA32 *im_data; - int im_w, im_h; - int tw, th; - int shift; - GLenum pixfmt, texfmt; + Eina_List *l_after = NULL; + int u = 0, v = 0; tex = calloc(1, sizeof(Evas_GL_Texture)); if (!tex) return NULL; - - if ((gc->ext.nv_texture_rectangle) && - (!(gc->ext.arb_texture_non_power_of_two && - gc->ext.sgis_generate_mipmap))) - { - tex->gc = gc; - tex->w = im->cache_entry.w; - tex->h = im->cache_entry.h; - tex->rectangle = 1; - tex->tw = im->cache_entry.w; - tex->th = im->cache_entry.h; - tex->references = 0; - tex->smooth = smooth; - tex->changed = 1; - - glEnable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_RECTANGLE_NV); - glGenTextures(1, &(tex->texture)); - glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex->texture); - if (smooth) - { - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - - if (gc->texture) gc->texture->references--; - gc->texture = tex; - gc->change.texture = 1; - tex->references++; - - if (im->cache_entry.flags.alpha) texfmt = GL_RGBA8; - else texfmt = GL_RGB8; - pixfmt = NATIVE_PIX_FORMAT; - - glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, - texfmt, tex->w, tex->h, 0, - pixfmt, NATIVE_PIX_UNIT, im->image.data); - return tex; - } - - if ((gc->ext.arb_texture_non_power_of_two) && (gc->ext.sgis_generate_mipmap)) - { - tw = im->cache_entry.w; - th = im->cache_entry.h; - } - else - { - shift = 1; while (im->cache_entry.w > shift) shift = shift << 1; tw = shift; - shift = 1; while (im->cache_entry.h > shift) shift = shift << 1; th = shift; - } + tex->gc = gc; - tex->w = tw; - tex->h = th; - tex->tw = im->cache_entry.w; - tex->th = im->cache_entry.h; - tex->references = 0; - tex->smooth = 0; - tex->changed = 1; - glEnable(GL_TEXTURE_2D); - glGenTextures(1, &(tex->texture)); - glBindTexture(GL_TEXTURE_2D, tex->texture); - if (gc->texture) gc->texture->references--; - gc->texture = tex; - gc->change.texture = 1; - tex->references++; - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - im_data = im->image.data; - im_w = im->cache_entry.w; - im_h = im->cache_entry.h; - - if (im->cache_entry.flags.alpha) texfmt = GL_RGBA8; - else texfmt = GL_RGB8; - pixfmt = NATIVE_PIX_FORMAT; - - glTexImage2D(GL_TEXTURE_2D, 0, - texfmt, tw, th, 0, - pixfmt, NATIVE_PIX_UNIT, NULL); -/* + tex->references = 1; + if (im->cache_entry.flags.alpha) + tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3, + im->cache_entry.h + 1, GL_RGBA, + &u, &v, &l_after, 1024); + else + tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3, + im->cache_entry.h + 1, GL_RGB, + &u, &v, &l_after, 1024); + if (!tex->pt) { - int ttw, tth; - int l; - - ttw = tw; - tth = th; - l = 0; - while ((ttw > 1) || (tth > 1)) - { - l++; - ttw /= 2; - tth /= 2; - if (ttw < 1) ttw = 1; - if (tth < 1) tth = 1; - glTexImage2D(GL_TEXTURE_2D, l, - texfmt, ttw, tth, 0, - pixfmt, NATIVE_PIX_UNIT, NULL); - } + free(tex); + return NULL; } - */ - if (gc->ext.sgis_generate_mipmap) - { - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); - tex->have_mipmaps = 1; - } - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, 0, im_w, im_h, - pixfmt, NATIVE_PIX_UNIT, - im_data); - if (im_w < tw) - glTexSubImage2D(GL_TEXTURE_2D, 0, - im_w, 0, 1, im_h, - pixfmt, NATIVE_PIX_UNIT, - im_data + im_w - 1); - if (im_h < th) - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, im_h, im_w, 1, - pixfmt, NATIVE_PIX_UNIT, - im_data + (im_w * (im_h - 1))); - if ((im_w < tw) && (im_h < th)) - glTexSubImage2D(GL_TEXTURE_2D, 0, - im_w, im_h, 1, 1, - pixfmt, NATIVE_PIX_UNIT, - im_data + (im_w * (im_h - 1)) + im_w - 1); + tex->x = u + 1; + tex->y = v; + tex->w = im->cache_entry.w; + tex->h = im->cache_entry.h; + if (l_after) + tex->pt->allocations = + eina_list_append_relative_list(tex->pt->allocations, tex, l_after); + else + tex->pt->allocations = + eina_list_prepend(tex->pt->allocations, tex); + tex->pt->references++; + evas_gl_common_texture_update(tex, im); return tex; } void -evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im, int smooth __UNUSED__) +evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im) { - DATA32 *im_data; - int im_w, im_h; - int tw, th; - GLenum pixfmt, texfmt, target; - - if (tex->rectangle) - { - void *data; - - glEnable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_RECTANGLE_NV); - glBindTexture(GL_TEXTURE_RECTANGLE_NV, tex->texture); - - data = im->image.data; -#if 0 // trying the glXAllocateMemoryNV() thing but its abysmally slow - tmp = glXAllocateMemoryNV(tex->w * tex->h * sizeof(DATA32), - 0.0, 1.0, 1.0); - if (tmp) - { - glEnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV); - glPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV, - tex->w * tex->h * sizeof(DATA32), - tmp); -// evas_common_copy_pixels_rgba_to_rgba_mmx2(im->image->data, tmp, -// tex->w * tex->h); - memcpy(tmp, im->image.data, - tex->w * tex->h * sizeof(DATA32)); - data = tmp; - } -#endif - if (tex->gc->texture) tex->gc->texture->references--; - tex->gc->texture = tex; - tex->gc->change.texture = 1; - tex->references++; - - if (im->cache_entry.flags.alpha) texfmt = GL_RGBA8; - else texfmt = GL_RGB8; - pixfmt = NATIVE_PIX_FORMAT; - - glTexSubImage2D(GL_TEXTURE_RECTANGLE_NV, 0, - 0, 0, tex->w, tex->h, - pixfmt, NATIVE_PIX_UNIT, - data); -#if 0 // trying the glXAllocateMemoryNV() thing but its abysmally slow - if (tmp) - { - glFlushPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV); - glXFreeMemoryNV(tmp); - } -#endif - return; - } - tw = tex->w; - th = tex->h; - tex->changed = 1; - tex->have_mipmaps = 0; -// if (tex->gc->ext.nv_texture_rectangle) glDisable(GL_TEXTURE_RECTANGLE_NV); - glEnable(GL_TEXTURE_2D); - if (tex->rectangle) - { - glEnable(GL_TEXTURE_RECTANGLE_NV); - target = GL_TEXTURE_RECTANGLE_NV; - } - else - { -// glDisable(GL_TEXTURE_RECTANGLE_NV); - glEnable(GL_TEXTURE_2D);// - target = GL_TEXTURE_2D; - } - - glBindTexture(GL_TEXTURE_2D, tex->texture); - - if (tex->gc->texture) tex->gc->texture->references--; - tex->gc->texture = tex; - tex->gc->change.texture = 1; - tex->references++; - - /* - if (!tex->opt) - { - glPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV, - im->image->w * im->image->h * 4, - im->image->data); - tex->opt = 1; - } - */ - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - tex->smooth = 0; - - im_data = im->image.data; - im_w = im->cache_entry.w; - im_h = im->cache_entry.h; - - if (im->cache_entry.flags.alpha) texfmt = GL_RGBA8; - else texfmt = GL_RGB8; - pixfmt = NATIVE_PIX_FORMAT; - - if (tex->gc->ext.sgis_generate_mipmap) - { - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); - tex->have_mipmaps = 1; - } +#ifdef defined(GL_UNSIGNED_INT_8_8_8_8_REV) && defined(GL_BGRA) +#define COLOR_FORMAT GL_RGBA +#define PIXEL_FORMAT GL_UNSIGNED_BYTE +// FIXME: need to change shader for this to work +//#define COLOR_FORMAT GL_BGRA +//#define PIXEL_FORMAT GL_UNSIGNED_INT_8_8_8_8_REV +#else +#define COLOR_FORMAT GL_RGBA +#define PIXEL_FORMAT GL_UNSIGNED_BYTE +#endif + glBindTexture(GL_TEXTURE_2D, tex->pt->texture); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + // +-+ + // +-+ + // glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, 0, im_w, im_h, - pixfmt, NATIVE_PIX_UNIT, - im_data); -#if 1 // this is sloooow... well slower than just the above... - if (im_w < tw) - glTexSubImage2D(GL_TEXTURE_2D, 0, - im_w, 0, 1, im_h, - pixfmt, NATIVE_PIX_UNIT, - im_data + im_w - 1); - if (im_h < th) - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, im_h, im_w, 1, - pixfmt, NATIVE_PIX_UNIT, - im_data + (im_w * (im_h - 1))); - if ((im_w < tw) && (im_h < th)) - glTexSubImage2D(GL_TEXTURE_2D, 0, - im_w, im_h, 1, 1, - pixfmt, NATIVE_PIX_UNIT, - im_data + (im_w * (im_h - 1)) + im_w - 1); -#endif + tex->x, tex->y, + im->cache_entry.w, im->cache_entry.h, + COLOR_FORMAT, PIXEL_FORMAT, + im->image.data); + // |xxx + // |xxx + // + glTexSubImage2D(GL_TEXTURE_2D, 0, + tex->x - 1, tex->y, + 1, im->cache_entry.h, + COLOR_FORMAT, PIXEL_FORMAT, + im->image.data); + // xxx| + // xxx| + // + glTexSubImage2D(GL_TEXTURE_2D, 0, + tex->x + im->cache_entry.w, tex->y, + 1, im->cache_entry.h, + COLOR_FORMAT, PIXEL_FORMAT, + im->image.data + (im->cache_entry.w - 1)); + // xxx + // xxx + // --- + glTexSubImage2D(GL_TEXTURE_2D, 0, + tex->x, tex->y + im->cache_entry.h, + im->cache_entry.w, 1, + COLOR_FORMAT, PIXEL_FORMAT, + im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w)); + // xxx + // xxx + // o + glTexSubImage2D(GL_TEXTURE_2D, 0, + tex->x - 1, tex->y + im->cache_entry.h, + 1, 1, + COLOR_FORMAT, PIXEL_FORMAT, + im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w)); + // xxx + // xxx + // o + glTexSubImage2D(GL_TEXTURE_2D, 0, + tex->x + im->cache_entry.w, tex->y + im->cache_entry.h, + 1, 1, + COLOR_FORMAT, PIXEL_FORMAT, + im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w) + (im->cache_entry.w - 1)); + if (tex->pt->texture != tex->gc->shader.cur_tex) + { + glBindTexture(GL_TEXTURE_2D, tex->gc->shader.cur_tex); + } } void evas_gl_common_texture_free(Evas_GL_Texture *tex) { - if (tex->references > 0) + if (!tex) return; + tex->references--; + if (tex->references > 0) return; + tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex); + tex->pt->references--; + if (tex->pt->references <= 0) { - /* FIXME: could be in more gc's */ + if (tex->pt->whole) + { + tex->gc->tex.whole = + eina_list_remove(tex->gc->tex.whole, tex->pt); + } + else + { + tex->gc->tex.atlas + [tex->pt->slot][tex->pt->fslot] = + eina_list_remove + (tex->gc->tex.atlas + [tex->pt->slot][tex->pt->fslot], + tex->pt); + } + glDeleteTextures(1, &(tex->pt->texture)); + free(tex->pt); } - if (tex->gc->texture == tex) - { - tex->gc->texture = NULL; - tex->gc->change.texture = 1; - } - glDeleteTextures(1, &tex->texture); - if (tex->texture2) glDeleteTextures(1, &tex->texture2); - if (tex->texture3) glDeleteTextures(1, &tex->texture3); -/* - if (tex->fshad) - { - glDeleteObjectARB(tex->fshad); - } - if (tex->prog) - { - glDeleteObjectARB(tex->prog); - } - */ free(tex); } -void -evas_gl_common_texture_mipmaps_build(Evas_GL_Texture *tex, RGBA_Image *im, int smooth) -{ - DATA32 *im_data; - int tw, th; - int im_w, im_h, w, h; - GLenum pixfmt, texfmt; - int level; - RGBA_Image *im1 = NULL, *im2 = NULL; -#ifdef BUILD_MMX - int mmx, sse, sse2; -#endif - - if (!smooth) return; - if (tex->rectangle) return; -#ifdef BUILD_MMX - evas_common_cpu_can_do(&mmx, &sse, &sse2); -#endif - tw = tex->w; - th = tex->h; - w = im->cache_entry.w; - h = im->cache_entry.h; - level = 0; - im1 = im; - - if (tex->gc->texture != tex) - { - if (tex->gc->texture) tex->gc->texture->references--; - tex->gc->texture = tex; - tex->gc->change.texture = 1; - if (tex) tex->references++; - } - - if (im->cache_entry.flags.alpha) texfmt = GL_RGBA8; - else texfmt = GL_RGB8; - pixfmt = NATIVE_PIX_FORMAT; - - if (tex->gc->ext.nv_texture_rectangle) glDisable(GL_TEXTURE_RECTANGLE_NV); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, tex->texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - while ((w > 1) || (h > 1)) - { - int pw, ph; - - pw = w; - ph = h; - w /= 2; - h /= 2; - if (w < 1) w = 1; - if (h < 1) h = 1; - tw /= 2; - th /= 2; - - level++; - im2 = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get()); - im2 = (RGBA_Image *) evas_cache_image_size_set(&im2->cache_entry, w, h); -#ifdef BUILD_MMX - if (mmx) - { - evas_common_scale_rgba_mipmap_down_2x2_mmx(im1->image.data, - im2->image.data, - pw, ph); - } - else -#endif - { - if (im->cache_entry.flags.alpha) - evas_common_scale_rgba_mipmap_down_2x2_c(im1->image.data, - im2->image.data, - pw, ph); - else - evas_common_scale_rgb_mipmap_down_2x2_c(im1->image.data, - im2->image.data, - pw, ph); - } - if (im1 != im) evas_cache_image_drop(&im1->cache_entry); - im1 = NULL; - - im_data = im2->image.data; - im_w = w; - im_h = h; - glTexSubImage2D(GL_TEXTURE_2D, level, - 0, 0, im_w, im_h, - pixfmt, NATIVE_PIX_UNIT, - im_data); - if (im_w < tw) - glTexSubImage2D(GL_TEXTURE_2D, level, - im_w, 0, 1, im_h, - pixfmt, NATIVE_PIX_UNIT, - im_data + im_w - 1); - if (im_h < th) - glTexSubImage2D(GL_TEXTURE_2D, level, - 0, im_h, im_w, 1, - pixfmt, NATIVE_PIX_UNIT, - im_data + (im_w * (im_h - 1))); - if ((im_w < tw) && (im_h < th)) - glTexSubImage2D(GL_TEXTURE_2D, level, - im_w, im_h, 1, 1, - pixfmt, NATIVE_PIX_UNIT, - im_data + (im_w * (im_h - 1)) + im_w - 1); - im1 = im2; - im2 = NULL; - } - if ((im1 != im) && (im1)) evas_cache_image_drop(&im1->cache_entry); - tex->have_mipmaps = 1; -#ifdef BUILD_MMX - if (mmx) evas_common_cpu_end_opt(); -#endif -} - Evas_GL_Texture * -evas_gl_common_ycbcr601pl_texture_new(Evas_GL_Context *gc, unsigned char **rows, int w, int h, int smooth) +evas_gl_common_texture_alpha_new(Evas_GL_Context *gc, DATA8 *pixels, int w, int h, int fh) { Evas_GL_Texture *tex; - int tw, th; - GLenum texfmt; - -// on an nv 6600gt this is fast - but on a 5500fx its DEAD SLOW!!!!! -// if (!gc->ext.arb_texture_non_power_of_two) return NULL; - + Eina_List *l_after = NULL; + int u = 0, v = 0; + int tw = 4096; + tex = calloc(1, sizeof(Evas_GL_Texture)); if (!tex) return NULL; - tw = w; - th = h; tex->gc = gc; - tex->w = tw; - tex->h = th; - tex->tw = w; - tex->th = h; - tex->references = 0; - tex->smooth = 0; - tex->changed = 1; - - tex->prog = gc->yuv422p.prog; - - glEnable(GL_TEXTURE_2D); - texfmt = GL_LUMINANCE; - - glUseProgramObjectARB(tex->prog); - - glGenTextures(1, &(tex->texture)); - glBindTexture(GL_TEXTURE_2D, tex->texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (smooth) + tex->references = 1; + if (tw > gc->info.max_texture_size) tw = gc->info.max_texture_size; + tex->pt = _pool_tex_find(gc, w + 3, fh, GL_ALPHA, + &u, &v, &l_after, tw); + if (!tex->pt) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + free(tex); + return NULL; } + tex->x = u + 1; + tex->y = v; + tex->w = w; + tex->h = h; + if (l_after) + tex->pt->allocations = eina_list_append_relative(tex->pt->allocations, tex, l_after); else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - glTexImage2D(GL_TEXTURE_2D, 0, texfmt, tex->w, tex->h, 0, - texfmt, GL_UNSIGNED_BYTE, NULL); - if (tex->h >= 2) - glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex->w, tex->h, - texfmt, GL_UNSIGNED_BYTE, rows[0]); -// for (y = 0; y < tex->h; y++) -// glTexSubImage2D(GL_TEXTURE_2D, 0, -// 0, y, tex->w, 1, -// texfmt, GL_UNSIGNED_BYTE, rows[y]); - - glGenTextures(1, &(tex->texture2)); - glBindTexture(GL_TEXTURE_2D, tex->texture2); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (smooth) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - glTexImage2D(GL_TEXTURE_2D, 0, texfmt, tex->w / 2, tex->h / 2, 0, - texfmt, GL_UNSIGNED_BYTE, NULL); - if (tex->h >= 4) - glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[tex->h + 1] - rows[tex->h]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex->w / 2, tex->h / 2, - texfmt, GL_UNSIGNED_BYTE, rows[tex->h]); -// for (y = 0; y < (tex->h / 2); y++) -// glTexSubImage2D(GL_TEXTURE_2D, 0, -// 0, y, tex->w / 2, 1, -// texfmt, GL_UNSIGNED_BYTE, rows[tex->h + y]); - - glGenTextures(1, &(tex->texture3)); - glBindTexture(GL_TEXTURE_2D, tex->texture3); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (smooth) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - glTexImage2D(GL_TEXTURE_2D, 0, - texfmt, tex->w / 2, tex->h / 2, 0, - texfmt, GL_UNSIGNED_BYTE, NULL); - if (tex->h >= 4) - glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[tex->h + (tex->h / 2) + 1] - rows[tex->h + (tex->h / 2)]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex->w / 2, tex->h / 2, - texfmt, GL_UNSIGNED_BYTE, rows[tex->h + (tex->h / 2)]); -// for (y = 0; y < (tex->h / 2); y++) -// glTexSubImage2D(GL_TEXTURE_2D, 0, -// 0, y, tex->w / 2, 1, -// texfmt, GL_UNSIGNED_BYTE, rows[tex->h + (tex->h / 2) + y]); - - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glUseProgramObjectARB(0); - - if (gc->texture) gc->texture->references--; - gc->texture = tex; - gc->change.texture = 1; - tex->references++; - + tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex); + tex->pt->references++; + evas_gl_common_texture_alpha_update(tex, pixels, w, h, fh); return tex; } void -evas_gl_common_ycbcr601pl_texture_update(Evas_GL_Texture *tex, unsigned char **rows, int w __UNUSED__, int h __UNUSED__, int smooth) +evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels, int w, int h, int fh) { - int texfmt; - - /* FIXME: should use subimage */ - glEnable(GL_TEXTURE_2D); - texfmt = GL_LUMINANCE; - - glBindTexture(GL_TEXTURE_2D, tex->texture); - if (smooth) + glBindTexture(GL_TEXTURE_2D, tex->pt->texture); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glTexSubImage2D(GL_TEXTURE_2D, 0, + tex->x, tex->y, w, h, + GL_ALPHA, GL_UNSIGNED_BYTE, + pixels); + if (tex->pt->texture != tex->gc->shader.cur_tex) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, tex->gc->shader.cur_tex); } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - if (tex->h >= 2) - glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex->w, tex->h, - texfmt, GL_UNSIGNED_BYTE, rows[0]); -// for (y = 0; y < tex->h; y++) -// glTexSubImage2D(GL_TEXTURE_2D, 0, -// 0, y, tex->w, 1, -// texfmt, GL_UNSIGNED_BYTE, rows[y]); - - glBindTexture(GL_TEXTURE_2D, tex->texture2); - if (smooth) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - if (tex->h >= 4) - glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[tex->h + 1] - rows[tex->h]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex->w / 2, tex->h / 2, - texfmt, GL_UNSIGNED_BYTE, rows[tex->h]); -// for (y = 0; y < (tex->h / 2); y++) -// glTexSubImage2D(GL_TEXTURE_2D, 0, -// 0, y, tex->w / 2, 1, -// texfmt, GL_UNSIGNED_BYTE, rows[tex->h + y]); - - glBindTexture(GL_TEXTURE_2D, tex->texture3); - if (smooth) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - if (tex->h >= 4) - glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[tex->h + (tex->h / 2) + 1] - rows[tex->h + (tex->h / 2)]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex->w / 2, tex->h / 2, - texfmt, GL_UNSIGNED_BYTE, rows[tex->h + (tex->h / 2)]); -// for (y = 0; y < (tex->h / 2); y++) -// glTexSubImage2D(GL_TEXTURE_2D, 0, -// 0, y, tex->w / 2, 1, -// texfmt, GL_UNSIGNED_BYTE, rows[tex->h + (tex->h / 2) + y]); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - - if (tex->gc->texture) tex->gc->texture->references--; - tex->gc->texture = tex; - tex->gc->change.texture = 1; - tex->references++; } diff --git a/legacy/evas/src/modules/engines/gl_common/shader/compile-s3c6410.sh b/legacy/evas/src/modules/engines/gl_common/shader/compile-s3c6410.sh new file mode 100755 index 0000000000..de2e37e8dd --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/compile-s3c6410.sh @@ -0,0 +1,34 @@ +#!/bin/sh +ORIONEXE=/home/raster/Data/orion/orion.exe +OPTS="-O --nolodcalc -hp" + +function compile() +{ + F=$1 + + make-c-str.sh $F"_frag.shd" > $F"_frag.h" + if test -f $F"_frag_s3c6410.asm"; then + wine $ORIONEXE -a $OPTS -f $F"_frag_s3c6410.asm" + make-c-bin.sh $F"_frag_s3c6410.bin" > $F"_frag_bin.h" + rm -f $F"_frag_s3c6410.bin" $F"_frag_s3c6410.h" + else + wine $ORIONEXE $OPTS -f $F"_frag.shd" + make-c-bin.sh $F"_frag.shd.bin" > $F"_frag_bin.h" + rm -f $F"_frag.shd.bin" $F"_frag.shd.asm" $F"_frag.shd.h" + fi + + make-c-str.sh $F"_vert.shd" > $F"_vert.h" + if test -f $F"_vert_s3c6410.asm"; then + wine $ORIONEXE -a $OPTS -v $F"_vert_s3c6410.asm" + make-c-bin.sh $F"_vert_s3c6410.bin" > $F"_vert_bin.h" + rm -f $F"_vert_s3c6410.bin" $F"_vert_s3c6410.h" + else + wine $ORIONEXE $OPTS -v $F"_vert.shd" + make-c-bin.sh $F"_vert.shd.bin" > $F"_vert_bin.h" + rm -f $F"_vert.shd.bin" $F"_vert.shd.asm" $F"_vert.shd.h" + fi +} + +compile rect +compile img +compile font diff --git a/legacy/evas/src/modules/engines/gl_common/shader/compile-sgx.sh b/legacy/evas/src/modules/engines/gl_common/shader/compile-sgx.sh new file mode 100755 index 0000000000..ce2be8035e --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/compile-sgx.sh @@ -0,0 +1,12 @@ +#!/bin/sh +function compile() +{ + F=$1 + + make-c-str.sh $F"_frag.shd" > $F"_frag.h" + make-c-str.sh $F"_vert.shd" > $F"_vert.h" +} + +compile rect +compile img +compile font diff --git a/legacy/evas/src/modules/engines/gl_common/shader/font_frag.h b/legacy/evas/src/modules/engines/gl_common/shader/font_frag.h new file mode 100644 index 0000000000..63efc42dce --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/font_frag.h @@ -0,0 +1,7 @@ +"uniform sampler2D tex;\n" +"varying vec4 col;\n" +"varying vec2 tex_c;\n" +"void main()\n" +"{\n" +" gl_FragColor = texture2D(tex, tex_c.xy).aaaa * col;\n" +"}\n" diff --git a/legacy/evas/src/modules/engines/gl_common/shader/font_frag.shd b/legacy/evas/src/modules/engines/gl_common/shader/font_frag.shd new file mode 100644 index 0000000000..d540e3cb0b --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/font_frag.shd @@ -0,0 +1,7 @@ +uniform sampler2D tex; +varying vec4 col; +varying vec2 tex_c; +void main() +{ + gl_FragColor = texture2D(tex, tex_c.xy).aaaa * col; +} diff --git a/legacy/evas/src/modules/engines/gl_common/shader/font_frag_s3c6410.asm b/legacy/evas/src/modules/engines/gl_common/shader/font_frag_s3c6410.asm new file mode 100644 index 0000000000..4ed116f0c2 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/font_frag_s3c6410.asm @@ -0,0 +1,26 @@ +#------------------------------------------------- +# ORION - OpenGL ES 2.0 Shading Language Compiler +# SAMSUNG INDIA SOFTWARE OPERATIONS PVT. LTD. +# Compiler Version : v04.00.09 +# Release Date : 19.01.2009 +# FIMG VERSION : FIMGv1.5 +# Optimizer Options : -O --nolodcalc +#------------------------------------------------- + +# hand optimised - removed useless ops + +ps_3_0 + +fimg_version 0x01020000 + +dcl_s2_tex s0 +dcl_f4_col v1.x +dcl_f2_tex_c v0.x + +label start +label main_ +texld r0.xyzw, v0.xyzw, s0 # tex=s0 +mul_sat oColor.xyzw, r0.wwww, v1.xyzw # gl_FragColor=oColor.xyzw, col=v1.xyzw +label main_end +ret +# 4 instructions, 4 C regs, 1 R regs diff --git a/legacy/evas/src/modules/engines/gl_common/shader/font_vert.h b/legacy/evas/src/modules/engines/gl_common/shader/font_vert.h new file mode 100644 index 0000000000..1a4c076328 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/font_vert.h @@ -0,0 +1,12 @@ +"attribute vec4 vertex;\n" +"attribute vec4 color;\n" +"attribute vec2 tex_coord;\n" +"uniform mat4 mvp;\n" +"varying vec4 col;\n" +"varying vec2 tex_c;\n" +"void main()\n" +"{\n" +" gl_Position = mvp * vertex;\n" +" col = color;\n" +" tex_c = tex_coord;\n" +"}\n" diff --git a/legacy/evas/src/modules/engines/gl_common/shader/font_vert.shd b/legacy/evas/src/modules/engines/gl_common/shader/font_vert.shd new file mode 100644 index 0000000000..a42d7f04dd --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/font_vert.shd @@ -0,0 +1,12 @@ +attribute vec4 vertex; +attribute vec4 color; +attribute vec2 tex_coord; +uniform mat4 mvp; +varying vec4 col; +varying vec2 tex_c; +void main() +{ + gl_Position = mvp * vertex; + col = color; + tex_c = tex_coord; +} diff --git a/legacy/evas/src/modules/engines/gl_common/shader/img_frag.h b/legacy/evas/src/modules/engines/gl_common/shader/img_frag.h new file mode 100644 index 0000000000..94e7a86840 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/img_frag.h @@ -0,0 +1,7 @@ +"uniform sampler2D tex;\n" +"varying vec4 col;\n" +"varying vec2 tex_c;\n" +"void main()\n" +"{\n" +" gl_FragColor = texture2D(tex, tex_c.xy).bgra * col;\n" +"}\n" diff --git a/legacy/evas/src/modules/engines/gl_common/shader/img_frag.shd b/legacy/evas/src/modules/engines/gl_common/shader/img_frag.shd new file mode 100644 index 0000000000..9b91ac51b8 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/img_frag.shd @@ -0,0 +1,7 @@ +uniform sampler2D tex; +varying vec4 col; +varying vec2 tex_c; +void main() +{ + gl_FragColor = texture2D(tex, tex_c.xy).bgra * col; +} diff --git a/legacy/evas/src/modules/engines/gl_common/shader/img_frag_s3c6410.asm b/legacy/evas/src/modules/engines/gl_common/shader/img_frag_s3c6410.asm new file mode 100644 index 0000000000..3716bce4f4 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/img_frag_s3c6410.asm @@ -0,0 +1,26 @@ + +#------------------------------------------------- +# ORION - OpenGL ES 2.0 Shading Language Compiler +# SAMSUNG INDIA SOFTWARE OPERATIONS PVT. LTD. +# Compiler Version : v04.00.09 +# Release Date : 19.01.2009 +# FIMG VERSION : FIMGv1.5 +# Optimizer Options : -O --nolodcalc +#------------------------------------------------- + +# hand optimised - removed useless ops + +ps_3_0 + +fimg_version 0x01020000 + +dcl_s2_tex s0 +dcl_f4_col v1.x +dcl_f2_tex_c v0.x + +label start +label main_ +texld r0.xyzw, v0.xyzw, s0 # tex=s0 +mul_sat oColor.xyzw, r0.zyxw, v1.xyzw # gl_FragColor=oColor.xyzw, col=v1.xyzw +label main_end +ret diff --git a/legacy/evas/src/modules/engines/gl_common/shader/img_vert.h b/legacy/evas/src/modules/engines/gl_common/shader/img_vert.h new file mode 100644 index 0000000000..1a4c076328 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/img_vert.h @@ -0,0 +1,12 @@ +"attribute vec4 vertex;\n" +"attribute vec4 color;\n" +"attribute vec2 tex_coord;\n" +"uniform mat4 mvp;\n" +"varying vec4 col;\n" +"varying vec2 tex_c;\n" +"void main()\n" +"{\n" +" gl_Position = mvp * vertex;\n" +" col = color;\n" +" tex_c = tex_coord;\n" +"}\n" diff --git a/legacy/evas/src/modules/engines/gl_common/shader/img_vert.shd b/legacy/evas/src/modules/engines/gl_common/shader/img_vert.shd new file mode 100644 index 0000000000..a42d7f04dd --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/img_vert.shd @@ -0,0 +1,12 @@ +attribute vec4 vertex; +attribute vec4 color; +attribute vec2 tex_coord; +uniform mat4 mvp; +varying vec4 col; +varying vec2 tex_c; +void main() +{ + gl_Position = mvp * vertex; + col = color; + tex_c = tex_coord; +} diff --git a/legacy/evas/src/modules/engines/gl_common/shader/make-c-bin.sh b/legacy/evas/src/modules/engines/gl_common/shader/make-c-bin.sh new file mode 100755 index 0000000000..2902df6de2 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/make-c-bin.sh @@ -0,0 +1,3 @@ +#!/bin/sh +od --width=4 -t x4 -v $1 | \ +awk '{ if (NF > 1) printf("0x%s, ", $2); L = L + 1; if (L > 5) { L = 0; printf("\n");}}' diff --git a/legacy/evas/src/modules/engines/gl_common/shader/make-c-str.sh b/legacy/evas/src/modules/engines/gl_common/shader/make-c-str.sh new file mode 100755 index 0000000000..fe7e80a9cb --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/make-c-str.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +awk '{printf("\"%s\\n\"\n", $0);}' $1 diff --git a/legacy/evas/src/modules/engines/gl_common/shader/rect_frag.h b/legacy/evas/src/modules/engines/gl_common/shader/rect_frag.h new file mode 100644 index 0000000000..c80f114525 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/rect_frag.h @@ -0,0 +1,6 @@ +"uniform sampler2D tex;\n" +"varying vec4 col;\n" +"void main()\n" +"{\n" +" gl_FragColor = col;\n" +"}\n" diff --git a/legacy/evas/src/modules/engines/gl_common/shader/rect_frag.shd b/legacy/evas/src/modules/engines/gl_common/shader/rect_frag.shd new file mode 100644 index 0000000000..53b4e61c68 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/rect_frag.shd @@ -0,0 +1,6 @@ +uniform sampler2D tex; +varying vec4 col; +void main() +{ + gl_FragColor = col; +} diff --git a/legacy/evas/src/modules/engines/gl_common/shader/rect_frag_s3c6410.asm b/legacy/evas/src/modules/engines/gl_common/shader/rect_frag_s3c6410.asm new file mode 100644 index 0000000000..24c47ac2e6 --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/rect_frag_s3c6410.asm @@ -0,0 +1,24 @@ + +#------------------------------------------------- +# ORION - OpenGL ES 2.0 Shading Language Compiler +# SAMSUNG INDIA SOFTWARE OPERATIONS PVT. LTD. +# Compiler Version : v04.00.09 +# Release Date : 19.01.2009 +# FIMG VERSION : FIMGv1.5 +# Optimizer Options : -O --nolodcalc +#------------------------------------------------- + +# hand optimised - removed useless ops + +ps_3_0 + +fimg_version 0x01020000 + +dcl_f4_col v0.x + +label start +label main_ +label main_end +mov_sat oColor.xyzw, v0.xyzw +ret + diff --git a/legacy/evas/src/modules/engines/gl_common/shader/rect_vert.h b/legacy/evas/src/modules/engines/gl_common/shader/rect_vert.h new file mode 100644 index 0000000000..c20ed59fba --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/rect_vert.h @@ -0,0 +1,10 @@ +"attribute vec4 vertex;\n" +"attribute vec4 color;\n" +"attribute vec2 tex_coord;\n" +"uniform mat4 mvp;\n" +"varying vec4 col;\n" +"void main()\n" +"{\n" +" gl_Position = mvp * vertex;\n" +" col = color;\n" +"}\n" diff --git a/legacy/evas/src/modules/engines/gl_common/shader/rect_vert.shd b/legacy/evas/src/modules/engines/gl_common/shader/rect_vert.shd new file mode 100644 index 0000000000..d4bd52b53a --- /dev/null +++ b/legacy/evas/src/modules/engines/gl_common/shader/rect_vert.shd @@ -0,0 +1,10 @@ +attribute vec4 vertex; +attribute vec4 color; +attribute vec2 tex_coord; +uniform mat4 mvp; +varying vec4 col; +void main() +{ + gl_Position = mvp * vertex; + col = color; +} diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c index d11e7e631a..1e99aa85cf 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/gl_x11/evas_engine.c @@ -1,28 +1,18 @@ -#ifdef HAVE_GL_GLEW_H -# include -#else -# include -#endif - -#include "evas_gl_common.h" - -#include -#include -#include - -#include "evas_common.h" -#include "evas_private.h" #include "evas_engine.h" -#include "Evas_Engine_GL_X11.h" + +// EGL / GLES +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) +# if defined(GLES_VARIETY_S3C6410) +# elif defined(GLES_VARIETY_SGX) +# endif +// GLX +#else +#endif /* function tables - filled in later (func and parent func) */ static Evas_Func func, pfunc; -static Visual *eng_best_visual_get(Display *disp, int screen); -static Colormap eng_best_colormap_get(Display *disp, int screen); -static int eng_best_depth_get(Display *disp, int screen); - typedef struct _Render_Engine Render_Engine; struct _Render_Engine @@ -65,7 +55,10 @@ eng_setup(Evas *e, void *in) info = (Evas_Engine_Info_GL_X11 *)in; if (!e->engine.data.output) { +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) +#else if (!glXQueryExtension(info->info.display, &eb, &evb)) return 0; +#endif re = calloc(1, sizeof(Render_Engine)); if (!re) return 0; e->engine.data.output = re; @@ -251,6 +244,10 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i if (cw) *cw = re->win->draw.x2 - re->win->draw.x1 + 1; if (ch) *ch = re->win->draw.y2 - re->win->draw.y1 + 1; #endif +// clear buffer. only needed for dest alpha +// glClearColor(0.0f, 0.0f, 0.0f, 0.0f); +// glClear(GL_COLOR_BUFFER_BIT); +//x// printf("frame -> new\n"); return re; } @@ -261,9 +258,10 @@ eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x re = (Render_Engine *)data; /* put back update surface.. in this case just unflag redraw */ -// printf("GL: update done.\n"); re->win->draw.redraw = 0; re->win->draw.drew = 1; + evas_gl_common_context_flush(re->win->gl_context); +//x// printf("frame -> push\n"); } static void @@ -273,32 +271,34 @@ eng_output_flush(void *data) re = (Render_Engine *)data; if (!re->win->draw.drew) return; +//x// printf("frame -> flush\n"); re->win->draw.drew = 0; -// printf("GL: flush your mush!\n"); eng_window_use(re->win); -#ifdef VSYNC_TO_SCREEN - glFlush(); +# if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]); +#else +# ifdef VSYNC_TO_SCREEN { unsigned int rc; - + glXGetVideoSyncSGI(&rc); glXWaitVideoSyncSGI(2, (rc + 1) % 2, &rc); } -#endif -#ifdef SLOW_GL_COPY_RECT +# endif +# ifdef SLOW_GL_COPY_RECT glXSwapBuffers(re->win->disp, re->win->win); -#else +# else /* SLOW AS ALL HELL! */ evas_gl_common_swap_rect(re->win->gl_context, re->win->draw.x1, re->win->draw.y1, re->win->draw.x2 - re->win->draw.x1 + 1, re->win->draw.y2 - re->win->draw.y1 + 1); -#endif +# endif // glFlush(); // glXWaitGL(); // XSync(re->win->disp, False); -// printf("SYNC! %i\n", fr++); +#endif } static void @@ -315,10 +315,8 @@ eng_context_cutout_add(void *data, void *context, int x, int y, int w, int h) Render_Engine *re; re = (Render_Engine *)data; -#ifndef EVAS_GL_COMMON_NOCUTOUTS re->win->gl_context->dc = context; evas_common_draw_context_add_cutout(context, x, y, w, h); -#endif } static void @@ -327,10 +325,8 @@ eng_context_cutout_clear(void *data, void *context) Render_Engine *re; re = (Render_Engine *)data; -#ifndef EVAS_GL_COMMON_NOCUTOUTS re->win->gl_context->dc = context; evas_common_draw_context_clear_cutouts(context); -#endif } static void @@ -350,8 +346,9 @@ eng_line_draw(void *data, void *context, void *surface __UNUSED__, int x1, int y Render_Engine *re; re = (Render_Engine *)data; + eng_window_use(re->win); re->win->gl_context->dc = context; - evas_gl_common_line_draw(re->win->gl_context, x1, y1, x2, y2); +//-// evas_gl_common_line_draw(re->win->gl_context, x1, y1, x2, y2); } static void * @@ -360,8 +357,8 @@ eng_polygon_point_add(void *data, void *context __UNUSED__, void *polygon, int x Render_Engine *re; re = (Render_Engine *)data; - return evas_gl_common_poly_point_add(polygon, x, y); - +//--// return evas_gl_common_poly_point_add(polygon, x, y); + return NULL; } static void * @@ -370,7 +367,8 @@ eng_polygon_points_clear(void *data, void *context __UNUSED__, void *polygon) Render_Engine *re; re = (Render_Engine *)data; - return evas_gl_common_poly_points_clear(polygon); +//--// return evas_gl_common_poly_points_clear(polygon); + return NULL; } static void @@ -379,8 +377,9 @@ eng_polygon_draw(void *data, void *context, void *surface __UNUSED__, void *poly Render_Engine *re; re = (Render_Engine *)data; + eng_window_use(re->win); re->win->gl_context->dc = context; - evas_gl_common_poly_draw(re->win->gl_context, polygon); +//--// evas_gl_common_poly_draw(re->win->gl_context, polygon); } static void @@ -493,85 +492,86 @@ eng_gradient2_radial_draw(void *data __UNUSED__, void *context __UNUSED__, void static void * eng_gradient_new(void *data __UNUSED__) { - return evas_gl_common_gradient_new(); +//--// return evas_gl_common_gradient_new(); + return NULL; } static void eng_gradient_color_stop_add(void *data __UNUSED__, void *gradient, int r, int g, int b, int a, int delta) { - evas_gl_common_gradient_color_stop_add(gradient, r, g, b, a, delta); +//--// evas_gl_common_gradient_color_stop_add(gradient, r, g, b, a, delta); } static void eng_gradient_alpha_stop_add(void *data __UNUSED__, void *gradient, int a, int delta) { - evas_gl_common_gradient_alpha_stop_add(gradient, a, delta); +//--// evas_gl_common_gradient_alpha_stop_add(gradient, a, delta); } static void eng_gradient_clear(void *data __UNUSED__, void *gradient) { - evas_gl_common_gradient_clear(gradient); +//--// evas_gl_common_gradient_clear(gradient); } static void eng_gradient_color_data_set(void *data __UNUSED__, void *gradient, void *map, int len, int has_alpha) { - evas_gl_common_gradient_color_data_set(gradient, map, len, has_alpha); +//--// evas_gl_common_gradient_color_data_set(gradient, map, len, has_alpha); } static void eng_gradient_alpha_data_set(void *data __UNUSED__, void *gradient, void *alpha_map, int len) { - evas_gl_common_gradient_alpha_data_set(gradient, alpha_map, len); +//--// evas_gl_common_gradient_alpha_data_set(gradient, alpha_map, len); } static void eng_gradient_free(void *data __UNUSED__, void *gradient) { - evas_gl_common_gradient_free(gradient); +//--// evas_gl_common_gradient_free(gradient); } static void eng_gradient_fill_set(void *data __UNUSED__, void *gradient, int x, int y, int w, int h) { - evas_gl_common_gradient_fill_set(gradient, x, y, w, h); +//--// evas_gl_common_gradient_fill_set(gradient, x, y, w, h); } static void eng_gradient_fill_angle_set(void *data __UNUSED__, void *gradient, double angle) { - evas_gl_common_gradient_fill_angle_set(gradient, angle); +//--// evas_gl_common_gradient_fill_angle_set(gradient, angle); } static void eng_gradient_fill_spread_set(void *data __UNUSED__, void *gradient, int spread) { - evas_gl_common_gradient_fill_spread_set(gradient, spread); +//--// evas_gl_common_gradient_fill_spread_set(gradient, spread); } static void eng_gradient_angle_set(void *data __UNUSED__, void *gradient, double angle) { - evas_gl_common_gradient_map_angle_set(gradient, angle); +//--// evas_gl_common_gradient_map_angle_set(gradient, angle); } static void eng_gradient_offset_set(void *data __UNUSED__, void *gradient, float offset) { - evas_gl_common_gradient_map_offset_set(gradient, offset); +//--// evas_gl_common_gradient_map_offset_set(gradient, offset); } static void eng_gradient_direction_set(void *data __UNUSED__, void *gradient, int direction) { - evas_gl_common_gradient_map_direction_set(gradient, direction); +//--// evas_gl_common_gradient_map_direction_set(gradient, direction); } static void eng_gradient_type_set(void *data __UNUSED__, void *gradient, char *name, char *params) { - evas_gl_common_gradient_type_set(gradient, name, params); +//--// evas_gl_common_gradient_type_set(gradient, name, params); } static int @@ -580,7 +580,8 @@ eng_gradient_is_opaque(void *data, void *context, void *gradient, int x, int y, Render_Engine *re = (Render_Engine *)data; re->win->gl_context->dc = context; - return evas_gl_common_gradient_is_opaque(re->win->gl_context, gradient, x, y, w, h); +//--// return evas_gl_common_gradient_is_opaque(re->win->gl_context, gradient, x, y, w, h); + return 0; } static int @@ -589,7 +590,8 @@ eng_gradient_is_visible(void *data, void *context, void *gradient, int x, int y, Render_Engine *re = (Render_Engine *)data; re->win->gl_context->dc = context; - return evas_gl_common_gradient_is_visible(re->win->gl_context, gradient, x, y, w, h); +//--// return evas_gl_common_gradient_is_visible(re->win->gl_context, gradient, x, y, w, h); + return 0; } static void @@ -598,13 +600,13 @@ eng_gradient_render_pre(void *data, void *context, void *gradient) Render_Engine *re = (Render_Engine *)data; re->win->gl_context->dc = context; - evas_gl_common_gradient_render_pre(re->win->gl_context, gradient); +//--// evas_gl_common_gradient_render_pre(re->win->gl_context, gradient); } static void eng_gradient_render_post(void *data __UNUSED__, void *gradient) { - evas_gl_common_gradient_render_post(gradient); +//--// evas_gl_common_gradient_render_post(gradient); } static void @@ -615,7 +617,7 @@ eng_gradient_draw(void *data, void *context, void *surface __UNUSED__, void *gra re = (Render_Engine *)data; eng_window_use(re->win); re->win->gl_context->dc = context; - evas_gl_common_gradient_draw(re->win->gl_context, gradient, x, y, w, h); +//--// evas_gl_common_gradient_draw(re->win->gl_context, gradient, x, y, w, h); } static int @@ -665,15 +667,15 @@ eng_image_alpha_set(void *data, void *image, int has_alpha) if ((has_alpha) && (im->im->cache_entry.flags.alpha)) return image; else if ((!has_alpha) && (!im->im->cache_entry.flags.alpha)) return image; if (im->references > 1) - { - Evas_GL_Image *im_new; - - im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->cache_entry.w, im->im->cache_entry.h, im->im->image.data, - eng_image_alpha_get(data, image), - eng_image_colorspace_get(data, image)); - if (!im_new) return im; - evas_gl_common_image_free(im); - im = im_new; + { + Evas_GL_Image *im_new; + + im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->cache_entry.w, im->im->cache_entry.h, im->im->image.data, + eng_image_alpha_get(data, image), + eng_image_colorspace_get(data, image)); + if (!im_new) return im; + evas_gl_common_image_free(im); + im = im_new; } else evas_gl_common_image_dirty(im); @@ -732,6 +734,7 @@ eng_image_colorspace_set(void *data, void *image, int cspace) im = image; /* FIXME: can move to gl_common */ if (im->cs.space == cspace) return; + eng_window_use(re->win); evas_cache_image_colorspace(&im->im->cache_entry, cspace); switch (cspace) { @@ -745,8 +748,8 @@ eng_image_colorspace_set(void *data, void *image, int cspace) break; case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P709_PL: - if (im->tex) evas_gl_common_texture_free(im->tex); - im->tex = NULL; + if (im->tex) evas_gl_common_texture_free(im->tex); + im->tex = NULL; if (im->cs.data) { if (!im->cs.no_free) free(im->cs.data); @@ -781,6 +784,7 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I *error = 0; eng_window_use(re->win); return evas_gl_common_image_load(re->win->gl_context, file, key, lo); + return NULL; } static void * @@ -791,6 +795,7 @@ eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, re = (Render_Engine *)data; eng_window_use(re->win); return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace); + return NULL; } static void * @@ -801,6 +806,7 @@ eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int re = (Render_Engine *)data; eng_window_use(re->win); return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace); + return NULL; } static void @@ -847,9 +853,9 @@ eng_image_size_set(void *data, void *image, int w, int h) return image; if (im_old) { - im = evas_gl_common_image_new(re->win->gl_context, w, h, - eng_image_alpha_get(data, image), - eng_image_colorspace_get(data, image)); + im = evas_gl_common_image_new(re->win->gl_context, w, h, + eng_image_alpha_get(data, image), + eng_image_colorspace_get(data, image)); /* evas_common_load_image_data_from_file(im_old->im); if (im_old->im->image->data) @@ -858,7 +864,7 @@ eng_image_size_set(void *data, void *image, int w, int h) evas_common_cpu_end_opt(); } */ - evas_gl_common_image_free(im_old); + evas_gl_common_image_free(im_old); } else im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888); @@ -872,6 +878,7 @@ eng_image_dirty_region(void *data, void *image, int x __UNUSED__, int y __UNUSED re = (Render_Engine *)data; if (!image) return NULL; + eng_window_use(re->win); evas_gl_common_image_dirty(image); return image; } @@ -900,19 +907,19 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data) { Evas_GL_Image *im_new; - im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->cache_entry.w, im->im->cache_entry.h, im->im->image.data, - eng_image_alpha_get(data, image), - eng_image_colorspace_get(data, image)); - if (!im_new) - { - *image_data = NULL; - return im; - } - evas_gl_common_image_free(im); - im = im_new; + im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->cache_entry.w, im->im->cache_entry.h, im->im->image.data, + eng_image_alpha_get(data, image), + eng_image_colorspace_get(data, image)); + if (!im_new) + { + *image_data = NULL; + return im; + } + evas_gl_common_image_free(im); + im = im_new; } - else - evas_gl_common_image_dirty(im); + else + evas_gl_common_image_dirty(im); } *image_data = im->im->image.data; break; @@ -949,9 +956,9 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) im2 = eng_image_new_from_data(data, w, h, image_data, eng_image_alpha_get(data, image), eng_image_colorspace_get(data, image)); - if (!im2) return im; - evas_gl_common_image_free(im); - im = im2; + if (!im2) return im; + evas_gl_common_image_free(im); + im = im2; } break; case EVAS_COLORSPACE_YCBCR422P601_PL: @@ -1008,9 +1015,9 @@ eng_image_draw(void *data, void *context, void *surface __UNUSED__, void *image, eng_window_use(re->win); re->win->gl_context->dc = context; evas_gl_common_image_draw(re->win->gl_context, image, - src_x, src_y, src_w, src_h, - dst_x, dst_y, dst_w, dst_h, - smooth); + src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h, + smooth); } static void @@ -1030,18 +1037,20 @@ eng_font_draw(void *data, void *context, void *surface __UNUSED__, void *font, i Render_Engine *re; re = (Render_Engine *)data; + eng_window_use(re->win); { + // FIXME: put im into context so we can free it static RGBA_Image *im = NULL; - - if (!im) - im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get()); - evas_cache_image_surface_alloc(&im->cache_entry, re->win->w, re->win->h); - - evas_common_draw_context_font_ext_set(context, - re->win->gl_context, - evas_gl_font_texture_new, - evas_gl_font_texture_free, - evas_gl_font_texture_draw); + + if (!im) + im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); + im->cache_entry.w = re->win->w; + im->cache_entry.h = re->win->h; + evas_common_draw_context_font_ext_set(context, + re->win->gl_context, + evas_gl_font_texture_new, + evas_gl_font_texture_free, + evas_gl_font_texture_draw); evas_common_font_draw(im, context, font, x, y, text); evas_common_draw_context_font_ext_set(context, NULL, @@ -1051,44 +1060,10 @@ eng_font_draw(void *data, void *context, void *surface __UNUSED__, void *font, i } } -/* private engine functions the calling prog can use */ - -static Visual * -eng_best_visual_get(Display *disp, int screen) -{ - if (!disp) return NULL; - if (!_evas_gl_x11_vi) - _evas_gl_x11_vi = glXChooseVisual(disp, screen, - _evas_gl_x11_configuration); - if (!_evas_gl_x11_vi) return NULL; - return _evas_gl_x11_vi->visual; -} - -static Colormap -eng_best_colormap_get(Display *disp, int screen) -{ - if (!disp) return 0; - if (!_evas_gl_x11_vi) - eng_best_visual_get(disp, screen); - if (!_evas_gl_x11_vi) return 0; - _evas_gl_x11_cmap = XCreateColormap(disp, RootWindow(disp, screen), - _evas_gl_x11_vi->visual, 0); - return _evas_gl_x11_cmap; -} - -static int -eng_best_depth_get(Display *disp, int screen) -{ - if (!disp) return 0; - if (!_evas_gl_x11_vi) - eng_best_visual_get(disp, screen); - if (!_evas_gl_x11_vi) return 0; - return _evas_gl_x11_vi->depth; -} - static Eina_Bool eng_canvas_alpha_get(void *data __UNUSED__, void *info __UNUSED__) { + // FIXME: support ARGB gl targets!!! return EINA_FALSE; } diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_engine.h b/legacy/evas/src/modules/engines/gl_x11/evas_engine.h index 6968ddbc95..f81980813e 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_engine.h +++ b/legacy/evas/src/modules/engines/gl_x11/evas_engine.h @@ -1,11 +1,39 @@ #ifndef EVAS_ENGINE_H #define EVAS_ENGINE_H -#include -#include -#include - +#include "config.h" +#ifdef HAVE_GL_GLEW_H +# include +#else +# if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) +# if defined(GLES_VARIETY_S3C6410) +# include +# include +# include +# include +# include +# elif defined(GLES_VARIETY_SGX) +# define SUPPORT_X11 1 +# include +# include +# include +# include +# include +# endif +# else +# include +# include +# include +# include +# include +# include +# endif +#endif +#include "evas_common.h" +#include "evas_private.h" #include "evas_gl_common.h" +#include "Evas.h" +#include "Evas_Engine_GL_X11.h" typedef struct _Evas_GL_X11_Window Evas_GL_X11_Window; @@ -19,31 +47,30 @@ struct _Evas_GL_X11_Window Visual *visual; Colormap colormap; int depth; - GLXContext context; Evas_GL_Context *gl_context; struct { int redraw : 1; int drew : 1; int x1, y1, x2, y2; } draw; +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + EGLContext egl_context[1]; + EGLSurface egl_surface[1]; + EGLConfig egl_config; + EGLDisplay egl_disp; +#else + GLXContext context; +#endif + }; -extern int _evas_gl_x11_configuration[9]; -extern XVisualInfo *_evas_gl_x11_vi; -extern Colormap _evas_gl_x11_cmap; - -Evas_GL_X11_Window * - eng_window_new(Display *disp, - Window win, - int screen, - Visual *vis, - Colormap cmap, - int depth, - int w, - int h); -void - eng_window_free(Evas_GL_X11_Window *gw); -void - eng_window_use(Evas_GL_X11_Window *gw); +Evas_GL_X11_Window *eng_window_new(Display *disp, Window win, int screen, + Visual *vis, Colormap cmap, + int depth, int w, int h); +void eng_window_free(Evas_GL_X11_Window *gw); +void eng_window_use(Evas_GL_X11_Window *gw); +Visual *eng_best_visual_get(Display *disp, int screen); +Colormap eng_best_colormap_get(Display *disp, int screen); +int eng_best_depth_get(Display *disp, int screen); #endif diff --git a/legacy/evas/src/modules/engines/gl_x11/evas_x_main.c b/legacy/evas/src/modules/engines/gl_x11/evas_x_main.c index bccd783898..5571468d5b 100644 --- a/legacy/evas/src/modules/engines/gl_x11/evas_x_main.c +++ b/legacy/evas/src/modules/engines/gl_x11/evas_x_main.c @@ -1,29 +1,13 @@ -#include "evas_gl_common.h" - -#include -#include -#include -#include - -#include "evas_common.h" -#include "evas_private.h" #include "evas_engine.h" -#include "Evas_Engine_GL_X11.h" static Evas_GL_X11_Window *_evas_gl_x11_window = NULL; -/* FIXME: this will only work for 1 display connection... :( */ -static GLXContext context = 0; - -int _evas_gl_x11_configuration[9] = -{ - GLX_DOUBLEBUFFER, - GLX_RGBA, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - None -}; +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) +static EGLContext context = EGL_NO_CONTEXT; +#else +// FIXME: this will only work for 1 display connection (glx land can have > 1) +static GLXContext context = NULL; +#endif XVisualInfo *_evas_gl_x11_vi = NULL; Colormap _evas_gl_x11_cmap = 0; @@ -39,8 +23,13 @@ eng_window_new(Display *disp, int h) { Evas_GL_X11_Window *gw; - + int context_attrs[3]; + int config_attrs[20]; + int major_version, minor_version; + int num_config; + if (!_evas_gl_x11_vi) return NULL; + gw = calloc(1, sizeof(Evas_GL_X11_Window)); if (!gw) return NULL; gw->disp = disp; @@ -51,14 +40,106 @@ eng_window_new(Display *disp, gw->depth = depth; gw->visualinfo = _evas_gl_x11_vi; + +// EGL / GLES +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION; + context_attrs[1] = 2; + context_attrs[2] = EGL_NONE; +# if defined(GLES_VARIETY_S3C6410) + if (_evas_gles_x11_vi->depth == 16) // 16bpp + { + config_attrs[0] = EGL_SURFACE_TYPE; + config_attrs[1] = EGL_WINDOW_BIT; + config_attrs[2] = EGL_RENDERABLE_TYPE; + config_attrs[3] = EGL_OPENGL_ES2_BIT; + config_attrs[4] = EGL_RED_SIZE; + config_attrs[5] = 5; + config_attrs[6] = EGL_GREEN_SIZE; + config_attrs[7] = 6; + config_attrs[8] = EGL_BLUE_SIZE; + config_attrs[9] = 5; + config_attrs[10] = EGL_NONE; + } + else // 24/32bit. no one does 8bpp anymore. and 15bpp... dead + { + config_attrs[0] = EGL_SURFACE_TYPE; + config_attrs[1] = EGL_WINDOW_BIT; + config_attrs[2] = EGL_RENDERABLE_TYPE; + config_attrs[3] = EGL_OPENGL_ES2_BIT; + config_attrs[4] = EGL_RED_SIZE; + config_attrs[5] = 8; + config_attrs[6] = EGL_GREEN_SIZE; + config_attrs[7] = 8; + config_attrs[8] = EGL_BLUE_SIZE; + config_attrs[9] = 8; + config_attrs[10] = EGL_DEPTH_SIZE; + config_attrs[11] = 24; + config_attrs[12] = EGL_NONE; + } +# elif defined(GLES_VARIETY_SGX) + context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION; + context_attrs[1] = 2; + context_attrs[2] = EGL_NONE; + + config_attrs[0] = EGL_SURFACE_TYPE; + config_attrs[1] = EGL_WINDOW_BIT; + config_attrs[2] = EGL_RENDERABLE_TYPE; + config_attrs[3] = EGL_OPENGL_ES2_BIT; + config_attrs[4] = EGL_NONE; +# endif + gw->egl_disp= eglGetDisplay((EGLNativeDisplayType)(gw->disp)); + if (!gw->egl_disp) + { + printf("Error: eglGetDisplay() fail.\n"); + } + if (!eglInitialize(gw->egl_disp, &major_version, &minor_version)) + { + printf("Error: eglInitialize() fail.\n"); + } + eglBindAPI(EGL_OPENGL_ES_API); + if (eglGetError() != EGL_SUCCESS) + { + printf("Error: eglBindAPI() fail.\n"); + } + if (!eglChooseConfig(gw->egl_disp, config_attrs, &gw->egl_config, + 1, &num_config) || (num_config != 1)) + { + printf("Error: eglChooseConfig() fail.\n"); + } + gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config, + (EGLNativeWindowType)gw->win, + NULL); + if (gw->egl_surface[0] == EGL_NO_SURFACE) + { + printf("Error: eglCreateWindowSurface() fail.\n", gw->win); + } + if (context == EGL_NO_CONTEXT) + context = eglCreateContext(gw->egl_disp, gw->egl_config, NULL, + context_attrs); + gw->egl_context[0] = context; + if (gw->egl_context[0] == EGL_NO_CONTEXT) + { + printf("Error: eglCreateContext() fail.\n"); + } + if (eglMakeCurrent(gw->egl_disp, + gw->egl_surface[0], + gw->egl_surface[0], + gw->egl_context[0]) == EGL_FALSE) + { + printf("Error: eglMakeCurrent() fail.\n"); + } +// GLX +#else if (!context) context = glXCreateContext(disp, gw->visualinfo, NULL, GL_TRUE); gw->context = context; glXMakeCurrent(gw->disp, gw->win, gw->context); +#endif + gw->gl_context = evas_gl_common_context_new(); if (!gw->gl_context) { - glXDestroyContext(gw->disp, gw->context); free(gw); return NULL; } @@ -71,7 +152,13 @@ eng_window_free(Evas_GL_X11_Window *gw) { if (gw == _evas_gl_x11_window) _evas_gl_x11_window = NULL; evas_gl_common_context_free(gw->gl_context); -// glXDestroyContext(gw->disp, gw->context); +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + if (gw->egl_surface[0] != EGL_NO_SURFACE) + eglDestroySurface(gw->egl_disp, gw->egl_surface[0]); +#else + // FIXME: refcount context + // glXDestroyContext(gw->disp, gw->context); +#endif free(gw); } @@ -81,7 +168,74 @@ eng_window_use(Evas_GL_X11_Window *gw) if (_evas_gl_x11_window != gw) { _evas_gl_x11_window = gw; - glXMakeCurrent(gw->disp, gw->win, gw->context); +// EGL / GLES +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + if (eglMakeCurrent(gw->egl_disp, + gw->egl_surface[0], + gw->egl_surface[0], + gw->egl_context[0]) == EGL_FALSE) + { + printf("Error: eglMakeCurrent() failed!\n"); + } +// GLX +#else + glXMakeCurrent(gw->disp, gw->win, gw->context); +#endif } evas_gl_common_context_use(gw->gl_context); } + +Visual * +eng_best_visual_get(Display *disp, int screen) +{ + if (!disp) return NULL; + if (!_evas_gl_x11_vi) + { +// EGL / GLES +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + int depth = DefaultDepth(disp, screen); + _evas_gl_x11_vi = calloc(1, sizeof(XVisualInfo)); + XMatchVisualInfo(disp, screen, depth, TrueColor, _evas_gl_x11_vi); +// GLX +#else + int _evas_gl_x11_configuration[9] = + { + GLX_DOUBLEBUFFER, + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None + }; + _evas_gl_x11_vi = glXChooseVisual(disp, screen, + _evas_gl_x11_configuration); +#endif + } + if (!_evas_gl_x11_vi) return NULL; + return _evas_gl_x11_vi->visual; +} + +Colormap +eng_best_colormap_get(Display *disp, int screen) +{ + if (!disp) return 0; + if (!_evas_gl_x11_vi) eng_best_visual_get(disp, screen); + if (!_evas_gl_x11_vi) return 0; + if (!_evas_gl_x11_cmap) + { + _evas_gl_x11_cmap = XCreateColormap(disp, + RootWindow(disp, screen), + _evas_gl_x11_vi->visual, + 0); + } + return _evas_gl_x11_cmap; +} + +int +eng_best_depth_get(Display *disp, int screen) +{ + if (!disp) return 0; + if (!_evas_gl_x11_vi) eng_best_visual_get(disp, screen); + if (!_evas_gl_x11_vi) return 0; + return _evas_gl_x11_vi->depth; +}