more backedn... yum!

SVN revision: 3026
This commit is contained in:
Carsten Haitzler 2000-08-05 20:11:27 +00:00
parent eccb8b7520
commit bd2656fd11
3 changed files with 242 additions and 48 deletions

View File

@ -10,6 +10,14 @@ static int __evas_gl_configuration[] =
None
};
static XVisualInfo *__evas_vi = NULL;
static GLXContext __evas_gl_cx = 0;
static Window __evas_context_window = 0;
static Evas_List __evas_images = NULL;
static int __evas_image_cache_max = 16 *1024 * 1024;
static int __evas_image_cache_used = 0;
void
__evas_gl_copy_image_rect_to_texture(Evas_GL_Image *im, int x, int y,
int w, int h, int tw, int th,
@ -50,9 +58,22 @@ __evas_gl_move_state_data_to_texture(Evas_GL_Image *im)
{
int i, x, y;
XSetWindowAttributes att;
int image_data = 0;
Imlib_Image image;
if ((!im->data) && (im->file))
{
image = imlib_load_image(im->file);
if (image)
{
imlib_context_set_image(image);
im->data = imlib_image_get_data_for_reading_only();
imlib_free_image();
image_data = 1;
}
}
if (!im->data) return;
im->texture.w = im->w / (im->texture.max_size - 2);
if (im->w > ((im->texture.max_size - 2) * im->texture.w))
{
@ -78,19 +99,29 @@ __evas_gl_move_state_data_to_texture(Evas_GL_Image *im)
else
im->texture.edge_h = im->texture.max_size;
att.colormap = im->buffer.colormap;
att.border_pixel = 0;
att.event_mask = 0;
im->buffer.window = XCreateWindow(im->buffer.display,
RootWindow(im->buffer.display, DefaultScreen(im->buffer.display)),
0, 0, 32, 32, 0,
im->buffer.visual_info->depth,
InputOutput,
im->buffer.visual_info->visual,
CWColormap | CWBorderPixel | CWEventMask,
&att);
im->texture.textures = malloc(sizeof(GLuint) * im->texture.w * im->texture.h);
glXMakeCurrent(im->buffer.display, im->buffer.window, im->context);
if (!__evas_context_window)
{
att.colormap = im->buffer.colormap;
att.border_pixel = 0;
att.event_mask = 0;
__evas_context_window = XCreateWindow(im->buffer.display,
RootWindow(im->buffer.display, DefaultScreen(im->buffer.display)),
0, 0, 32, 32, 0,
im->buffer.visual_info->depth,
InputOutput,
im->buffer.visual_info->visual,
CWColormap | CWBorderPixel | CWEventMask,
&att);
im->buffer.window = __evas_context_window;
im->texture.textures = malloc(sizeof(GLuint) * im->texture.w * im->texture.h);
glXMakeCurrent(im->buffer.display, im->buffer.window, im->context);
}
else
{
im->buffer.window = __evas_context_window;
im->texture.textures = malloc(sizeof(GLuint) * im->texture.w * im->texture.h);
glXMakeCurrent(im->buffer.display, im->buffer.window, im->context);
}
glGenTextures(im->texture.w * im->texture.h, im->texture.textures);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glEnable(GL_TEXTURE_2D);
@ -124,10 +155,18 @@ __evas_gl_move_state_data_to_texture(Evas_GL_Image *im)
__evas_gl_copy_image_rect_to_texture(im, xx, yy, ww, hh, tw, th,
im->texture.textures[i]);
__evas_image_cache_used += (tw * th * 4);
}
}
/* done - set the actual image state to textured */
im->state = EVAS_STATE_TEXTURE;
if (image_data)
{
imlib_context_set_image(image);
imlib_image_put_back_data(im->data);
im->data = NULL;
imlib_free_image();
}
}
void __evas_calc_tex_and_poly(Evas_GL_Image *im, int x, double *x1, double *x2,
@ -139,7 +178,6 @@ void __evas_calc_tex_and_poly(Evas_GL_Image *im, int x, double *x1, double *x2,
*txx = im->texture.max_size - 2;
*dtx = (double)*tx / (im->texture.max_size);
*dtxx = (double)*txx / (im->texture.max_size);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
}
else if (x < (tw - 1))
{
@ -179,20 +217,30 @@ void __evas_gl_set_conect_for_dest(Evas_GL_Image *im, Display *disp, Window w,
{
if (im->buffer.dest != w)
{
im->buffer.dest = w;
glXMakeCurrent(disp, w, im->context);
im->buffer.dest = w;
}
if (im->alpha)
{
glEnable(GL_BLEND);
glEnable(GL_DITHER);
glShadeModel(GL_FLAT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
/* why doesnt scissor work ? */
/*
glEnable(GL_SCISSOR_TEST);
glScissor(dst_x, win_h - dst_y - 1, dst_w, dst_h);
*/
}
else
{
glDisable(GL_BLEND);
}
glEnable(GL_DITHER);
glShadeModel(GL_FLAT);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
/* why doesnt scissor work ? */
/*
glEnable(GL_SCISSOR_TEST);
glScissor(dst_x, win_h - dst_y - 1, dst_w, dst_h);
*/
if ((win_w != im->buffer.dest_w) || (win_h != im->buffer.dest_h))
{
glViewport(0, 0, win_w, win_h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@ -201,6 +249,8 @@ void __evas_gl_set_conect_for_dest(Evas_GL_Image *im, Display *disp, Window w,
glLoadIdentity();
glScalef(1, -1, 1);
glTranslatef(0, -win_h, 0);
im->buffer.dest_w = win_w;
im->buffer.dest_h = win_h;
}
}
@ -265,9 +315,6 @@ __evas_gl_create_image(void)
return im;
}
static XVisualInfo *__evas_vi = NULL;
static GLXContext __evas_gl_cx = 0;
int
__evas_gl_capable(Display *disp)
{
@ -320,46 +367,182 @@ __evas_gl_init(Display *disp)
/* direct rendering client */
__evas_gl_cx = glXCreateContext(disp, __evas_vi, NULL, GL_TRUE);
/* GLX indirect */
/* __evas_gl_cx = glXCreateContext(disp, __evas_vi, NULL, GL_TRUE);*/
/* __evas_gl_cx = glXCreateContext(disp, __evas_vi, NULL, GL_FALSE);*/
}
Evas_GL_Image *
__evas_gl_image_new_from_file(Display *disp, char *file)
__evas_gl_image_create_from_file(Display *disp, char *file)
{
Evas_GL_Image *im;
Imlib_Image i;
i = imlib_load_image(file);
if (!i) return NULL;
imlib_context_set_image(i);
if (!file) return NULL;
im = __evas_gl_create_image();
im->w = imlib_image_get_width();
im->h = imlib_image_get_height();
im->data = imlib_image_get_data();
im->file = strdup(file);
i = imlib_load_image(file);
if (i)
{
imlib_context_set_image(i);
im->w = imlib_image_get_width();
im->h = imlib_image_get_height();
im->alpha = imlib_image_has_alpha();
imlib_free_image();
}
else
{
im->w = 0;
im->h = 0;
}
im->data = NULL;
im->texture.max_size = 256;
__evas_gl_init(disp);
im->texture.w = 0;
im->texture.h = 0;
im->texture.edge_w = 0;
im->texture.edge_h = 0;
im->texture.textures = NULL;
__evas_gl_init(disp);
im->context = __evas_gl_cx;
im->buffer.display = disp;
im->buffer.colormap = __evas_gl_get_colormap(disp);
im->buffer.visual_info = __evas_vi;
im->buffer.window = 0;
im->buffer.dest = 0;
im->buffer.dest_w = 0;
im->buffer.dest_h = 0;
im->references = 1;
return im;
}
Evas_GL_Image *
__evas_gl_image_new_from_file(Display *disp, char *file)
{
Evas_GL_Image *im;
Evas_List l;
for (l = __evas_images; l; l = l->next)
{
im = l->data;
if (((im->file) && (im->buffer.display == disp)) &&
(!strcmp(im->file, file)))
{
if (l != __evas_images)
{
__evas_images = evas_list_remove(__evas_images, im);
__evas_images = evas_list_prepend(__evas_images, im);
}
im->references++;
return im;
}
}
im = __evas_gl_image_create_from_file(disp, file);
__evas_images = evas_list_prepend(__evas_images, im);
return im;
}
void
__evas_sync(Display *disp)
__evas_gl_image_free(Evas_GL_Image *im)
{
im->references--;
if (im->references <= 0)
__evas_gl_image_cache_flush(im->buffer.display);
}
void
__evas_gl_image_destroy(Evas_GL_Image *im)
{
if (im->file) free(im->file);
if (im->data) free(im->data);
if (im->texture.textures)
{
glDeleteTextures(im->texture.w * im->texture.h, im->texture.textures);
free(im->texture.textures);
}
free(im);
}
void
__evas_gl_image_cache_flush(Display *disp)
{
while (__evas_image_cache_used > __evas_image_cache_max)
{
Evas_GL_Image *im = NULL, *im_last;
Evas_List l;
im_last = NULL;
for (l = __evas_images; l; l = l->next)
{
im = l->data;
if (im->references <= 0)
im_last = im;
}
if (im_last)
{
__evas_images = evas_list_remove(__evas_images, im_last);
__evas_gl_image_destroy(im_last);
}
}
}
void
__evas_gl_image_cache_empty(Display *disp)
{
Evas_GL_Image *im = NULL, *im_last;
Evas_List l;
im_last = (Evas_GL_Image *)1;
while (im_last)
{
im_last = NULL;
for (l = __evas_images; l; l = l->next)
{
im = l->data;
if (im->references <= 0)
im_last = im;
}
if (im_last)
{
__evas_images = evas_list_remove(__evas_images, im_last);
__evas_gl_image_destroy(im_last);
}
}
}
void
__evas_gl_image_cache_set_size(Display *disp, int size)
{
__evas_image_cache_max = size;
__evas_gl_image_cache_flush(disp);
}
int
__evas_gl_image_cache_get_size(Display *disp)
{
return __evas_image_cache_max;
}
void
__evas_gl_sync(Display *disp)
{
glXWaitGL();
XSync(disp, False);
}
void
__evas_flush_draw(Display *disp, Window win)
__evas_gl_flush_draw(Display *disp, Window win)
{
glXSwapBuffers(disp, win);
}
void
__evas_draw_rectangle(Display *disp, Window win, int x, int y, int w, int h,
int r, int g, int b, int a)
__evas_gl_draw_rectangle(Display *disp, Window win, int x, int y, int w, int h,
int r, int g, int b, int a)
{
}

View File

@ -29,12 +29,14 @@ struct _evas_gl_image
{
Evas_GL_Image_State state;
int w, h;
int alpha;
char *file;
/* data specific params */
DATA32 *data;
/* common GL params */
GLXContext context;
/* texture state specific params */
struct _tex
struct
{
int max_size;
int w, h;
@ -42,13 +44,15 @@ struct _evas_gl_image
GLuint *textures;
} texture;
/* buffer specific params */
struct _buf
struct
{
Display *display;
XVisualInfo *visual_info;
Colormap colormap;
Window window, dest;
int dest_w, dest_h;
} buffer;
int references;
};
void __evas_gl_copy_image_rect_to_texture(Evas_GL_Image *im, int x, int y,
@ -69,8 +73,15 @@ Visual * __evas_gl_get_visual(Display *disp);
XVisualInfo *__evas_gl_get_visual_info(Display *disp);
Colormap __evas_gl_get_colormap(Display *disp);
void __evas_gl_init(Display *disp);
Evas_GL_Image *__evas_gl_image_create_from_file(Display *disp, char *file);
Evas_GL_Image * __evas_gl_image_new_from_file(Display *disp, char *file);
void __evas_sync(Display *disp);
void __evas_flush_draw(Display *disp, Window win);
void __evas_draw_rectangle(Display *disp, Window win, int x, int y, int w, int h,
void __evas_gl_image_free(Evas_GL_Image *im);
void __evas_gl_image_destroy(Evas_GL_Image *im);
void __evas_gl_image_cache_flush(Display *disp);
void __evas_gl_image_cache_empty(Display *disp);
void __evas_gl_image_cache_set_size(Display *disp, int size);
int __evas_gl_image_cache_get_size(Display *disp);
void __evas_gl_sync(Display *disp);
void __evas_gl_flush_draw(Display *disp, Window win);
void __evas_gl_draw_rectangle(Display *disp, Window win, int x, int y, int w, int h,
int r, int g, int b, int a);

View File

@ -87,7 +87,7 @@ main(int argc, char **argv)
0, 0, i[j]->w, i[j]->h,
xx - win_w, yy, win_w, win_h);
}
__evas_flush_draw(d, win);
__evas_gl_flush_draw(d, win);
a++;
if (a == (win_w * 4))
{