forked from enlightenment/efl
parent
eccb8b7520
commit
bd2656fd11
|
@ -10,6 +10,14 @@ static int __evas_gl_configuration[] =
|
||||||
None
|
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
|
void
|
||||||
__evas_gl_copy_image_rect_to_texture(Evas_GL_Image *im, int x, int y,
|
__evas_gl_copy_image_rect_to_texture(Evas_GL_Image *im, int x, int y,
|
||||||
int w, int h, int tw, int th,
|
int w, int h, int tw, int th,
|
||||||
|
@ -50,7 +58,20 @@ __evas_gl_move_state_data_to_texture(Evas_GL_Image *im)
|
||||||
{
|
{
|
||||||
int i, x, y;
|
int i, x, y;
|
||||||
XSetWindowAttributes att;
|
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;
|
if (!im->data) return;
|
||||||
|
|
||||||
im->texture.w = im->w / (im->texture.max_size - 2);
|
im->texture.w = im->w / (im->texture.max_size - 2);
|
||||||
|
@ -78,19 +99,29 @@ __evas_gl_move_state_data_to_texture(Evas_GL_Image *im)
|
||||||
else
|
else
|
||||||
im->texture.edge_h = im->texture.max_size;
|
im->texture.edge_h = im->texture.max_size;
|
||||||
|
|
||||||
att.colormap = im->buffer.colormap;
|
if (!__evas_context_window)
|
||||||
att.border_pixel = 0;
|
{
|
||||||
att.event_mask = 0;
|
att.colormap = im->buffer.colormap;
|
||||||
im->buffer.window = XCreateWindow(im->buffer.display,
|
att.border_pixel = 0;
|
||||||
RootWindow(im->buffer.display, DefaultScreen(im->buffer.display)),
|
att.event_mask = 0;
|
||||||
0, 0, 32, 32, 0,
|
__evas_context_window = XCreateWindow(im->buffer.display,
|
||||||
im->buffer.visual_info->depth,
|
RootWindow(im->buffer.display, DefaultScreen(im->buffer.display)),
|
||||||
InputOutput,
|
0, 0, 32, 32, 0,
|
||||||
im->buffer.visual_info->visual,
|
im->buffer.visual_info->depth,
|
||||||
CWColormap | CWBorderPixel | CWEventMask,
|
InputOutput,
|
||||||
&att);
|
im->buffer.visual_info->visual,
|
||||||
im->texture.textures = malloc(sizeof(GLuint) * im->texture.w * im->texture.h);
|
CWColormap | CWBorderPixel | CWEventMask,
|
||||||
glXMakeCurrent(im->buffer.display, im->buffer.window, im->context);
|
&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);
|
glGenTextures(im->texture.w * im->texture.h, im->texture.textures);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||||
glEnable(GL_TEXTURE_2D);
|
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,
|
__evas_gl_copy_image_rect_to_texture(im, xx, yy, ww, hh, tw, th,
|
||||||
im->texture.textures[i]);
|
im->texture.textures[i]);
|
||||||
|
__evas_image_cache_used += (tw * th * 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* done - set the actual image state to textured */
|
/* done - set the actual image state to textured */
|
||||||
im->state = EVAS_STATE_TEXTURE;
|
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,
|
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;
|
*txx = im->texture.max_size - 2;
|
||||||
*dtx = (double)*tx / (im->texture.max_size);
|
*dtx = (double)*tx / (im->texture.max_size);
|
||||||
*dtxx = (double)*txx / (im->texture.max_size);
|
*dtxx = (double)*txx / (im->texture.max_size);
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
|
||||||
}
|
}
|
||||||
else if (x < (tw - 1))
|
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)
|
if (im->buffer.dest != w)
|
||||||
{
|
{
|
||||||
im->buffer.dest = w;
|
|
||||||
glXMakeCurrent(disp, w, im->context);
|
glXMakeCurrent(disp, w, im->context);
|
||||||
|
im->buffer.dest = w;
|
||||||
|
}
|
||||||
|
if (im->alpha)
|
||||||
|
{
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glEnable(GL_DITHER);
|
|
||||||
glShadeModel(GL_FLAT);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
}
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
else
|
||||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
{
|
||||||
/* why doesnt scissor work ? */
|
glDisable(GL_BLEND);
|
||||||
/*
|
}
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_DITHER);
|
||||||
glScissor(dst_x, win_h - dst_y - 1, dst_w, dst_h);
|
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);
|
glViewport(0, 0, win_w, win_h);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
@ -201,6 +249,8 @@ void __evas_gl_set_conect_for_dest(Evas_GL_Image *im, Display *disp, Window w,
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glScalef(1, -1, 1);
|
glScalef(1, -1, 1);
|
||||||
glTranslatef(0, -win_h, 0);
|
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;
|
return im;
|
||||||
}
|
}
|
||||||
|
|
||||||
static XVisualInfo *__evas_vi = NULL;
|
|
||||||
static GLXContext __evas_gl_cx = 0;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
__evas_gl_capable(Display *disp)
|
__evas_gl_capable(Display *disp)
|
||||||
{
|
{
|
||||||
|
@ -320,46 +367,182 @@ __evas_gl_init(Display *disp)
|
||||||
/* direct rendering client */
|
/* direct rendering client */
|
||||||
__evas_gl_cx = glXCreateContext(disp, __evas_vi, NULL, GL_TRUE);
|
__evas_gl_cx = glXCreateContext(disp, __evas_vi, NULL, GL_TRUE);
|
||||||
/* GLX indirect */
|
/* 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_create_from_file(Display *disp, char *file)
|
||||||
|
{
|
||||||
|
Evas_GL_Image *im;
|
||||||
|
Imlib_Image i;
|
||||||
|
|
||||||
|
if (!file) return NULL;
|
||||||
|
im = __evas_gl_create_image();
|
||||||
|
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;
|
||||||
|
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 *
|
||||||
__evas_gl_image_new_from_file(Display *disp, char *file)
|
__evas_gl_image_new_from_file(Display *disp, char *file)
|
||||||
{
|
{
|
||||||
Evas_GL_Image *im;
|
Evas_GL_Image *im;
|
||||||
Imlib_Image i;
|
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);
|
||||||
|
|
||||||
i = imlib_load_image(file);
|
|
||||||
if (!i) return NULL;
|
|
||||||
imlib_context_set_image(i);
|
|
||||||
im = __evas_gl_create_image();
|
|
||||||
im->w = imlib_image_get_width();
|
|
||||||
im->h = imlib_image_get_height();
|
|
||||||
im->data = imlib_image_get_data();
|
|
||||||
im->texture.max_size = 256;
|
|
||||||
__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;
|
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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();
|
glXWaitGL();
|
||||||
XSync(disp, False);
|
XSync(disp, False);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
__evas_flush_draw(Display *disp, Window win)
|
__evas_gl_flush_draw(Display *disp, Window win)
|
||||||
{
|
{
|
||||||
glXSwapBuffers(disp, win);
|
glXSwapBuffers(disp, win);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
__evas_draw_rectangle(Display *disp, Window win, int x, int y, int w, int h,
|
__evas_gl_draw_rectangle(Display *disp, Window win, int x, int y, int w, int h,
|
||||||
int r, int g, int b, int a)
|
int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,14 @@ struct _evas_gl_image
|
||||||
{
|
{
|
||||||
Evas_GL_Image_State state;
|
Evas_GL_Image_State state;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
int alpha;
|
||||||
|
char *file;
|
||||||
/* data specific params */
|
/* data specific params */
|
||||||
DATA32 *data;
|
DATA32 *data;
|
||||||
/* common GL params */
|
/* common GL params */
|
||||||
GLXContext context;
|
GLXContext context;
|
||||||
/* texture state specific params */
|
/* texture state specific params */
|
||||||
struct _tex
|
struct
|
||||||
{
|
{
|
||||||
int max_size;
|
int max_size;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
@ -42,13 +44,15 @@ struct _evas_gl_image
|
||||||
GLuint *textures;
|
GLuint *textures;
|
||||||
} texture;
|
} texture;
|
||||||
/* buffer specific params */
|
/* buffer specific params */
|
||||||
struct _buf
|
struct
|
||||||
{
|
{
|
||||||
Display *display;
|
Display *display;
|
||||||
XVisualInfo *visual_info;
|
XVisualInfo *visual_info;
|
||||||
Colormap colormap;
|
Colormap colormap;
|
||||||
Window window, dest;
|
Window window, dest;
|
||||||
|
int dest_w, dest_h;
|
||||||
} buffer;
|
} buffer;
|
||||||
|
int references;
|
||||||
};
|
};
|
||||||
|
|
||||||
void __evas_gl_copy_image_rect_to_texture(Evas_GL_Image *im, int x, int y,
|
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);
|
XVisualInfo *__evas_gl_get_visual_info(Display *disp);
|
||||||
Colormap __evas_gl_get_colormap(Display *disp);
|
Colormap __evas_gl_get_colormap(Display *disp);
|
||||||
void __evas_gl_init(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);
|
Evas_GL_Image * __evas_gl_image_new_from_file(Display *disp, char *file);
|
||||||
void __evas_sync(Display *disp);
|
void __evas_gl_image_free(Evas_GL_Image *im);
|
||||||
void __evas_flush_draw(Display *disp, Window win);
|
void __evas_gl_image_destroy(Evas_GL_Image *im);
|
||||||
void __evas_draw_rectangle(Display *disp, Window win, int x, int y, int w, int h,
|
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);
|
int r, int g, int b, int a);
|
||||||
|
|
|
@ -87,7 +87,7 @@ main(int argc, char **argv)
|
||||||
0, 0, i[j]->w, i[j]->h,
|
0, 0, i[j]->w, i[j]->h,
|
||||||
xx - win_w, yy, win_w, win_h);
|
xx - win_w, yy, win_w, win_h);
|
||||||
}
|
}
|
||||||
__evas_flush_draw(d, win);
|
__evas_gl_flush_draw(d, win);
|
||||||
a++;
|
a++;
|
||||||
if (a == (win_w * 4))
|
if (a == (win_w * 4))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue