open gl is fulyl functional now - it coudl defnitely do with optimizations
with texture upload. it does NOt check error returns anywhere from gl... this may mean issues with LOTs of images, LARGE images etc. need to fix that later SVN revision: 7432
This commit is contained in:
parent
9606e485e5
commit
246fd31846
|
@ -1,7 +1,10 @@
|
|||
#include "config.h"
|
||||
#include "evas_test_main.h"
|
||||
|
||||
//#define VID_TEST
|
||||
// test writing to image objects for video playback
|
||||
//define VID_TEST
|
||||
// actualyl fill the video buffer (not fair a test as cpu spends time filling)
|
||||
//#define VID_WRITE
|
||||
|
||||
#define EVAS_PI (3.141592654)
|
||||
|
||||
|
@ -141,6 +144,7 @@ loop(void)
|
|||
{
|
||||
int tt;
|
||||
|
||||
#ifdef VID_WRITE
|
||||
tt = t * 1000;
|
||||
for (y = 0; y < ih; y++)
|
||||
{
|
||||
|
@ -148,6 +152,7 @@ loop(void)
|
|||
data[(y * iw) + x] =
|
||||
(((x * y / 10) + tt)) | 0xff000000;
|
||||
}
|
||||
#endif
|
||||
evas_object_image_data_update_add(test_pattern, 0, 0, iw, ih);
|
||||
evas_object_image_data_set(test_pattern, data);
|
||||
}
|
||||
|
@ -156,7 +161,10 @@ loop(void)
|
|||
}
|
||||
else if (t > 5.0)
|
||||
{
|
||||
printf("# EVAS BENCH: %3.3f\n", ((double)frames / (t - time_start)) / 60.0);
|
||||
printf("# FRAME COUNT: %i frames\n", frames);
|
||||
printf("# TIME: %3.3f seconds\n", (t - time_start));
|
||||
printf("# AVERAGE FPS: %3.3f fps\n", (double)frames / (t - time_start));
|
||||
printf("# EVAS BENCH: %3.3f\n", ((double)frames / (t - time_start)) / 60.0);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -20,6 +20,19 @@ evas_common_draw_context_free(RGBA_Draw_Context *dc)
|
|||
free(dc);
|
||||
}
|
||||
|
||||
void
|
||||
evas_common_draw_context_font_ext_set(RGBA_Draw_Context *dc,
|
||||
void *data,
|
||||
void *(*gl_new) (void *data, RGBA_Font_Glyph *fg),
|
||||
void (*gl_free) (void *ext_dat),
|
||||
void (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, int y))
|
||||
{
|
||||
dc->font_ext.data = data;
|
||||
dc->font_ext.func.gl_new = gl_new;
|
||||
dc->font_ext.func.gl_free = gl_free;
|
||||
dc->font_ext.func.gl_draw = gl_draw;
|
||||
}
|
||||
|
||||
void
|
||||
evas_common_draw_context_clip_clip(RGBA_Draw_Context *dc, int x, int y, int w, int h)
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@ evas_common_font_cache_glyph_get(RGBA_Font *fn, FT_UInt index)
|
|||
}
|
||||
fg->glyph_out = (FT_BitmapGlyph)fg->glyph;
|
||||
|
||||
fn->glyphs = evas_hash_add(fn->glyphs, key, fg);
|
||||
fn->glyphs = evas_hash_add(fn->glyphs, key, fg);
|
||||
return fg;
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,13 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
|
|||
}
|
||||
fg = evas_common_font_cache_glyph_get(fn, index);
|
||||
if (!fg) continue;
|
||||
|
||||
if ((dc->font_ext.func.gl_new) && (!fg->ext_dat))
|
||||
{
|
||||
/* extension calls */
|
||||
fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg);
|
||||
fg->ext_dat_free = dc->font_ext.func.gl_free;
|
||||
}
|
||||
|
||||
chr_x = (pen_x + (fg->glyph_out->left << 8)) >> 8;
|
||||
chr_y = (pen_y + (fg->glyph_out->top << 8)) >> 8;
|
||||
|
@ -133,33 +140,46 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
|
|||
{
|
||||
if ((j > 0) && (chr_x + w > ext_x))
|
||||
{
|
||||
for (i = 0; i < h; i++)
|
||||
if (fg->ext_dat)
|
||||
{
|
||||
int dx, dy;
|
||||
int in_x, in_w;
|
||||
|
||||
in_x = 0;
|
||||
in_w = 0;
|
||||
dx = chr_x;
|
||||
dy = y - (chr_y - i - y);
|
||||
if ((dx < (ext_x + ext_w)) &&
|
||||
(dy >= (ext_y)) &&
|
||||
(dy < (ext_y + ext_h)))
|
||||
/* ext glyph draw */
|
||||
dc->font_ext.func.gl_draw(dc->font_ext.data,
|
||||
NULL,
|
||||
dc, fg,
|
||||
chr_x,
|
||||
y - (chr_y - y)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
if (dx + w > (ext_x + ext_w))
|
||||
in_w += (dx + w) - (ext_x + ext_w);
|
||||
if (dx < ext_x)
|
||||
int dx, dy;
|
||||
int in_x, in_w;
|
||||
|
||||
in_x = 0;
|
||||
in_w = 0;
|
||||
dx = chr_x;
|
||||
dy = y - (chr_y - i - y);
|
||||
if ((dx < (ext_x + ext_w)) &&
|
||||
(dy >= (ext_y)) &&
|
||||
(dy < (ext_y + ext_h)))
|
||||
{
|
||||
in_w += ext_x - dx;
|
||||
in_x = ext_x - dx;
|
||||
dx = ext_x;
|
||||
}
|
||||
if (in_w < w)
|
||||
{
|
||||
func(data + (i * j) + in_x,
|
||||
im + (dy * im_w) + dx,
|
||||
w - in_w,
|
||||
dc->col.col);
|
||||
if (dx + w > (ext_x + ext_w))
|
||||
in_w += (dx + w) - (ext_x + ext_w);
|
||||
if (dx < ext_x)
|
||||
{
|
||||
in_w += ext_x - dx;
|
||||
in_x = ext_x - dx;
|
||||
dx = ext_x;
|
||||
}
|
||||
if (in_w < w)
|
||||
{
|
||||
func(data + (i * j) + in_x,
|
||||
im + (dy * im_w) + dx,
|
||||
w - in_w,
|
||||
dc->col.col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -182,6 +182,8 @@ font_flush_free_glyph_cb(Evas_Hash *hash, const char *key, void *data, void *fda
|
|||
|
||||
fg = data;
|
||||
FT_Done_Glyph(fg->glyph);
|
||||
/* extension calls */
|
||||
if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat);
|
||||
free(fg);
|
||||
return 1;
|
||||
hash = 0;
|
||||
|
|
|
@ -65,8 +65,16 @@ evas_gl_common_context_use(Evas_GL_Context *gc)
|
|||
{
|
||||
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;
|
||||
printf("EXT supported: GL_SGIS_generate_mipmap = %x\n", gc->ext.sgis_generate_mipmap);
|
||||
printf("EXT supported: GL_NV_texture_rectangle = %x\n", gc->ext.nv_texture_rectangle);
|
||||
/* technically this should work, as its a compatible */
|
||||
/* implementation of the nvidia texture_rectangle extension */
|
||||
/* since the #define value is the same as is the description */
|
||||
/* if (strstr(ext, "GL_EXT_texture_rectangle")) gc->ext.nv_texture_rectangle = 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("GL EXT supported: No extensions!!!!!\n");
|
||||
}
|
||||
gc->ext.checked = 1;
|
||||
}
|
||||
|
@ -76,6 +84,7 @@ evas_gl_common_context_use(Evas_GL_Context *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);
|
||||
|
@ -132,6 +141,11 @@ 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)
|
||||
{
|
||||
if (gc->font_texture > 0)
|
||||
{
|
||||
gc->font_texture = 0;
|
||||
gc->change.texture = 1;
|
||||
}
|
||||
if (gc->texture != tex)
|
||||
{
|
||||
if (gc->texture) gc->texture->references--;
|
||||
|
@ -153,6 +167,24 @@ evas_gl_common_context_texture_set(Evas_GL_Context *gc, Evas_GL_Texture *tex, in
|
|||
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_not_power_of_two = ft->pool->not_power_of_two;
|
||||
gc->change.texture = 1;
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
@ -245,7 +277,23 @@ static void
|
|||
_evas_gl_common_texture_set(Evas_GL_Context *gc)
|
||||
{
|
||||
if (!gc->change.texture) return;
|
||||
if (gc->texture)
|
||||
if (gc->font_texture > 0)
|
||||
{
|
||||
if (gc->font_texture_not_power_of_two)
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_TEXTURE_RECTANGLE_NV);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_NV, gc->font_texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
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->not_power_of_two)
|
||||
{
|
||||
|
@ -255,7 +303,7 @@ _evas_gl_common_texture_set(Evas_GL_Context *gc)
|
|||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_TEXTURE_RECTANGLE_NV);
|
||||
if (gc->ext.nv_texture_rectangle) glDisable(GL_TEXTURE_RECTANGLE_NV);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, gc->texture->texture);
|
||||
}
|
||||
|
@ -287,8 +335,11 @@ _evas_gl_common_texture_set(Evas_GL_Context *gc)
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1,370 @@
|
|||
#include "evas_gl_private.h"
|
||||
|
||||
static Evas_GL_Font_Texture_Pool_Allocation *_evas_gl_font_texture_pool_request(Evas_GL_Context *gc, int w, int h);
|
||||
static void _evas_gl_font_texture_pool_relinquish(Evas_GL_Font_Texture_Pool_Allocation *fa);
|
||||
static int _evas_gl_font_texture_pool_rect_find(Evas_GL_Font_Texture_Pool *fp, int w, int h, int *x, int *y);
|
||||
|
||||
static Evas_GL_Font_Texture_Pool_Allocation *
|
||||
_evas_gl_font_texture_pool_request(Evas_GL_Context *gc, int w, int h)
|
||||
{
|
||||
Evas_List *l;
|
||||
Evas_GL_Font_Texture_Pool_Allocation *fa;
|
||||
Evas_GL_Font_Texture_Pool *fp;
|
||||
int minw = 256;
|
||||
int minh = 256;
|
||||
int shift;
|
||||
|
||||
for (l = gc->tex_pool; l; l = l->next)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
fp = l->data;
|
||||
if (_evas_gl_font_texture_pool_rect_find(fp, w, h, &x, &y))
|
||||
{
|
||||
fa = calloc(1, sizeof(Evas_GL_Font_Texture_Pool_Allocation));
|
||||
if (!fa) return NULL;
|
||||
fa->pool = fp;
|
||||
fa->x = x;
|
||||
fa->y = y;
|
||||
fa->w = w;
|
||||
fa->h = h;
|
||||
fp->allocations = evas_list_prepend(fp->allocations, fa);
|
||||
fp->references++;
|
||||
return fa;
|
||||
}
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
fp = calloc(1, sizeof(Evas_GL_Font_Texture_Pool));
|
||||
if (!fp) return NULL;
|
||||
fp->gc = gc;
|
||||
fp->w = minw;
|
||||
fp->h = minh;
|
||||
if (gc->ext.nv_texture_rectangle) fp->not_power_of_two = 1;
|
||||
gc->tex_pool = evas_list_append(gc->tex_pool, fp);
|
||||
|
||||
if (gc->ext.sgis_generate_mipmap)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
if (fp->not_power_of_two)
|
||||
{
|
||||
glEnable(GL_TEXTURE_RECTANGLE_NV);
|
||||
glGenTextures(1, &(fp->texture));
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_NV, fp->texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
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_ALPHA8, fp->w, fp->h, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
glGenTextures(1, &(fp->texture));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, fp->texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
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_ALPHA8, fp->w, fp->h, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
|
||||
/* new allocation entirely */
|
||||
fa = calloc(1, sizeof(Evas_GL_Font_Texture_Pool_Allocation));
|
||||
if (!fa) return NULL;
|
||||
fa->pool = fp;
|
||||
fa->x = 0;
|
||||
fa->y = 0;
|
||||
fa->w = w;
|
||||
fa->h = h;
|
||||
fp->allocations = evas_list_prepend(fp->allocations, fa);
|
||||
fp->references++;
|
||||
return fa;
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_gl_font_texture_pool_relinquish(Evas_GL_Font_Texture_Pool_Allocation *fa)
|
||||
{
|
||||
fa->pool->allocations = evas_list_remove(fa->pool->allocations, fa);
|
||||
fa->pool->references--;
|
||||
if (fa->pool->references <= 0)
|
||||
{
|
||||
fa->pool->gc->tex_pool =
|
||||
evas_list_remove(fa->pool->gc->tex_pool, fa->pool);
|
||||
glDeleteTextures(1, &(fa->pool->texture));
|
||||
free(fa->pool);
|
||||
}
|
||||
free(fa);
|
||||
}
|
||||
|
||||
static int
|
||||
_evas_gl_font_texture_pool_rect_find(Evas_GL_Font_Texture_Pool *fp,
|
||||
int w, int h,
|
||||
int *x, int *y)
|
||||
{
|
||||
Evas_List *l;
|
||||
|
||||
if ((w > fp->w) || (h > fp->h)) return 0;
|
||||
for (l = fp->allocations; l; l = l->next)
|
||||
{
|
||||
Evas_GL_Font_Texture_Pool_Allocation *fa;
|
||||
Evas_List *l2;
|
||||
int tx, ty, tw, th;
|
||||
int t1, t2;
|
||||
int intersects;
|
||||
|
||||
fa = l->data;
|
||||
t1 = t2 = 1;
|
||||
if ((fa->x + fa->w + w) > fp->w) t1 = 0;
|
||||
if ((fa->y + h) > fp->h) t1 = 0;
|
||||
if ((fa->y + fa->h + h) > fp->h) t2 = 0;
|
||||
if ((fa->x + w) > fp->w) t2 = 0;
|
||||
intersects = 0;
|
||||
if (t1)
|
||||
{
|
||||
/* 1. try here:
|
||||
* +----++--+
|
||||
* |AAAA||??|
|
||||
* |AAAA|+--+
|
||||
* |AAAA|
|
||||
* +----+
|
||||
*/
|
||||
tx = fa->x + fa->w;
|
||||
ty = fa->y;
|
||||
tw = w;
|
||||
th = h;
|
||||
for (l2 = fp->allocations; l2; l2 = l2->next)
|
||||
{
|
||||
Evas_GL_Font_Texture_Pool_Allocation *fa2;
|
||||
int rx, ry, rw, rh;
|
||||
|
||||
/* dont do the rect we are just using as our offset */
|
||||
if (l2 == l) continue;
|
||||
fa2 = l2->data;
|
||||
rx = fa2->x;
|
||||
ry = fa2->y;
|
||||
rw = fa2->w;
|
||||
rh = fa2->h;
|
||||
if (RECTS_INTERSECT(tx, ty, tw, th, rx, ry, rw, rh))
|
||||
{
|
||||
intersects = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!intersects)
|
||||
{
|
||||
*x = tx;
|
||||
*y = ty;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
intersects = 0;
|
||||
if (t2)
|
||||
{
|
||||
/* 2. try here:
|
||||
* +----+
|
||||
* |AAAA|
|
||||
* |AAAA|
|
||||
* |AAAA|
|
||||
* +----+
|
||||
* +--+
|
||||
* |??|
|
||||
* +--+
|
||||
*/
|
||||
tx = fa->x;
|
||||
ty = fa->y + fa->h;
|
||||
tw = w;
|
||||
th = h;
|
||||
for (l2 = fp->allocations; l2; l2 = l2->next)
|
||||
{
|
||||
Evas_GL_Font_Texture_Pool_Allocation *fa2;
|
||||
int rx, ry, rw, rh;
|
||||
|
||||
/* dont do the rect we are just using as our offset */
|
||||
if (l2 == l) continue;
|
||||
fa2 = l2->data;
|
||||
|
||||
rx = fa2->x;
|
||||
ry = fa2->y;
|
||||
rw = fa2->w;
|
||||
rh = fa2->h;
|
||||
if (RECTS_INTERSECT(tx, ty, tw, th, rx, ry, rw, rh))
|
||||
{
|
||||
intersects = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!intersects)
|
||||
{
|
||||
*x = tx;
|
||||
*y = ty;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Evas_GL_Font_Texture *
|
||||
evas_gl_font_texture_new(Evas_GL_Context *gc, RGBA_Font_Glyph *fg)
|
||||
{
|
||||
Evas_GL_Font_Texture *ft;
|
||||
DATA8 *data;
|
||||
int w, h, j;
|
||||
|
||||
int nw;
|
||||
DATA8 *ndata;
|
||||
|
||||
ft = calloc(1, sizeof(Evas_GL_Font_Texture));
|
||||
if (!ft) return NULL;
|
||||
|
||||
data = fg->glyph_out->bitmap.buffer;
|
||||
w = fg->glyph_out->bitmap.width;
|
||||
h = fg->glyph_out->bitmap.rows;
|
||||
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;
|
||||
}
|
||||
{
|
||||
int x, y;
|
||||
DATA8 *p1, *p2;
|
||||
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
p1 = data + (j * y);
|
||||
p2 = ndata + (nw * y);
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
*p2 = *p1;
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
ft->x = ft->alloc->x;
|
||||
ft->y = ft->alloc->y;
|
||||
ft->pool = ft->alloc->pool;
|
||||
ft->texture = ft->pool->texture;
|
||||
if (ft->pool->not_power_of_two)
|
||||
{
|
||||
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_not_power_of_two = ft->pool->not_power_of_two;
|
||||
gc->change.texture = 1;
|
||||
|
||||
return ft;
|
||||
}
|
||||
|
||||
void
|
||||
evas_gl_font_texture_free(Evas_GL_Font_Texture *ft)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
evas_gl_font_texture_draw(Evas_GL_Context *gc, void *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y)
|
||||
{
|
||||
int r, g, b, a;
|
||||
Evas_GL_Font_Texture *ft;
|
||||
|
||||
ft = fg->ext_dat;
|
||||
if (!ft) return;
|
||||
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 (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_font_texture_set(gc, ft);
|
||||
evas_gl_common_context_blend_set(gc, 1);
|
||||
evas_gl_common_context_read_buf_set(gc, GL_BACK);
|
||||
evas_gl_common_context_write_buf_set(gc, GL_BACK);
|
||||
{
|
||||
double tx1, ty1, tx2, ty2;
|
||||
|
||||
if (ft->pool->not_power_of_two)
|
||||
{
|
||||
tx1 = ft->x;
|
||||
ty1 = ft->y;
|
||||
tx2 = ft->x + ft->w;
|
||||
ty2 = ft->y + ft->h;
|
||||
}
|
||||
else
|
||||
{
|
||||
tx1 = (double)(ft->x ) / (double)(ft->pool->w);
|
||||
ty1 = (double)(ft->y ) / (double)(ft->pool->h);
|
||||
tx2 = (double)(ft->x + ft->w) / (double)(ft->pool->w);
|
||||
ty2 = (double)(ft->y + ft->h) / (double)(ft->pool->h);
|
||||
}
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(tx1, ty1); glVertex2i(x , y );
|
||||
glTexCoord2d(tx2, ty1); glVertex2i(x + ft->w, y );
|
||||
glTexCoord2d(tx2, ty2); glVertex2i(x + ft->w, y + ft->h);
|
||||
glTexCoord2d(tx1, ty2); glVertex2i(x , y + ft->h);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "evas_gl_common.h"
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
/* nvidia extensions */
|
||||
extern void glPixelDataRangeNV(GLenum target, GLsizei length, void *pointer);
|
||||
#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878
|
||||
|
|
|
@ -13,10 +13,8 @@ evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im, int smooth)
|
|||
tex = calloc(1, sizeof(Evas_GL_Texture));
|
||||
if (!tex) return NULL;
|
||||
|
||||
if ((gc->ext.nv_texture_rectangle) && (1))
|
||||
if (gc->ext.nv_texture_rectangle)
|
||||
{
|
||||
printf("new rect tex %ix%i\n", im->image->w, im->image->h);
|
||||
|
||||
tex->gc = gc;
|
||||
tex->w = im->image->w;
|
||||
tex->h = im->image->h;
|
||||
|
@ -52,12 +50,12 @@ evas_gl_common_texture_new(Evas_GL_Context *gc, RGBA_Image *im, int smooth)
|
|||
tex->gc = gc;
|
||||
tex->w = tw;
|
||||
tex->h = th;
|
||||
printf("new tex %ix%i\n", tw, th);
|
||||
tex->tw = im->image->w;
|
||||
tex->th = im->image->h;
|
||||
tex->references = 0;
|
||||
tex->smooth = 0;
|
||||
tex->changed = 1;
|
||||
if (gc->ext.nv_texture_rectangle) glDisable(GL_TEXTURE_RECTANGLE_NV);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glGenTextures(1, &(tex->texture));
|
||||
glBindTexture(GL_TEXTURE_2D, tex->texture);
|
||||
|
@ -151,7 +149,9 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im, int smooth)
|
|||
glPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV,
|
||||
im->image->w * im->image->h * 4,
|
||||
im->image->data);
|
||||
printf("ER1: %s\n", gluErrorString(glGetError()));
|
||||
glEnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV);
|
||||
printf("ER2: %s\n", gluErrorString(glGetError()));
|
||||
tex->opt = 1;
|
||||
}
|
||||
*/
|
||||
|
@ -186,6 +186,7 @@ evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im, int smooth)
|
|||
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->not_power_of_two)
|
||||
{
|
||||
|
@ -310,6 +311,7 @@ evas_gl_common_texture_mipmaps_build(Evas_GL_Texture *tex, RGBA_Image *im, int s
|
|||
pixfmt = NATIVE_PIX_FORMAT;
|
||||
|
||||
printf("building mipmaps... [%i x %i]\n", tw, th);
|
||||
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);
|
||||
|
|
|
@ -957,76 +957,28 @@ evas_engine_gl_x11_font_draw(void *data, void *context, void *surface, void *fon
|
|||
Render_Engine *re;
|
||||
|
||||
re = (Render_Engine *)data;
|
||||
//#define GL_TXT 1
|
||||
|
||||
#ifdef GL_TXT
|
||||
{
|
||||
/* create output surface size ow x oh and scale to w x h */
|
||||
RGBA_Draw_Context *dc;
|
||||
RGBA_Image *im;
|
||||
|
||||
dc = context;
|
||||
im = evas_common_image_create(ow, oh);
|
||||
if (im)
|
||||
{
|
||||
int max_ascent;
|
||||
int i, j;
|
||||
RGBA_Draw_Context *dct;
|
||||
|
||||
im->flags |= RGBA_IMAGE_HAS_ALPHA;
|
||||
j = ow * oh;
|
||||
memset(im->image->data, 0, j * sizeof(DATA32));
|
||||
max_ascent = evas_common_font_max_ascent_get(font);
|
||||
dct = evas_common_draw_context_new();
|
||||
if (dct)
|
||||
{
|
||||
evas_common_draw_context_set_color(dct, 255, 255, 255, 255);
|
||||
evas_common_font_draw(im, dct, font, 0, max_ascent, text);
|
||||
evas_common_cpu_end_opt();
|
||||
evas_common_draw_context_free(dct);
|
||||
}
|
||||
{
|
||||
Evas_GL_Texture *tex;
|
||||
Evas_GL_Context *gc;
|
||||
double tx1, ty1, tx2, ty2;
|
||||
int r, g, b, a;
|
||||
|
||||
gc = re->win->gl_context;
|
||||
tex = evas_gl_common_texture_new(gc, im, 0);
|
||||
evas_gl_common_context_texture_set(gc, tex, 0, w, h);
|
||||
tx1 = 0;
|
||||
ty1 = 0;
|
||||
tx2 = (double)(ow) / (double)(tex->w);
|
||||
ty2 = (double)(oh) / (double)(tex->h);
|
||||
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);
|
||||
evas_gl_common_context_blend_set(gc, 1);
|
||||
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_read_buf_set(gc, GL_BACK);
|
||||
evas_gl_common_context_write_buf_set(gc, GL_BACK);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(tx1, ty1); glVertex2i(x , y - ((max_ascent * h) / oh));
|
||||
glTexCoord2d(tx2, ty1); glVertex2i(x + w, y - ((max_ascent * h) / oh));
|
||||
glTexCoord2d(tx2, ty2); glVertex2i(x + w, y - ((max_ascent * h) / oh) + h);
|
||||
glTexCoord2d(tx1, ty2); glVertex2i(x , y - ((max_ascent * h) / oh) + h);
|
||||
glEnd();
|
||||
|
||||
evas_gl_common_texture_free(tex);
|
||||
}
|
||||
evas_common_image_free(im);
|
||||
}
|
||||
im = evas_common_image_new();
|
||||
im->image = evas_common_image_surface_new();
|
||||
im->image->w = re->win->w;
|
||||
im->image->h = re->win->h;
|
||||
im->image->data = NULL;
|
||||
im->image->no_free = 1;
|
||||
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,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
evas_common_image_free(im);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -67,7 +67,7 @@ evas_engine_gl_x11_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);
|
||||
// glXDestroyContext(gw->disp, gw->context);
|
||||
free(gw);
|
||||
}
|
||||
|
||||
|
|
|
@ -239,30 +239,38 @@ struct _Evas_Hash_El
|
|||
struct _RGBA_Draw_Context
|
||||
{
|
||||
struct {
|
||||
int use : 1;
|
||||
char use : 1;
|
||||
DATA8 r[256], g[256], b[256], a[256];
|
||||
} mod;
|
||||
struct {
|
||||
int use : 1;
|
||||
char use : 1;
|
||||
DATA32 col;
|
||||
} mul;
|
||||
struct {
|
||||
DATA32 col;
|
||||
} col;
|
||||
struct {
|
||||
int use : 1;
|
||||
char use : 1;
|
||||
int x, y, w, h;
|
||||
} clip;
|
||||
struct {
|
||||
Cutout_Rect *rects;
|
||||
} cutout;
|
||||
struct {
|
||||
struct {
|
||||
void *(*gl_new) (void *data, RGBA_Font_Glyph *fg);
|
||||
void (*gl_free) (void *ext_dat);
|
||||
void (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, int y);
|
||||
} func;
|
||||
void *data;
|
||||
} font_ext;
|
||||
};
|
||||
|
||||
struct _RGBA_Surface
|
||||
{
|
||||
int w, h;
|
||||
DATA32 *data;
|
||||
int no_free : 1;
|
||||
char no_free : 1;
|
||||
};
|
||||
|
||||
struct _RGBA_Image
|
||||
|
@ -326,8 +334,10 @@ struct _RGBA_Font
|
|||
|
||||
struct _RGBA_Font_Glyph
|
||||
{
|
||||
FT_Glyph glyph;
|
||||
FT_BitmapGlyph glyph_out;
|
||||
FT_Glyph glyph;
|
||||
FT_BitmapGlyph glyph_out;
|
||||
void *ext_dat;
|
||||
void (*ext_dat_free) (void *ext_dat);
|
||||
};
|
||||
|
||||
struct _Tilebuf
|
||||
|
@ -817,6 +827,11 @@ void evas_common_draw_init (void);
|
|||
|
||||
RGBA_Draw_Context *evas_common_draw_context_new (void);
|
||||
void evas_common_draw_context_free (RGBA_Draw_Context *dc);
|
||||
void evas_common_draw_context_font_ext_set (RGBA_Draw_Context *dc,
|
||||
void *data,
|
||||
void *(*gl_new) (void *data, RGBA_Font_Glyph *fg),
|
||||
void (*gl_free) (void *ext_dat),
|
||||
void (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, int y));
|
||||
void evas_common_draw_context_clip_clip (RGBA_Draw_Context *dc, int x, int y, int w, int h);
|
||||
void evas_common_draw_context_set_clip (RGBA_Draw_Context *dc, int x, int y, int w, int h);
|
||||
void evas_common_draw_context_unset_clip (RGBA_Draw_Context *dc);
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#ifndef EVAS_GL_COMMON_H
|
||||
#define EVAS_GL_COMMON_H
|
||||
|
||||
//#define RADEON_HACK
|
||||
#define NVIDIA_HACK
|
||||
|
||||
#include "evas_common.h"
|
||||
#include "config.h"
|
||||
|
||||
|
@ -23,13 +20,16 @@
|
|||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
typedef struct _Evas_GL_Context Evas_GL_Context;
|
||||
typedef struct _Evas_GL_Texture Evas_GL_Texture;
|
||||
typedef struct _Evas_GL_Image Evas_GL_Image;
|
||||
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_Context Evas_GL_Context;
|
||||
typedef struct _Evas_GL_Texture Evas_GL_Texture;
|
||||
typedef struct _Evas_GL_Image Evas_GL_Image;
|
||||
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_Context
|
||||
{
|
||||
int w, h;
|
||||
|
@ -63,7 +63,9 @@ struct _Evas_GL_Context
|
|||
GLenum read_buf;
|
||||
GLenum write_buf;
|
||||
|
||||
Evas_GL_Texture *texture;
|
||||
Evas_GL_Texture *texture;
|
||||
GLuint font_texture;
|
||||
char font_texture_not_power_of_two : 1;
|
||||
|
||||
int max_texture_depth;
|
||||
int max_texture_size;
|
||||
|
@ -71,6 +73,7 @@ struct _Evas_GL_Context
|
|||
int references;
|
||||
|
||||
Evas_List *images;
|
||||
Evas_List *tex_pool;
|
||||
};
|
||||
|
||||
struct _Evas_GL_Texture
|
||||
|
@ -79,12 +82,15 @@ struct _Evas_GL_Texture
|
|||
int w, h;
|
||||
int tw, th;
|
||||
int uw, uh;
|
||||
|
||||
GLuint texture;
|
||||
|
||||
char smooth : 1;
|
||||
char changed : 1;
|
||||
char have_mipmaps : 1;
|
||||
char opt : 1;
|
||||
char not_power_of_two : 1;
|
||||
char opt : 1;
|
||||
|
||||
int references;
|
||||
};
|
||||
|
||||
|
@ -114,6 +120,32 @@ struct _Evas_GL_Gradient
|
|||
Evas_GL_Texture *tex;
|
||||
};
|
||||
|
||||
struct _Evas_GL_Font_Texture
|
||||
{
|
||||
Evas_GL_Context *gc;
|
||||
int x, y, w, h;
|
||||
int aw, ah;
|
||||
GLuint texture;
|
||||
Evas_GL_Font_Texture_Pool *pool;
|
||||
Evas_GL_Font_Texture_Pool_Allocation *alloc;
|
||||
};
|
||||
|
||||
struct _Evas_GL_Font_Texture_Pool
|
||||
{
|
||||
Evas_GL_Context *gc;
|
||||
int w, h;
|
||||
GLuint texture;
|
||||
int references;
|
||||
char not_power_of_two : 1;
|
||||
Evas_List *allocations;
|
||||
};
|
||||
|
||||
struct _Evas_GL_Font_Texture_Pool_Allocation
|
||||
{
|
||||
Evas_GL_Font_Texture_Pool *pool;
|
||||
int x, y, w, h;
|
||||
};
|
||||
|
||||
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);
|
||||
|
@ -122,9 +154,11 @@ void evas_gl_common_context_color_set(Evas_GL_Context *gc, int r, i
|
|||
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_texture_free(Evas_GL_Texture *tex);
|
||||
|
@ -136,8 +170,10 @@ 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);
|
||||
void evas_gl_common_image_free(Evas_GL_Image *im);
|
||||
void evas_gl_common_image_dirty(Evas_GL_Image *im);
|
||||
|
||||
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);
|
||||
|
||||
Evas_GL_Gradient *evas_gl_common_gradient_color_add(Evas_GL_Gradient *gr, int r, int g, int b, int a, int distance);
|
||||
Evas_GL_Gradient *evas_gl_common_gradient_colors_clear(Evas_GL_Gradient *gr);
|
||||
|
||||
|
@ -149,7 +185,9 @@ void evas_gl_common_line_draw(Evas_GL_Context *gc, RGBA_Draw_Contex
|
|||
void evas_gl_common_poly_draw(Evas_GL_Context *gc, RGBA_Draw_Context *dc, Evas_GL_Polygon *poly);
|
||||
void evas_gl_common_gradient_draw(Evas_GL_Context *gc, RGBA_Draw_Context *dc, Evas_GL_Gradient *gr, int x, int y, int w, int h, double angle);
|
||||
|
||||
|
||||
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:
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue