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
This commit is contained in:
Carsten Haitzler 2009-10-09 12:10:27 +00:00
parent fd65247e8e
commit 37b66e806b
36 changed files with 1721 additions and 1826 deletions

View File

@ -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])

View File

@ -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"]
)

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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 <GL/glew.h>
#else
# define GL_GLEXT_PROTOTYPES
#endif /* BUILD_ENGINE_GL_GLEW */
#endif
#ifdef BUILD_ENGINE_GL_QUARTZ
# include <OpenGL/gl.h>
# include <OpenGL/glu.h>
#else
# include <GL/gl.h>
# include <GL/glu.h>
#endif /* BUILD_ENGINE_GL_QUARTZ */
# if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
# if defined(GLES_VARIETY_S3C6410)
# include <GLES/gl.h>
# elif defined(GLES_VARIETY_SGX)
# include <GLES2/gl2.h>
# endif
# else
# include <GL/gl.h>
# 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:
*

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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

View File

@ -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);
}

View File

@ -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++;
}

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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;
}

View File

@ -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

View File

@ -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"

View File

@ -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;
}

View File

@ -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"

View File

@ -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;
}

View File

@ -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

View File

@ -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"

View File

@ -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;
}

View File

@ -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");}}'

View File

@ -0,0 +1,3 @@
#!/bin/sh
awk '{printf("\"%s\\n\"\n", $0);}' $1

View File

@ -0,0 +1,6 @@
"uniform sampler2D tex;\n"
"varying vec4 col;\n"
"void main()\n"
"{\n"
" gl_FragColor = col;\n"
"}\n"

View File

@ -0,0 +1,6 @@
uniform sampler2D tex;
varying vec4 col;
void main()
{
gl_FragColor = col;
}

View File

@ -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

View File

@ -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"

View File

@ -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;
}

View File

@ -1,28 +1,18 @@
#ifdef HAVE_GL_GLEW_H
# include <GL/glxew.h>
#else
# include <GL/glx.h>
#endif
#include "evas_gl_common.h"
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#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;
}

View File

@ -1,11 +1,39 @@
#ifndef EVAS_ENGINE_H
#define EVAS_ENGINE_H
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include "config.h"
#ifdef HAVE_GL_GLEW_H
# include <GL/glxew.h>
#else
# if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
# if defined(GLES_VARIETY_S3C6410)
# include <EGL/egl.h>
# include <GLES/gl.h>
# include <X11/Xlib.h>
# include <X11/Xatom.h>
# include <X11/Xutil.h>
# elif defined(GLES_VARIETY_SGX)
# define SUPPORT_X11 1
# include <EGL/egl.h>
# include <GLES2/gl2.h>
# include <X11/Xlib.h>
# include <X11/Xatom.h>
# include <X11/Xutil.h>
# endif
# else
# include <GL/glx.h>
# include <X11/Xlib.h>
# include <X11/Xatom.h>
# include <X11/Xutil.h>
# include <GL/gl.h>
# include <GL/glx.h>
# 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

View File

@ -1,29 +1,13 @@
#include "evas_gl_common.h"
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>
#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;
}