remove xrender xcb directory (useless since the merge)

SVN revision: 39669
This commit is contained in:
Vincent Torri 2009-03-24 08:11:25 +00:00
parent e402cd49eb
commit 9a074ec131
10 changed files with 0 additions and 3901 deletions

View File

@ -1,6 +0,0 @@
.deps
.libs
Makefile
Makefile.in
*.lo
*.la

View File

@ -1,25 +0,0 @@
#ifndef __EVAS_ENGINE_XRENDER_XCB_H__
#define __EVAS_ENGINE_XRENDER_XCB_H__
#include <xcb/xcb.h>
typedef struct _Evas_Engine_Info_XRender_Xcb Evas_Engine_Info_XRender_Xcb;
struct _Evas_Engine_Info_XRender_Xcb
{
/* PRIVATE - don't mess with this baby or evas will poke its tongue out */
/* at you and make nasty noises */
Evas_Engine_Info magic;
/* engine specific data & parameters it needs to set up */
struct {
xcb_connection_t *conn;
xcb_screen_t *screen;
xcb_drawable_t drawable;
xcb_pixmap_t mask;
xcb_visualtype_t *visual;
unsigned char destination_alpha : 1;
} info;
};
#endif /* __EVAS_ENGINE_XRENDER_XCB_H__ */

View File

@ -1,35 +0,0 @@
MAINTAINERCLEANFILES = Makefile.in
AM_CPPFLAGS = \
-I. \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib/include \
-I$(top_srcdir)/src/modules/engines \
@FREETYPE_CFLAGS@ \
@EINA_CFLAGS@ \
@evas_engine_xrender_xcb_cflags@
if BUILD_ENGINE_XRENDER_XCB
pkgdir = $(libdir)/evas/modules/engines/xrender_xcb/$(MODULE_ARCH)
pkg_LTLIBRARIES = module.la
module_la_SOURCES = \
evas_engine.c \
evas_engine_ximage.c \
evas_engine_xrender.c \
evas_engine_image.c \
evas_engine_font.c \
evas_engine_gradient.c
module_la_LIBADD = @EINA_LIBS@ @evas_engine_xrender_xcb_libs@ $(top_builddir)/src/lib/libevas.la
module_la_LDFLAGS = -module -avoid-version
module_la_LIBTOOLFLAGS = --tag=disable-static
include_HEADERS = Evas_Engine_XRender_Xcb.h
endif
EXTRA_DIST = evas_engine.h

File diff suppressed because it is too large Load Diff

View File

@ -1,191 +0,0 @@
#ifndef EVAS_ENGINE_H
#define EVAS_ENGINE_H
#include <sys/ipc.h>
#include <sys/shm.h>
#include <xcb/xcb.h>
#include <xcb/render.h>
#include <xcb/xcb_image.h>
typedef struct _Xcb_Image_Info Xcb_Image_Info;
typedef struct _Xcb_Image_Image Xcb_Image_Image;
typedef struct _Xcb_Render_Surface Xcb_Render_Surface;
struct _Xcb_Image_Info
{
xcb_connection_t *conn;
xcb_screen_t *screen;
xcb_drawable_t root;
xcb_drawable_t draw;
int depth;
xcb_visualtype_t *visual;
int pool_mem;
Eina_List *pool;
unsigned char can_do_shm;
xcb_render_pictforminfo_t *fmt32;
xcb_render_pictforminfo_t *fmt24;
xcb_render_pictforminfo_t *fmt8;
xcb_render_pictforminfo_t *fmt4;
xcb_render_pictforminfo_t *fmt1;
xcb_render_pictforminfo_t *fmtdef;
unsigned char mul_r;
unsigned char mul_g;
unsigned char mul_b;
unsigned char mul_a;
Xcb_Render_Surface *mul;
int references;
};
struct _Xcb_Image_Image
{
Xcb_Image_Info *xcbinf;
xcb_image_t *xcbim;
xcb_shm_segment_info_t *shm_info;
int w;
int h;
int depth;
int line_bytes;
unsigned char *data;
unsigned char available : 1;
};
struct _Xcb_Render_Surface
{
Xcb_Image_Info *xcbinf;
int w;
int h;
int depth;
xcb_render_pictforminfo_t *fmt;
xcb_drawable_t draw;
xcb_render_picture_t pic;
unsigned char alpha : 1;
unsigned char allocated : 1;
unsigned char bordered : 1;
};
/* ximage support calls (ximage vs xshmimage, cache etc.) */
Xcb_Image_Info *_xr_image_info_get(xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *visual);
void _xr_image_info_free(Xcb_Image_Info *xcbinf);
void _xr_image_info_pool_flush(Xcb_Image_Info *xcbinf, int max_num, int max_mem);
Xcb_Image_Image *_xr_image_new(Xcb_Image_Info *xcbinf, int w, int h, int depth);
void _xr_image_free(Xcb_Image_Image *xim);
void _xr_image_put(Xcb_Image_Image *xim, xcb_drawable_t draw, int x, int y, int w, int h);
/* xrender support calls */
Xcb_Render_Surface *_xr_render_surface_new(Xcb_Image_Info *xcbinf, int w, int h, xcb_render_pictforminfo_t *fmt, int alpha);
Xcb_Render_Surface *_xr_render_surface_adopt(Xcb_Image_Info *xcbinf, xcb_drawable_t draw, int w, int h, int alpha);
Xcb_Render_Surface *_xr_render_surface_format_adopt(Xcb_Image_Info *xcbinf, xcb_drawable_t draw, int w, int h, xcb_render_pictforminfo_t *fmt, int alpha);
void _xr_render_surface_free(Xcb_Render_Surface *rs);
void _xr_render_surface_repeat_set(Xcb_Render_Surface *rs, int repeat);
void _xr_render_surface_solid_rectangle_set(Xcb_Render_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h);
void _xr_render_surface_argb_pixels_fill(Xcb_Render_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h, int ox, int oy);
void _xr_render_surface_rgb_pixels_fill(Xcb_Render_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h, int ox, int oy);
void _xr_render_surface_clips_set(Xcb_Render_Surface *rs, RGBA_Draw_Context *dc, int rx, int ry, int rw, int rh);
void _xr_render_surface_composite(Xcb_Render_Surface *srs, Xcb_Render_Surface *drs, RGBA_Draw_Context *dc, int sx, int sy, int sw, int sh, int x, int y, int w, int h, int smooth);
void _xr_render_surface_copy(Xcb_Render_Surface *srs, Xcb_Render_Surface *drs, int sx, int sy, int x, int y, int w, int h);
void _xr_render_surface_rectangle_draw(Xcb_Render_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h);
void _xr_render_surface_line_draw(Xcb_Render_Surface *rs, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2);
void _xre_poly_draw(Xcb_Render_Surface *rs, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points);
typedef struct _XR_Image XR_Image;
struct _XR_Image
{
Xcb_Image_Info *xcbinf;
const char *file;
const char *key;
char *fkey;
RGBA_Image *im;
void *data;
int w, h;
Xcb_Render_Surface *surface;
int references;
char *format;
const char *comment;
Tilebuf *updates;
RGBA_Image_Loadopts load_opts;
struct {
int space;
void *data;
unsigned char no_free : 1;
} cs;
unsigned char alpha : 1;
unsigned char dirty : 1;
unsigned char free_data : 1;
};
XR_Image *_xre_image_load(Xcb_Image_Info *xcbinf, const char *file, const char *key, Evas_Image_Load_Opts *lo);
XR_Image *_xre_image_new_from_data(Xcb_Image_Info *xcbinf, int w, int h, void *data, int alpha, int cspace);
XR_Image *_xre_image_new_from_copied_data(Xcb_Image_Info *xcbinf, int w, int h, void *data, int alpha, int cspace);
XR_Image *_xre_image_new(Xcb_Image_Info *xcbinf, int w, int h);
void _xre_image_resize(XR_Image *im, int w, int h);
void _xre_image_free(XR_Image *im);
void _xre_image_region_dirty(XR_Image *im, int x, int y, int w, int h);
void _xre_image_dirty(XR_Image *im);
XR_Image *_xre_image_copy(XR_Image *im);
void *_xre_image_data_get(XR_Image *im);
XR_Image *_xre_image_data_find(void *data);
void _xre_image_data_put(XR_Image *im, void *data);
void _xre_image_alpha_set(XR_Image *im, int alpha);
int _xre_image_alpha_get(XR_Image *im);
void _xre_image_border_set(XR_Image *im, int l, int r, int t, int b);
void _xre_image_border_get(XR_Image *im, int *l, int *r, int *t, int *b);
void _xre_image_surface_gen(XR_Image *im);
void _xre_image_cache_set(int size);
int _xre_image_cache_get(void);
typedef struct _XR_Font_Surface XR_Font_Surface;
struct _XR_Font_Surface
{
Xcb_Image_Info *xcbinf;
RGBA_Font_Glyph *fg;
int w;
int h;
xcb_drawable_t draw;
xcb_render_picture_t pic;
};
XR_Font_Surface *_xre_font_surface_new (Xcb_Image_Info *xcbinf,
RGBA_Font_Glyph *fg);
void _xre_font_surface_free (XR_Font_Surface *fs);
void _xre_font_surface_draw (Xcb_Image_Info *xcbinf,
RGBA_Image *surface,
RGBA_Draw_Context *dc,
RGBA_Font_Glyph *fg,
int x,
int y);
typedef struct _XR_Gradient XR_Gradient;
struct _XR_Gradient
{
Xcb_Image_Info *xcbinf;
Xcb_Render_Surface *surface;
RGBA_Gradient *grad;
unsigned char changed : 1;
int sw, sh;
};
/* gradient */
XR_Gradient *_xre_gradient_new(Xcb_Image_Info *xcbinf);
void _xre_gradient_free(XR_Gradient *gr);
void _xre_gradient_color_stop_add(XR_Gradient *gr, int r, int g, int b, int a, int delta);
void _xre_gradient_alpha_stop_add(XR_Gradient *gr, int a, int delta);
void _xre_gradient_color_data_set(XR_Gradient *gr, void *map, int len, int has_alpha);
void _xre_gradient_alpha_data_set(XR_Gradient *gr, void *alpha_map, int len);
void _xre_gradient_clear(XR_Gradient *gr);
void _xre_gradient_fill_set(XR_Gradient *gr, int x, int y, int w, int h);
void _xre_gradient_fill_angle_set(XR_Gradient *gr, double angle);
void _xre_gradient_fill_spread_set(XR_Gradient *gr, int spread);
void _xre_gradient_angle_set(XR_Gradient *gr, double angle);
void _xre_gradient_offset_set(XR_Gradient *gr, float offset);
void _xre_gradient_direction_set(XR_Gradient *gr, int direction);
void _xre_gradient_type_set(XR_Gradient *gr, char *name, char *params);
void _xre_gradient_draw(Xcb_Render_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h);
#endif

View File

@ -1,208 +0,0 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_Xcb.h"
static Eina_Hash *_xr_fg_pool = NULL;
XR_Font_Surface *
_xre_font_surface_new(Xcb_Image_Info *xcbinf, RGBA_Font_Glyph *fg)
{
char buf[256];
char buf2[256];
uint32_t values[3];
XR_Font_Surface *fs;
DATA8 *data;
Xcb_Image_Image *xcbim;
Eina_Hash *pool;
uint32_t mask;
int w;
int h;
int pitch;
data = fg->glyph_out->bitmap.buffer;
w = fg->glyph_out->bitmap.width;
h = fg->glyph_out->bitmap.rows;
pitch = fg->glyph_out->bitmap.pitch;
if (pitch < w) pitch = w;
if ((w <= 0) || (h <= 0)) return NULL;
if (fg->ext_dat)
{
fs = fg->ext_dat;
if ((fs->xcbinf->conn == xcbinf->conn) &&
(fs->xcbinf->root == xcbinf->root))
return fs;
snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xcbinf->conn, fs->xcbinf->root);
pool = eina_hash_find(_xr_fg_pool, buf);
if (pool)
{
snprintf(buf, sizeof(buf), "%p", fg);
fs = eina_hash_find(pool, buf);
if (fs) return fs;
}
}
fs = calloc(1, sizeof(XR_Font_Surface));
if (!fs) return NULL;
fs->xcbinf = xcbinf;
fs->fg = fg;
fs->xcbinf->references++;
fs->w = w;
fs->h = h;
snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xcbinf->conn, fs->xcbinf->root);
pool = eina_hash_find(_xr_fg_pool, buf);
if (!pool) pool = eina_hash_string_superfast_new(NULL);
snprintf(buf2, sizeof(buf2), "%p", fg);
eina_hash_add(pool, buf2, fs);
if (!_xr_fg_pool) _xr_fg_pool = eina_hash_string_superfast_new(NULL);
eina_hash_add(_xr_fg_pool, buf, pool);
fs->draw = xcb_generate_id(xcbinf->conn);
xcb_create_pixmap(xcbinf->conn, xcbinf->fmt8->depth, fs->draw, xcbinf->root, w, h);
mask = XCB_RENDER_CP_REPEAT | XCB_RENDER_CP_DITHER | XCB_RENDER_CP_COMPONENT_ALPHA;
values[0] = 0;
values[1] = 0;
values[2] = 0;
fs->pic = xcb_generate_id(xcbinf->conn);
xcb_render_create_picture(xcbinf->conn, fs->pic, fs->draw, xcbinf->fmt8->id, mask, values);
xcbim = _xr_image_new(fs->xcbinf, w, h, xcbinf->fmt8->depth);
if ((fg->glyph_out->bitmap.num_grays == 256) &&
(fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
{
int x, y;
DATA8 *p1, *p2;
for (y = 0; y < h; y++)
{
p1 = data + (pitch * y);
p2 = ((DATA8 *)xcbim->data) + (xcbim->line_bytes * y);
for (x = 0; x < w; x++)
{
*p2 = *p1;
p1++;
p2++;
}
}
}
else
{
DATA8 *tmpbuf = NULL, *dp, *tp, bits;
int bi, bj, end;
const DATA8 bitrepl[2] = {0x0, 0xff};
tmpbuf = alloca(w);
{
int x, y;
DATA8 *p1, *p2;
for (y = 0; y < h; y++)
{
p1 = tmpbuf;
p2 = ((DATA8 *)xcbim->data) + (xcbim->line_bytes * y);
tp = tmpbuf;
dp = data + (y * fg->glyph_out->bitmap.pitch);
for (bi = 0; bi < w; bi += 8)
{
bits = *dp;
if ((w - bi) < 8) end = w - bi;
else end = 8;
for (bj = 0; bj < end; bj++)
{
*tp = bitrepl[(bits >> (7 - bj)) & 0x1];
tp++;
}
dp++;
}
for (x = 0; x < w; x++)
{
*p2 = *p1;
p1++;
p2++;
}
}
}
}
_xr_image_put(xcbim, fs->draw, 0, 0, w, h);
return fs;
}
static Evas_Bool
_xre_font_pool_cb(const Eina_Hash *hash, const char *key, void *data, void *fdata)
{
char buf[256];
Eina_Hash *pool;
XR_Font_Surface *fs;
fs = fdata;
pool = data;
snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xcbinf->conn, fs->xcbinf->root);
eina_hash_del(pool, buf, fs);
if (!hash) hash = eina_hash_string_superfast_new(NULL);
eina_hash_modify(hash, key, pool);
return 1;
}
void
_xre_font_surface_free(XR_Font_Surface *fs)
{
if (!fs) return;
eina_hash_foreach(_xr_fg_pool, _xre_font_pool_cb, fs);
xcb_free_pixmap(fs->xcbinf->conn, fs->draw);
xcb_render_free_picture(fs->xcbinf->conn, fs->pic);
_xr_image_info_free(fs->xcbinf);
free(fs);
}
void
_xre_font_surface_draw(Xcb_Image_Info *xcbinf __UNUSED__, RGBA_Image *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y)
{
XR_Font_Surface *fs;
Xcb_Render_Surface *target_surface;
xcb_rectangle_t rect;
int r;
int g;
int b;
int a;
fs = fg->ext_dat;
if (!fs || !fs->xcbinf || !dc || !dc->col.col) return;
target_surface = (Xcb_Render_Surface *)(surface->image.data);
a = (dc->col.col >> 24) & 0xff;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
if ((fs->xcbinf->mul_r != r) || (fs->xcbinf->mul_g != g) ||
(fs->xcbinf->mul_b != b) || (fs->xcbinf->mul_a != a))
{
fs->xcbinf->mul_r = r;
fs->xcbinf->mul_g = g;
fs->xcbinf->mul_b = b;
fs->xcbinf->mul_a = a;
_xr_render_surface_solid_rectangle_set(fs->xcbinf->mul, r, g, b, a, 0, 0, 1, 1);
}
rect.x = x;
rect.y = y;
rect.width = fs->w;
rect.height = fs->h;
if (dc->clip.use)
{
RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.width, rect.height,
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
}
xcb_render_set_picture_clip_rectangles(target_surface->xcbinf->conn,
target_surface->pic, 0, 0, 1, &rect);
xcb_render_composite(fs->xcbinf->conn, XCB_RENDER_PICT_OP_OVER,
fs->xcbinf->mul->pic,
fs->pic,
target_surface->pic,
0, 0,
0, 0,
x, y,
fs->w, fs->h);
}

View File

@ -1,208 +0,0 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_Xcb.h"
#include <math.h>
XR_Gradient *
_xre_gradient_new(Xcb_Image_Info *xcbinf)
{
XR_Gradient *gr;
if (!xcbinf) return NULL;
gr = calloc(1, sizeof(XR_Gradient));
if (!gr) return NULL;
gr->grad = evas_common_gradient_new();
if (!gr->grad)
{
free(gr);
return NULL;
}
gr->xcbinf = xcbinf;
gr->xcbinf->references++;
gr->changed = 1;
return gr;
}
void
_xre_gradient_free(XR_Gradient *gr)
{
if (!gr) return;
if (gr->grad)
evas_common_gradient_free(gr->grad);
if (gr->surface)
_xr_render_surface_free(gr->surface);
_xr_image_info_free(gr->xcbinf);
free(gr);
}
void
_xre_gradient_color_stop_add(XR_Gradient *gr, int r, int g, int b, int a, int delta)
{
if (!gr) return;
evas_common_gradient_color_stop_add(gr->grad, r, g, b, a, delta);
gr->changed = 1;
}
void
_xre_gradient_alpha_stop_add(XR_Gradient *gr, int a, int delta)
{
if (!gr) return;
evas_common_gradient_alpha_stop_add(gr->grad, a, delta);
gr->changed = 1;
}
void
_xre_gradient_clear(XR_Gradient *gr)
{
if (!gr) return;
evas_common_gradient_clear(gr->grad);
gr->changed = 1;
}
void
_xre_gradient_color_data_set(XR_Gradient *gr, void *map, int len, int has_alpha)
{
evas_common_gradient_color_data_set(gr->grad, map, len, has_alpha);
gr->changed = 1;
}
void
_xre_gradient_alpha_data_set(XR_Gradient *gr, void *amap, int len)
{
evas_common_gradient_alpha_data_set(gr->grad, amap, len);
gr->changed = 1;
}
void
_xre_gradient_fill_set(XR_Gradient *gr, int x, int y, int w, int h)
{
if (!gr) return;
evas_common_gradient_fill_set(gr->grad, x, y, w, h);
gr->changed = 1;
}
void
_xre_gradient_fill_angle_set(XR_Gradient *gr, double angle)
{
if (!gr) return;
evas_common_gradient_fill_angle_set(gr->grad, angle);
gr->changed = 1;
}
void
_xre_gradient_fill_spread_set(XR_Gradient *gr, int spread)
{
if (!gr) return;
evas_common_gradient_fill_spread_set(gr->grad, spread);
gr->changed = 1;
}
void
_xre_gradient_angle_set(XR_Gradient *gr, double angle)
{
if (!gr) return;
evas_common_gradient_map_angle_set(gr->grad, angle);
gr->changed = 1;
}
void
_xre_gradient_offset_set(XR_Gradient *gr, float offset)
{
if (!gr) return;
evas_common_gradient_map_offset_set(gr->grad, offset);
gr->changed = 1;
}
void
_xre_gradient_direction_set(XR_Gradient *gr, int direction)
{
if (!gr) return;
evas_common_gradient_map_direction_set(gr->grad, direction);
gr->changed = 1;
}
void
_xre_gradient_type_set(XR_Gradient *gr, char *name, char *params)
{
if (!gr) return;
evas_common_gradient_type_set(gr->grad, name, params);
gr->changed = 1;
}
void
_xre_gradient_draw(Xcb_Render_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h)
{
int alpha = 0;
if ((w < 1) || (h < 1)) return;
if (!rs || !dc || !gr) return;
if (!gr->xcbinf || !gr->grad || !gr->grad->type.geometer) return;
if (gr->grad->type.geometer->has_alpha(gr->grad, dc->render_op) ||
gr->grad->type.geometer->has_mask(gr->grad, dc->render_op))
alpha = 1;
if (((gr->sw != w) || (gr->sh != h)) && gr->surface)
{
_xr_render_surface_free(gr->surface);
gr->surface = NULL;
gr->changed = 1;
}
if (!gr->surface)
{
gr->surface = _xr_render_surface_new(gr->xcbinf, w, h, gr->xcbinf->fmt32, 1);
if (!gr->surface) return;
gr->changed = 1;
}
if (gr->changed)
{
int op = dc->render_op, cuse = dc->clip.use;
RGBA_Image *im;
Xcb_Image_Image *xcbim;
xcbim = _xr_image_new(gr->xcbinf, w, h, gr->surface->depth);
if (!xcbim)
{
_xr_render_surface_free(gr->surface);
gr->surface = NULL;
return;
}
im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
w, h,
(DATA32 *)xcbim->data,
1, EVAS_COLORSPACE_ARGB8888);
if (!im)
{
_xr_render_surface_free(gr->surface);
gr->surface = NULL;
return;
}
dc->render_op = _EVAS_RENDER_FILL;
dc->clip.use = 0;
evas_common_gradient_draw(im, dc, 0, 0, w, h, gr->grad);
if
#ifdef WORDS_BIGENDIAN
(xcbim->xcbim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST)
#else
(xcbim->xcbim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
#endif
{
DATA32 *p = im->image.data, *pe = p + (w * h);
while (p < pe)
{
*p = (*p << 24) + ((*p << 8) & 0xff0000) + ((*p >> 8) & 0xff00) + (*p >> 24);
p++;
}
}
_xr_image_put(xcbim, gr->surface->draw, 0, 0, w, h);
evas_cache_image_drop(&im->cache_entry);
dc->render_op = op;
dc->clip.use = cuse;
}
gr->surface->alpha = alpha;
_xr_render_surface_composite(gr->surface, rs, dc, 0, 0, gr->surface->w, gr->surface->h, x, y, w, h, 0);
gr->changed = 0;
gr->sw = w; gr->sh = h;
}

View File

@ -1,696 +0,0 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_Xcb.h"
static Eina_Hash *_xr_image_hash = NULL;
static int _xr_image_cache_size = 0;
static int _xr_image_cache_usage = 0;
static Eina_List *_xr_image_cache = NULL;
static Eina_Hash *_xr_image_dirty_hash = NULL;
static void
__xre_image_dirty_hash_add(XR_Image *im)
{
char buf[64];
if (!im->data) return;
snprintf(buf, sizeof(buf), "%p", im->data);
if (!_xr_image_dirty_hash) _xr_image_dirty_hash = eina_hash_string_superfast_new(NULL);
eina_hash_add(_xr_image_dirty_hash, buf, im);
}
static void
__xre_image_dirty_hash_del(XR_Image *im)
{
char buf[64];
if (!im->data) return;
snprintf(buf, sizeof(buf), "%p", im->data);
eina_hash_del(_xr_image_dirty_hash, buf, im);
}
static XR_Image *
__xre_image_dirty_hash_find(void *data)
{
char buf[64];
snprintf(buf, sizeof(buf), "%p", data);
return eina_hash_find(_xr_image_dirty_hash, buf);
}
static XR_Image *
__xre_image_find(char *fkey)
{
XR_Image *im;
im = eina_hash_find(_xr_image_hash, fkey);
if (!im)
{
Eina_List *l;
EINA_LIST_FOREACH(_xr_image_cache, l, im)
{
if (!strcmp(im->fkey, fkey))
{
_xr_image_cache = eina_list_remove_list(_xr_image_cache, l);
if (!_xr_image_hash) _xr_image_hash = eina_hash_string_superfast_new(NULL);
eina_hash_add(_xr_image_hash, im->fkey, im);
_xr_image_cache_usage -= (im->w * im->h * 4);
break;
}
im = NULL;
}
}
if (im) im->references++;
return im;
}
XR_Image *
_xre_image_load(Xcb_Image_Info *xcbinf, const char *file, const char *key, Evas_Image_Load_Opts *lo)
{
char buf[4096];
XR_Image *im;
if (!file) return NULL;
if (!lo)
{
if (key)
snprintf(buf, sizeof(buf), "/@%p@%x@/%s//://%s", xcbinf->conn, xcbinf->root, file, key);
else
snprintf(buf, sizeof(buf), "/@%p@%x@/%s", xcbinf->conn, xcbinf->root, file);
}
else
{
if (key)
snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//@%p@%x@/%s//://%s", lo->scale_down_by, lo->dpi, lo->w, lo->h, xcbinf->conn, xcbinf->root, file, key);
else
snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//@%p@%x@/%s", lo->scale_down_by, lo->dpi, lo->w, lo->h, xcbinf->conn, xcbinf->root, file);
}
im = __xre_image_find(buf);
if (im)
{
return im;
}
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->im = evas_common_load_image_from_file(file, key, lo);
if (!im->im)
{
free(im);
return NULL;
}
im->xcbinf = xcbinf;
im->xcbinf->references++;
im->cs.space = EVAS_COLORSPACE_ARGB8888;
im->fkey = strdup(buf);
im->file = (char *)eina_stringshare_add(file);
if (key) im->key = (char *)eina_stringshare_add(key);
im->w = im->im->cache_entry.w;
im->h = im->im->cache_entry.h;
im->references = 1;
if (lo) im->load_opts = *lo;
if (im->im->info.comment) im->comment = (char *)eina_stringshare_add(im->im->info.comment);
/* if (im->im->info.format == 1) im->format = eina_stringshare_add("png"); */
if (im->im->cache_entry.flags.alpha) im->alpha = 1;
if (!_xr_image_hash) _xr_image_hash = eina_hash_string_superfast_new(NULL);
eina_hash_direct_add(_xr_image_hash, im->fkey, im);
return im;
}
XR_Image *
_xre_image_new_from_data(Xcb_Image_Info *xcbinf, int w, int h, void *data, int alpha, int cspace)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->xcbinf = xcbinf;
im->xcbinf->references++;
im->cs.space = cspace;
im->w = w;
im->h = h;
im->references = 1;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
im->data = data;
im->alpha = alpha;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
im->cs.data = data;
im->cs.no_free = 1;
break;
default:
abort();
break;
}
im->dirty = 1;
__xre_image_dirty_hash_add(im);
return im;
}
XR_Image *
_xre_image_new_from_copied_data(Xcb_Image_Info *xcbinf, int w, int h, void *data, int alpha, int cspace)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->cs.space = cspace;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
im->data = malloc(w * h * 4);
if (!im->data)
{
free(im);
return NULL;
}
if (data)
{
Gfx_Func_Copy func;
func = evas_common_draw_func_copy_get(w * h, 0);
if (func) func(data, im->data, w * h);
evas_common_cpu_end_opt();
}
im->alpha = alpha;
im->free_data = 1;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
im->cs.no_free = 0;
im->cs.data = calloc(1, h * sizeof(unsigned char *) * 2);
if ((data) && (im->cs.data))
memcpy(im->cs.data, data, h * sizeof(unsigned char *) * 2);
break;
default:
abort();
break;
}
im->w = w;
im->h = h;
im->references = 1;
im->xcbinf = xcbinf;
im->xcbinf->references++;
im->dirty = 1;
__xre_image_dirty_hash_add(im);
return im;
}
XR_Image *
_xre_image_new(Xcb_Image_Info *xcbinf, int w, int h)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->data = malloc(w * h * 4);
if (!im->data)
{
free(im);
return NULL;
}
im->w = w;
im->h = h;
im->references = 1;
im->cs.space = EVAS_COLORSPACE_ARGB8888;
im->xcbinf = xcbinf;
im->xcbinf->references++;
im->free_data = 1;
im->alpha = 1;
im->dirty = 1;
__xre_image_dirty_hash_add(im);
return im;
}
static void
__xre_image_real_free(XR_Image *im)
{
if (im->cs.data)
{
if (!im->cs.no_free) free(im->cs.data);
}
if (im->file) eina_stringshare_del(im->file);
if (im->key) eina_stringshare_del(im->key);
if (im->fkey) free(im->fkey);
if (im->im) evas_cache_image_drop(&im->im->cache_entry);
if ((im->data) && (im->dirty)) __xre_image_dirty_hash_del(im);
if ((im->free_data) && (im->data)) free(im->data);
if (im->surface) _xr_render_surface_free(im->surface);
if (im->format) eina_stringshare_del(im->format);
if (im->comment) eina_stringshare_del(im->comment);
if (im->updates) evas_common_tilebuf_free(im->updates);
_xr_image_info_free(im->xcbinf);
free(im);
}
void
_xre_image_free(XR_Image *im)
{
im->references--;
if (im->references != 0) return;
if (!im->dirty)
{
if (im->fkey)
eina_hash_del(_xr_image_hash, im->fkey, im);
_xr_image_cache = eina_list_prepend(_xr_image_cache, im);
_xr_image_cache_usage += (im->w * im->h * 4);
_xre_image_cache_set(_xr_image_cache_size);
}
else
{
__xre_image_real_free(im);
}
}
void
_xre_image_region_dirty(XR_Image *im, int x, int y, int w, int h)
{
if (!im->updates)
{
im->updates = evas_common_tilebuf_new(im->w, im->h);
if (im->updates) evas_common_tilebuf_set_tile_size(im->updates, 8, 8);
}
if (im->updates)
evas_common_tilebuf_add_redraw(im->updates, x, y, w, h);
}
void
_xre_image_dirty(XR_Image *im)
{
if (im->dirty) return;
if (im->fkey)
eina_hash_del(_xr_image_hash, im->fkey, im);
im->dirty = 1;
__xre_image_dirty_hash_add(im);
}
XR_Image *
_xre_image_copy(XR_Image *im)
{
XR_Image *im2;
void *data = NULL;
if (im->data) data = im->data;
else if (im->cs.data) data = im->cs.data;
else
{
if (!im->im)
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts));
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
data = im->im->image.data;
}
}
if (!data) return NULL;
im2 = _xre_image_new_from_copied_data(im->xcbinf, im->w, im->h, data, im->alpha, im->cs.space);
return im2;
}
void
_xre_image_resize(XR_Image *im, int w, int h)
{
if ((w == im->w) && (h == im->h)) return;
if (im->surface)
{
Xcb_Render_Surface *old_surface;
old_surface = im->surface;
im->surface = _xr_render_surface_new(old_surface->xcbinf, w + 2, h + 2, old_surface->fmt, old_surface->alpha);
_xr_render_surface_free(old_surface);
}
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
if (im->data)
{
if (im->free_data)
{
if (im->data) free(im->data);
im->data = malloc(w * h * 4);
}
}
else if (im->im)
{
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
if (im->free_data)
{
if (im->data) free(im->data);
im->data = malloc(w * h * 4);
}
}
else
{
im->data = malloc(w * h * 4);
im->free_data = 1;
}
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
if (im->data)
{
if (im->free_data)
{
if (im->data) free(im->data);
}
im->data = NULL;
}
if (im->im)
{
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
}
if (!im->cs.no_free)
{
if (im->cs.data) free(im->cs.data);
im->cs.data = calloc(1, h * sizeof(unsigned char *) * 2);
}
break;
default:
abort();
break;
}
__xre_image_dirty_hash_del(im);
__xre_image_dirty_hash_add(im);
im->w = w;
im->h = h;
}
void *
_xre_image_data_get(XR_Image *im)
{
void *data = NULL;
if (im->data) data = im->data;
else if (im->cs.data) data = im->cs.data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts));
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
data = im->im->image.data;
}
}
return data;
}
XR_Image *
_xre_image_data_find(void *data)
{
XR_Image *im;
im = __xre_image_dirty_hash_find(data);
if (im)
{
im->references++;
}
return im;
}
void
_xre_image_data_put(XR_Image *im, void *data)
{
void *imdata = NULL;
if (!data) return;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
if (im->im)
{
if (data == im->im->image.data) return;
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
}
if (im->cs.data == data) return;
if (im->data)
{
if (im->data == data) return;
if (im->free_data) free(im->data);
im->free_data = 0;
}
im->data = data;
im->free_data = 0;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
if (im->data)
{
if (im->free_data) free(im->data);
im->data = NULL;
}
im->free_data = 0;
if (data == im->cs.data) return;
if (!im->cs.no_free)
{
if (im->cs.data) free(im->cs.data);
}
im->cs.data = data;
break;
default:
abort();
break;
}
__xre_image_dirty_hash_del(im);
__xre_image_dirty_hash_add(im);
if (im->surface)
{
_xr_render_surface_free(im->surface);
im->surface = NULL;
}
if (!im->dirty)
{
if (im->fkey)
eina_hash_del(_xr_image_hash, im->fkey, im);
im->dirty = 1;
}
if (im->updates)
{
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
}
void
_xre_image_alpha_set(XR_Image *im, int alpha)
{
if (im->alpha == alpha) return;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
im->alpha = alpha;
if (im->surface)
{
Xcb_Render_Surface *old_surface;
old_surface = im->surface;
im->surface = NULL;
if (im->alpha)
im->surface = _xr_render_surface_new(im->xcbinf, im->w + 2, im->h + 2, im->xcbinf->fmt32, 1);
else
{
/* FIXME: if im->depth == 16, use xcbinf->fmtdef */
if ((im->xcbinf->depth == 16) &&
(im->xcbinf->visual->red_mask == 0xf800) &&
(im->xcbinf->visual->green_mask == 0x07e0) &&
(im->xcbinf->visual->blue_mask == 0x001f))
im->surface = _xr_render_surface_new(im->xcbinf, im->w + 2, im->h + 2, im->xcbinf->fmtdef, 0);
else
im->surface = _xr_render_surface_new(im->xcbinf, im->w + 2, im->h + 2, im->xcbinf->fmt24, 0);
}
if (im->surface)
_xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, im->w + 2, im->h + 2);
_xr_render_surface_free(old_surface);
}
if (im->updates)
{
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
default:
break;
}
}
int
_xre_image_alpha_get(XR_Image *im)
{
if (im->im)
{
if (im->im->cache_entry.space != EVAS_COLORSPACE_ARGB8888) return 0;
}
return im->alpha;
}
void
_xre_image_border_set(XR_Image *im, int l, int r, int t, int b)
{
if (!im) return;
_xre_image_surface_gen(im);
if (l < 1) l = 0;
if (r < 1) r = 0;
if (t < 1) t = 0;
if (b < 1) b = 0;
if (im->surface)
{
if (l | r | t | b)
im->surface->bordered = 1;
else
im->surface->bordered = 0;
}
}
void
_xre_image_border_get(XR_Image *im __UNUSED__, int *l __UNUSED__, int *r __UNUSED__, int *t __UNUSED__, int *b __UNUSED__)
{
}
void
_xre_image_surface_gen(XR_Image *im)
{
void *data = NULL;
void *tdata = NULL;
if ((im->surface) && (!im->updates)) return;
if (im->data) data = im->data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts));
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
data = im->im->image.data;
}
}
if (!data)
{
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
return;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
if ((im->cs.data) && (*((unsigned char **)im->cs.data)))
{
tdata = malloc(im->w * im->h * sizeof(DATA32));
if (tdata)
evas_common_convert_yuv_420p_601_rgba(im->cs.data,
tdata,
im->w, im->h);
data = tdata;
}
break;
default:
abort();
break;
}
if (!data) return;
}
if (im->surface)
{
if (im->updates)
{
Tilebuf_Rect *rects, *r;
rects = evas_common_tilebuf_get_render_rects(im->updates);
if (rects)
{
EINA_INLIST_FOREACH(rects, r)
{
int rx, ry, rw, rh;
rx = r->x; ry = r->y; rw = r->w, rh = r->h;
RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, im->w, im->h);
if (im->alpha)
_xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh, 1, 1);
else
/* FIXME: if im->depth == 16 - convert to 16bpp then
* upload */
_xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh, 1, 1);
}
evas_common_tilebuf_free_render_rects(rects);
}
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
if (tdata) free(tdata);
return;
}
if (im->alpha)
{
im->surface = _xr_render_surface_new(im->xcbinf, im->w + 2, im->h + 2, im->xcbinf->fmt32, 1);
_xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h, 1, 1);
}
else
{
/* FIXME: if im->xcbinf->depth == 16, use xcbinf->fmtdef */
if ((im->xcbinf->depth == 16) &&
(im->xcbinf->visual->red_mask == 0xf800) &&
(im->xcbinf->visual->green_mask == 0x07e0) &&
(im->xcbinf->visual->blue_mask == 0x001f))
im->surface = _xr_render_surface_new(im->xcbinf, im->w + 2, im->h + 2, im->xcbinf->fmtdef, 0);
else
im->surface = _xr_render_surface_new(im->xcbinf, im->w + 2, im->h + 2, im->xcbinf->fmt24, 0);
/* FIXME: if im->depth == 16 - convert to 16bpp then
* upload */
_xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h, 1, 1);
}
/* fill borders */
_xr_render_surface_copy(im->surface, im->surface,
1, 1,
0, 1,
1, im->h);
_xr_render_surface_copy(im->surface, im->surface,
0, 1,
0, 0,
im->w + 2, 1);
_xr_render_surface_copy(im->surface, im->surface,
im->w, 1,
im->w + 1, 1,
1, im->h);
_xr_render_surface_copy(im->surface, im->surface,
0, im->h,
0, im->h + 1,
im->w + 2, 1);
if ((im->im) && (!im->dirty))
{
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
}
if (tdata) free(tdata);
}
void
_xre_image_cache_set(int size)
{
_xr_image_cache_size = size;
while (_xr_image_cache_usage > _xr_image_cache_size)
{
Eina_List *l;
l = eina_list_last(_xr_image_cache);
if (l)
{
XR_Image *im;
im = l->data;
_xr_image_cache = eina_list_remove_list(_xr_image_cache, l);
_xr_image_cache_usage -= (im->w * im->h * 4);
__xre_image_real_free(im);
}
}
}
int
_xre_image_cache_get(void)
{
return _xr_image_cache_size;
}

View File

@ -1,573 +0,0 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_Xcb.h"
static Eina_List *_image_info_list = NULL;
static int _xcb_err = 0;
enum
{
xcb_render_pictforminfo_id = 1 << 0,
xcb_render_pictforminfo_type_t = 1 << 1,
xcb_render_pictforminfo_depth_t = 1 << 2,
xcb_render_pictforminfo_red_shift_t = 1 << 3,
xcb_render_pictforminfo_red_mask_t = 1 << 4,
xcb_render_pictforminfo_green_shift_t = 1 << 5,
xcb_render_pictforminfo_green_mask_t = 1 << 6,
xcb_render_pictforminfo_blue_shift_t = 1 << 7,
xcb_render_pictforminfo_blue_mask_t = 1 << 8,
xcb_render_pictforminfo_alpha_shift_t = 1 << 9,
xcb_render_pictforminfo_alpha_mask_t = 1 << 10,
xcb_render_pictforminfo_colormap_t = 1 << 11,
};
enum
{
xcb_render_standard_pictforminfoargb_32_t,
xcb_render_standard_pictforminforgb_24_t,
xcb_render_standard_pictforminfoa_8_t,
xcb_render_standard_pictforminfoa_4_t,
xcb_render_standard_pictforminfoa_1_t,
xcb_render_standard_pictforminfo_count_t
};
static xcb_render_pictforminfo_t *
xcb_render_find_pictforminfo (xcb_connection_t *conn, uint32_t mask, const xcb_render_pictforminfo_t *template, int count)
{
xcb_render_query_pict_formats_cookie_t cookie;
xcb_render_query_pict_formats_reply_t *rep;
xcb_render_pictforminfo_iterator_t iter_forminfo;
cookie = xcb_render_query_pict_formats_unchecked (conn);
rep = xcb_render_query_pict_formats_reply (conn, cookie, NULL);
iter_forminfo = xcb_render_query_pict_formats_formats_iterator (rep);
for (; iter_forminfo.rem; xcb_render_pictforminfo_next (&iter_forminfo)) {
if (mask & xcb_render_pictforminfo_id)
if (template->id != iter_forminfo.data->id)
continue;
if (mask & xcb_render_pictforminfo_type_t)
if (template->type != iter_forminfo.data->type)
continue;
if (mask & xcb_render_pictforminfo_depth_t)
if (template->depth != iter_forminfo.data->depth)
continue;
if (mask & xcb_render_pictforminfo_red_shift_t)
if (template->direct.red_shift != iter_forminfo.data->direct.red_shift)
continue;
if (mask & xcb_render_pictforminfo_red_mask_t)
if (template->direct.red_mask != iter_forminfo.data->direct.red_mask)
continue;
if (mask & xcb_render_pictforminfo_green_shift_t)
if (template->direct.green_shift != iter_forminfo.data->direct.green_shift)
continue;
if (mask & xcb_render_pictforminfo_green_mask_t)
if (template->direct.green_mask != iter_forminfo.data->direct.green_mask)
continue;
if (mask & xcb_render_pictforminfo_blue_shift_t)
if (template->direct.blue_shift != iter_forminfo.data->direct.blue_shift)
continue;
if (mask & xcb_render_pictforminfo_blue_mask_t)
if (template->direct.blue_mask != iter_forminfo.data->direct.blue_mask)
continue;
if (mask & xcb_render_pictforminfo_alpha_shift_t)
if (template->direct.alpha_shift != iter_forminfo.data->direct.alpha_shift)
continue;
if (mask & xcb_render_pictforminfo_alpha_mask_t)
if (template->direct.alpha_mask != iter_forminfo.data->direct.alpha_mask)
continue;
if (mask & xcb_render_pictforminfo_colormap_t)
if (template->colormap != iter_forminfo.data->colormap)
continue;
if (count-- == 0) {
xcb_render_pictforminfo_t *forminfo;
forminfo = (xcb_render_pictforminfo_t *)malloc (sizeof (xcb_render_pictforminfo_t));
memcpy (forminfo, iter_forminfo.data, sizeof (xcb_render_pictforminfo_t));
free (rep);
return forminfo;
}
}
free (rep);
return NULL;
}
static xcb_render_pictforminfo_t *
xcb_render_find_standard_pictforminfo (xcb_connection_t *conn, int format)
{
xcb_render_pictforminfo_t *forminfo = NULL;
struct {
xcb_render_pictforminfo_t template;
uint32_t mask;
} standardFormats[xcb_render_standard_pictforminfo_count_t] = {
/* StandardPICTFORMINFOARGB32 */
{
{
0, /* id */
XCB_RENDER_PICT_TYPE_DIRECT, /* type */
32, /* depth */
{ 0, 0 }, /* pad */
{ /* direct */
16, /* direct.red_shift */
0xff, /* direct.red_mask */
8, /* direct.green_shift */
0xff, /* direct.green_mask */
0, /* direct.blue_shift */
0xff, /* direct.blue_mask */
24, /* direct.alpha_shift */
0xff /* direct.alpha_mask */
},
0 /* colormap */
},
xcb_render_pictforminfo_type_t |
xcb_render_pictforminfo_depth_t |
xcb_render_pictforminfo_red_shift_t |
xcb_render_pictforminfo_red_mask_t |
xcb_render_pictforminfo_green_shift_t |
xcb_render_pictforminfo_green_mask_t |
xcb_render_pictforminfo_blue_shift_t |
xcb_render_pictforminfo_blue_mask_t |
xcb_render_pictforminfo_alpha_shift_t |
xcb_render_pictforminfo_alpha_mask_t
},
/* StandardPICTFORMINFORGB24 */
{
{
0, /* id */
XCB_RENDER_PICT_TYPE_DIRECT, /* type */
24, /* depth */
{ 0, 0 }, /* pad */
{ /* direct */
16, /* direct.red_shift */
0xff, /* direct.red_mask */
8, /* direct.green_shift */
0xff, /* direct.green_mask */
0, /* direct.blue_shift */
0xff, /* direct.blue_mask */
0, /* direct.alpha_shift */
0x00 /* direct.alpha_mask */
},
0 /* colormap */
},
xcb_render_pictforminfo_type_t |
xcb_render_pictforminfo_depth_t |
xcb_render_pictforminfo_red_shift_t |
xcb_render_pictforminfo_red_mask_t |
xcb_render_pictforminfo_green_shift_t |
xcb_render_pictforminfo_green_mask_t |
xcb_render_pictforminfo_blue_shift_t |
xcb_render_pictforminfo_blue_mask_t |
xcb_render_pictforminfo_alpha_mask_t
},
/* StandardPICTFORMINFOA8 */
{
{
0, /* id */
XCB_RENDER_PICT_TYPE_DIRECT, /* type */
8, /* depth */
{ 0, 0 }, /* pad */
{ /* direct */
0, /* direct.red_shift */
0x00, /* direct.red_mask */
0, /* direct.green_shift */
0x00, /* direct.green_mask */
0, /* direct.blue_shift */
0x00, /* direct.blue_mask */
0, /* direct.alpha_shift */
0xff /* direct.alpha_mask */
},
0 /* colormap */
},
xcb_render_pictforminfo_type_t |
xcb_render_pictforminfo_depth_t |
xcb_render_pictforminfo_red_mask_t |
xcb_render_pictforminfo_green_mask_t |
xcb_render_pictforminfo_blue_mask_t |
xcb_render_pictforminfo_alpha_shift_t |
xcb_render_pictforminfo_alpha_mask_t
},
/* StandardPICTFORMINFOA4 */
{
{
0, /* id */
XCB_RENDER_PICT_TYPE_DIRECT, /* type */
4, /* depth */
{ 0, 0 }, /* pad */
{ /* direct */
0, /* direct.red_shift */
0x00, /* direct.red_mask */
0, /* direct.green_shift */
0x00, /* direct.green_mask */
0, /* direct.blue_shift */
0x00, /* direct.blue_mask */
0, /* direct.alpha_shift */
0x0f /* direct.alpha_mask */
},
0 /* colormap */
},
xcb_render_pictforminfo_type_t |
xcb_render_pictforminfo_depth_t |
xcb_render_pictforminfo_red_mask_t |
xcb_render_pictforminfo_green_mask_t |
xcb_render_pictforminfo_blue_mask_t |
xcb_render_pictforminfo_alpha_shift_t |
xcb_render_pictforminfo_alpha_mask_t
},
/* StandardPICTFORMINFOA1 */
{
{
0, /* id */
XCB_RENDER_PICT_TYPE_DIRECT, /* type */
1, /* depth */
{ 0, 0 }, /* pad */
{ /* direct */
0, /* direct.red_shift */
0x00, /* direct.red_mask */
0, /* direct.green_shift */
0x00, /* direct.green_mask */
0, /* direct.blue_shift */
0x00, /* direct.blue_mask */
0, /* direct.alpha_shift */
0x01 /* direct.alpha_mask */
},
0 /* colormap */
},
xcb_render_pictforminfo_type_t |
xcb_render_pictforminfo_depth_t |
xcb_render_pictforminfo_red_mask_t |
xcb_render_pictforminfo_green_mask_t |
xcb_render_pictforminfo_blue_mask_t |
xcb_render_pictforminfo_alpha_shift_t |
xcb_render_pictforminfo_alpha_mask_t
},
};
if ((format >= 0) && (format < xcb_render_standard_pictforminfo_count_t))
forminfo = xcb_render_find_pictforminfo (conn,
standardFormats[format].mask,
&standardFormats[format].template,
0);
return forminfo;
}
static void
_tmp_xcb_err(xcb_connection_t *conn __UNUSED__/* , XErrorEvent *ev */)
{
_xcb_err = 1;
return;
}
Xcb_Image_Info *
_xr_image_info_get(xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *visual)
{
xcb_get_geometry_cookie_t cookie;
xcb_get_geometry_reply_t *rep;
Xcb_Image_Info *xcbinf;
Xcb_Image_Info *xcbinf2;
Eina_List *l;
xcbinf2 = NULL;
EINA_LIST_FOREACH(_image_info_list, l, xcbinf)
{
if (xcbinf->conn == conn)
{
xcbinf2 = xcbinf;
break;
}
}
xcbinf = calloc(1, sizeof(Xcb_Image_Info));
if (!xcbinf) return NULL;
xcbinf->references = 1;
xcbinf->conn = conn;
xcbinf->screen = screen;
xcbinf->draw = draw;
cookie = xcb_get_geometry_unchecked(xcbinf->conn, xcbinf->draw);
rep = xcb_get_geometry_reply(xcbinf->conn, cookie, NULL);
xcbinf->root = rep->root;
free(rep);
xcbinf->visual = visual;
xcbinf->fmt32 = xcb_render_find_standard_pictforminfo(xcbinf->conn, xcb_render_standard_pictforminfoargb_32_t);
xcbinf->fmt24 = xcb_render_find_standard_pictforminfo(xcbinf->conn, xcb_render_standard_pictforminforgb_24_t);
xcbinf->fmt8 = xcb_render_find_standard_pictforminfo(xcbinf->conn, xcb_render_standard_pictforminfoa_8_t);
xcbinf->fmt4 = xcb_render_find_standard_pictforminfo(xcbinf->conn, xcb_render_standard_pictforminfoa_4_t);
xcbinf->fmt1 = xcb_render_find_standard_pictforminfo(xcbinf->conn, xcb_render_standard_pictforminfoa_1_t);
xcbinf->mul = _xr_render_surface_new(xcbinf, 1, 1, xcbinf->fmt32, 1);
_xr_render_surface_repeat_set(xcbinf->mul, 1);
xcbinf->mul_r = xcbinf->mul_g = xcbinf->mul_b = xcbinf->mul_a = 0xff;
_xr_render_surface_solid_rectangle_set(xcbinf->mul, xcbinf->mul_r, xcbinf->mul_g, xcbinf->mul_b, xcbinf->mul_a, 0, 0, 1, 1);
if (xcbinf2)
{
xcbinf->can_do_shm = xcbinf2->can_do_shm;
xcbinf->depth = xcbinf2->depth;
}
else
{
xcb_depth_iterator_t iter_depth;
xcb_shm_segment_info_t shm_info;
xcb_image_t *xcbim;
iter_depth = xcb_screen_allowed_depths_iterator (xcbinf->screen);
for (; iter_depth.rem ; xcb_depth_next (&iter_depth))
{
xcb_visualtype_iterator_t iter_visual;
iter_visual = xcb_depth_visuals_iterator (iter_depth.data);
for (; iter_visual.rem ; xcb_visualtype_next (&iter_visual))
{
if (iter_visual.data->visual_id == visual->visual_id)
xcbinf->depth = iter_depth.data->depth;
}
}
xcbinf->can_do_shm = 0;
shm_info.shmseg = xcb_generate_id(xcbinf->conn);
xcbim = xcb_image_create_native(xcbinf->conn, 1, 1,
XCB_IMAGE_FORMAT_Z_PIXMAP,
xcbinf->depth, NULL, ~0, NULL);
if (xcbim) {
shm_info.shmid = shmget(IPC_PRIVATE, xcbim->size, IPC_CREAT | 0777);
if (shm_info.shmid >= 0) {
shm_info.shmaddr = xcbim->data = shmat(shm_info.shmid, 0, 0);
if ((shm_info.shmaddr != NULL) && (shm_info.shmaddr != (void *) -1)) {
xcb_get_input_focus_reply_t *reply;
/*
* FIXME: no error mechanism
*/
/* XErrorHandler ph; */
/* we sync */
reply = xcb_get_input_focus_reply(xcbinf->conn,
xcb_get_input_focus_unchecked(xcbinf->conn),
NULL);
free(reply);
_xcb_err = 0;
/* ph = XSetErrorHandler((XErrorHandler)_tmp_xcb_err); */
xcb_shm_attach(xcbinf->conn, shm_info.shmseg, shm_info.shmid, 0);
/* we sync */
reply = xcb_get_input_focus_reply(xcbinf->conn,
xcb_get_input_focus_unchecked(xcbinf->conn),
NULL);
free(reply);
/* XSetErrorHandler((XErrorHandler)ph); */
if (!_xcb_err) xcbinf->can_do_shm = 1;
shmdt(shm_info.shmaddr);
}
shmctl(shm_info.shmid, IPC_RMID, 0);
}
xcb_image_destroy(xcbim);
}
}
_image_info_list = eina_list_prepend(_image_info_list, xcbinf);
return xcbinf;
}
void
_xr_image_info_free(Xcb_Image_Info *xcbinf)
{
if (!xcbinf) return;
if (xcbinf->pool)
{
xcb_get_input_focus_reply_t *reply;
reply = xcb_get_input_focus_reply(xcbinf->conn,
xcb_get_input_focus_unchecked(xcbinf->conn),
NULL);
free(reply);
}
_xr_image_info_pool_flush(xcbinf, 0, 0);
xcbinf->references--;
if (xcbinf->references != 0) return;
_xr_render_surface_free(xcbinf->mul);
if (xcbinf->fmt1)
free(xcbinf->fmt1);
if (xcbinf->fmt4)
free(xcbinf->fmt4);
if (xcbinf->fmt8)
free(xcbinf->fmt8);
if (xcbinf->fmt24)
free(xcbinf->fmt24);
if (xcbinf->fmt32)
free(xcbinf->fmt32);
free(xcbinf);
_image_info_list = eina_list_remove(_image_info_list, xcbinf);
}
void
_xr_image_info_pool_flush(Xcb_Image_Info *xcbinf, int max_num, int max_mem)
{
if ((xcbinf->pool_mem <= max_mem) && (eina_list_count(xcbinf->pool) <= max_num)) return;
while ((xcbinf->pool_mem > max_mem) || (eina_list_count(xcbinf->pool) > max_num))
{
Xcb_Image_Image *xcbim;
if (!xcbinf->pool) break;
xcbim = xcbinf->pool->data;
_xr_image_free(xcbim);
}
}
Xcb_Image_Image *
_xr_image_new(Xcb_Image_Info *xcbinf, int w, int h, int depth)
{
Xcb_Image_Image *xcbim, *xcbim2;
Eina_List *l;
xcbim2 = NULL;
EINA_LIST_FOREACH(xcbinf->pool, l, xcbim)
{
if ((xcbim->w >= w) && (xcbim->h >= h) && (xcbim->depth == depth) && (xcbim->available))
{
if (!xcbim2) xcbim2 = xcbim;
else if ((xcbim->w * xcbim->h) < (xcbim2->w * xcbim2->h)) xcbim2 = xcbim;
}
}
if (xcbim2)
{
xcbim2->available = 0;
return xcbim2;
}
xcbim = calloc(1, sizeof(Xcb_Image_Image));
if (xcbim)
{
xcbim->xcbinf = xcbinf;
xcbim->w = w;
xcbim->h = h;
xcbim->depth = depth;
xcbim->available = 0;
if (xcbim->xcbinf->can_do_shm)
{
xcbim->shm_info = calloc(1, sizeof(xcb_shm_segment_info_t));
if (xcbim->shm_info)
{
xcbim->shm_info->shmseg = xcb_generate_id(xcbinf->conn);
xcbim->xcbim = xcb_image_create_native(xcbim->xcbinf->conn, xcbim->w, xcbim->h, XCB_IMAGE_FORMAT_Z_PIXMAP, xcbim->depth, NULL, ~0, NULL);
if (xcbim->xcbim)
{
xcbim->shm_info->shmid = shmget(IPC_PRIVATE, xcbim->xcbim->size, IPC_CREAT | 0777);
if (xcbim->shm_info->shmid >= 0)
{
xcbim->shm_info->shmaddr = xcbim->xcbim->data = shmat(xcbim->shm_info->shmid, 0, 0);
if ((xcbim->shm_info->shmaddr) && (xcbim->shm_info->shmaddr != (void *) -1))
{
xcb_get_input_focus_reply_t *reply;
/*
* FIXME: no error mechanism
*/
/* XErrorHandler ph; */
/* we sync */
reply = xcb_get_input_focus_reply(xcbim->xcbinf->conn,
xcb_get_input_focus_unchecked(xcbim->xcbinf->conn),
NULL);
free(reply);
_xcb_err = 0;
/* ph = XSetErrorHandler((XErrorHandler)_tmp_xcb_err); */
xcb_shm_attach(xcbim->xcbinf->conn, xcbim->shm_info->shmseg, xcbim->shm_info->shmid, 0);
/* we sync */
reply = xcb_get_input_focus_reply(xcbim->xcbinf->conn,
xcb_get_input_focus_unchecked(xcbim->xcbinf->conn),
NULL);
free(reply);
/* XSetErrorHandler((XErrorHandler)ph); */
if (!_xcb_err) goto xcbim_ok;
shmdt(xcbim->shm_info->shmaddr);
}
shmctl(xcbim->shm_info->shmid, IPC_RMID, 0);
}
xcb_image_destroy(xcbim->xcbim);
}
free(xcbim->shm_info);
xcbim->shm_info = NULL;
}
}
xcbim->xcbim = xcb_image_create_native(xcbim->xcbinf->conn, xcbim->w, xcbim->h, XCB_IMAGE_FORMAT_Z_PIXMAP, xcbim->depth, NULL, ~0, NULL);
if (!xcbim->xcbim)
{
free(xcbim);
return NULL;
}
xcbim->xcbim->data = malloc(xcbim->xcbim->size);
if (!xcbim->xcbim->data)
{
xcb_image_destroy(xcbim->xcbim);
free(xcbim);
return NULL;
}
}
xcbim_ok:
_xr_image_info_pool_flush(xcbinf, 32, (1600 * 1200 * 32 * 2));
xcbim->line_bytes = xcbim->xcbim->stride;
xcbim->data = (void *)(xcbim->xcbim->data);
xcbinf->pool_mem += (xcbim->w * xcbim->h * xcbim->depth);
xcbinf->pool = eina_list_append(xcbinf->pool, xcbim);
return xcbim;
}
void
_xr_image_free(Xcb_Image_Image *xcbim)
{
if (xcbim->shm_info)
{
if (!xcbim->available)
{
xcb_get_input_focus_reply_t *reply;
reply = xcb_get_input_focus_reply(xcbim->xcbinf->conn,
xcb_get_input_focus_unchecked(xcbim->xcbinf->conn),
NULL);
free(reply);
}
xcb_shm_detach(xcbim->xcbinf->conn, xcbim->shm_info->shmseg);
xcb_image_destroy(xcbim->xcbim);
shmdt(xcbim->shm_info->shmaddr);
shmctl(xcbim->shm_info->shmid, IPC_RMID, 0);
free(xcbim->shm_info);
}
else
{
free(xcbim->xcbim->data);
xcbim->xcbim->data = NULL;
xcb_image_destroy(xcbim->xcbim);
}
xcbim->xcbinf->pool_mem -= (xcbim->w * xcbim->h * xcbim->depth);
xcbim->xcbinf->pool = eina_list_remove(xcbim->xcbinf->pool, xcbim);
free(xcbim);
}
void
_xr_image_put(Xcb_Image_Image *xcbim, xcb_drawable_t draw, int x, int y, int w, int h)
{
xcb_get_input_focus_reply_t *reply;
xcb_gcontext_t gc;
gc = xcb_generate_id(xcbim->xcbinf->conn);
xcb_create_gc(xcbim->xcbinf->conn, gc, draw, 0, NULL);
if (xcbim->shm_info)
{
xcb_shm_put_image(xcbim->xcbinf->conn, draw, gc,
xcbim->xcbim->width, xcbim->xcbim->height,
0, 0,
w, h,
x, y,
xcbim->xcbim->depth, xcbim->xcbim->format,
0,
xcbim->shm_info->shmseg,
xcbim->xcbim->data - xcbim->shm_info->shmaddr);
/* we sync */
reply = xcb_get_input_focus_reply(xcbim->xcbinf->conn,
xcb_get_input_focus_unchecked(xcbim->xcbinf->conn),
NULL);
free(reply);
}
else
xcb_image_put(xcbim->xcbinf->conn, draw, gc, xcbim->xcbim, x, y, 0);
xcbim->available = 1;
xcb_free_gc(xcbim->xcbinf->conn, gc);
}

View File

@ -1,844 +0,0 @@
/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "evas_common.h"
/* #include "evas_macros.h" */
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_Xcb.h"
#include <math.h>
/* As opposed to libXRender, we don't have
* XDoubleToFixed in XCB :/
*/
#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536))
/* this is a work around broken xrender - when/if this ever gets fixed in xorg
* we can comment this out and one day remove it - for now keep it until such
* a fix is spotted in the wild
*/
#define BROKEN_XORG_XRENDER 1
static inline void
set_filter(Xcb_Render_Surface *s, int smooth)
{
const char *f = smooth ? "best": "nearest";
xcb_render_set_picture_filter (s->xcbinf->conn, s->pic, strlen (f), f, 0, NULL);
}
xcb_render_pictforminfo_t *
xcb_render_find_visual_format (xcb_connection_t *c, xcb_visualtype_t *visual)
{
xcb_render_query_pict_formats_cookie_t cookie;
xcb_render_query_pict_formats_reply_t *rep;
xcb_render_pictscreen_iterator_t screen_iter;
xcb_render_pictformat_t format = { 0 };
cookie = xcb_render_query_pict_formats (c);
rep = xcb_render_query_pict_formats_reply (c, cookie, NULL);
if (!rep)
return NULL;
screen_iter = xcb_render_query_pict_formats_screens_iterator (rep);
for (; screen_iter.rem; xcb_render_pictscreen_next (&screen_iter)) {
xcb_render_pictdepth_iterator_t depth_iter;
depth_iter = xcb_render_pictscreen_depths_iterator (screen_iter.data);
for (; depth_iter.rem; xcb_render_pictdepth_next (&depth_iter)) {
xcb_render_pictvisual_iterator_t visual_iter;
visual_iter = xcb_render_pictdepth_visuals_iterator (depth_iter.data);
for (; visual_iter.rem; xcb_render_pictvisual_next (&visual_iter)) {
if (visual->visual_id == visual_iter.data->visual) {
format = visual_iter.data->format;
}
}
}
}
if (format != 0)
{
xcb_render_pictforminfo_iterator_t forminfo_iter;
forminfo_iter = xcb_render_query_pict_formats_formats_iterator (rep);
for (; forminfo_iter.rem; xcb_render_pictforminfo_next (&forminfo_iter)) {
if (forminfo_iter.data->id == format) {
xcb_render_pictforminfo_t *forminfo;
forminfo = (xcb_render_pictforminfo_t *)malloc (sizeof (xcb_render_pictforminfo_t));
memcpy (forminfo, forminfo_iter.data, sizeof (xcb_render_pictforminfo_t));
free (rep);
return forminfo;
}
}
}
return NULL;
}
Xcb_Render_Surface *
_xr_render_surface_new(Xcb_Image_Info *xcbinf, int w, int h, xcb_render_pictforminfo_t *fmt, int alpha)
{
Xcb_Render_Surface *rs;
uint32_t mask;
uint32_t values[3];
if ((!xcbinf) || (!fmt) || (w < 1) || (h < 1)) return NULL;
rs = calloc(1, sizeof(Xcb_Render_Surface));
if (!rs) return NULL;
rs->xcbinf = xcbinf;
rs->w = w;
rs->h = h;
rs->fmt = (xcb_render_pictforminfo_t *)malloc (sizeof (xcb_render_pictforminfo_t));
if (!rs->fmt)
{
free(rs);
return NULL;
}
memcpy (rs->fmt, fmt, sizeof (xcb_render_pictforminfo_t));
rs->alpha = alpha;
rs->depth = fmt->depth;
rs->allocated = 1;
rs->draw = xcb_generate_id(xcbinf->conn);
xcb_create_pixmap(xcbinf->conn, fmt->depth, rs->draw, xcbinf->root, w, h);
if (rs->draw == XCB_NONE)
{
free(rs->fmt);
free(rs);
return NULL;
}
rs->xcbinf->references++;
mask = XCB_RENDER_CP_REPEAT | XCB_RENDER_CP_DITHER | XCB_RENDER_CP_COMPONENT_ALPHA;
values[0] = 0;
values[1] = 1;
values[2] = 0;
rs->pic = xcb_generate_id(xcbinf->conn);
xcb_render_create_picture(xcbinf->conn, rs->pic, rs->draw, fmt->id, mask, values);
if (rs->pic == XCB_NONE)
{
xcb_free_pixmap(rs->xcbinf->conn, rs->draw);
rs->xcbinf->references--;
free(rs->fmt);
free(rs);
return NULL;
}
return rs;
}
Xcb_Render_Surface *
_xr_render_surface_adopt(Xcb_Image_Info *xcbinf, xcb_drawable_t draw, int w, int h, int alpha)
{
Xcb_Render_Surface *rs;
uint32_t mask;
uint32_t values[3];
if ((!xcbinf) || (draw == 0) || (w < 1) || (h < 1)) return NULL;
rs = calloc(1, sizeof(Xcb_Render_Surface));
if (!rs) return NULL;
rs->xcbinf = xcbinf;
rs->w = w;
rs->h = h;
/* if (fmt->depth == xcbinf->fmt32->depth) */
/* rs->fmt = xcbinf->fmt32; */
/* else if (fmt->depth == xcbinf->fmt24->depth) */
/* rs->fmt = xcbinf->fmt24; */
/* else if (fmt->depth == xcbinf->fmt8->depth) */
/* rs->fmt = xcbinf->fmt8; */
/* else if (fmt->depth == xcbinf->fmt4->depth) */
/* rs->fmt = xcbinf->fmt4; */
/* else */
/* rs->fmt = xcbinf->fmt1; */
/* free(fmt); */
rs->fmt = xcb_render_find_visual_format(xcbinf->conn, xcbinf->visual);
if (!rs->fmt)
{
free(rs);
return NULL;
}
rs->alpha = alpha;
rs->depth = rs->fmt->depth;
if (rs->fmt->depth == 32) rs->alpha = 1;
rs->allocated = 0;
rs->draw = draw;
rs->xcbinf->references++;
mask = XCB_RENDER_CP_REPEAT | XCB_RENDER_CP_DITHER | XCB_RENDER_CP_COMPONENT_ALPHA;
values[0] = 0;
values[1] = 1;
values[2] = 0;
rs->pic = xcb_generate_id(xcbinf->conn);
xcb_render_create_picture(xcbinf->conn, rs->pic, rs->draw, rs->fmt->id, mask, values);
if (rs->pic == XCB_NONE)
{
rs->xcbinf->references--;
free(rs->fmt);
free(rs);
return NULL;
}
return rs;
}
Xcb_Render_Surface *
_xr_render_surface_format_adopt(Xcb_Image_Info *xcbinf, xcb_drawable_t draw, int w, int h, xcb_render_pictforminfo_t *fmt, int alpha)
{
Xcb_Render_Surface *rs;
uint32_t mask;
uint32_t values[3];
if ((!xcbinf) || (!fmt) || (draw == XCB_NONE) || (w < 1) || (h < 1)) return NULL;
rs = calloc(1, sizeof(Xcb_Render_Surface));
if (!rs) return NULL;
rs->xcbinf = xcbinf;
rs->w = w;
rs->h = h;
rs->fmt = (xcb_render_pictforminfo_t *)malloc (sizeof (xcb_render_pictforminfo_t));
memcpy (rs->fmt, fmt, sizeof (xcb_render_pictforminfo_t));
rs->alpha = alpha;
rs->depth = fmt->depth;
if (fmt->depth == 32) rs->alpha = 1;
rs->xcbinf->references++;
rs->allocated = 0;
rs->draw = draw;
mask = XCB_RENDER_CP_REPEAT | XCB_RENDER_CP_DITHER | XCB_RENDER_CP_COMPONENT_ALPHA;
values[0] = 0;
values[1] = 1;
values[2] = 0;
rs->pic = xcb_generate_id(xcbinf->conn);
xcb_render_create_picture(xcbinf->conn, rs->pic, rs->draw, fmt->id, mask, values);
if (rs->pic == XCB_NONE)
{
rs->xcbinf->references--;
free(rs->fmt);
free(rs);
return NULL;
}
return rs;
}
void
_xr_render_surface_free(Xcb_Render_Surface *rs)
{
if (!rs) return;
if (rs->xcbinf)
{
if ((rs->allocated) && (rs->draw != XCB_NONE))
xcb_free_pixmap(rs->xcbinf->conn, rs->draw);
if (rs->pic != XCB_NONE)
xcb_render_free_picture(rs->xcbinf->conn, rs->pic);
_xr_image_info_free(rs->xcbinf);
rs->xcbinf = NULL;
}
free(rs->fmt);
free(rs);
}
void
_xr_render_surface_repeat_set(Xcb_Render_Surface *rs, int repeat)
{
uint32_t mask;
uint32_t value[1];
mask = XCB_RENDER_CP_REPEAT;
value[0] = repeat;
xcb_render_change_picture(rs->xcbinf->conn, rs->pic, mask, value);
}
void
_xr_render_surface_solid_rectangle_set(Xcb_Render_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h)
{
xcb_render_color_t col;
xcb_rectangle_t rect;
col.red = (r << 8) | r;
col.green = (g << 8) | g;
col.blue = (b << 8) | b;
col.alpha = (a << 8) | a;
rect.x = x;
rect.y = y;
rect.width = w;
rect.height = h;
xcb_render_fill_rectangles(rs->xcbinf->conn, XCB_RENDER_PICT_OP_SRC, rs->pic, col, 1, &rect);
}
void
_xr_render_surface_argb_pixels_fill(Xcb_Render_Surface *rs, int sw, int sh __UNUSED__, void *pixels, int x, int y, int w, int h, int ox, int oy)
{
Xcb_Image_Image *xcbim;
unsigned int *p, *sp, *sple, *spe;
unsigned int jump, sjump;
xcbim = _xr_image_new(rs->xcbinf, w, h, rs->depth);
if (!xcbim) return;
p = (unsigned int *)xcbim->data;
sp = ((unsigned int *)pixels) + (y * sw) + x;
jump = ((xcbim->line_bytes / 4) - w);
sjump = sw - w;
spe = sp + ((h - 1) * sw) + w;
if
#ifdef WORDS_BIGENDIAN
(xcbim->xcbim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST)
#else
(xcbim->xcbim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
#endif
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
{
*p++ = (*sp << 24) + ((*sp << 8) & 0xff0000) + ((*sp >> 8) & 0xff00) + (*sp >> 24);
// *p++ = (B_VAL(sp) << 24) | (G_VAL(sp) << 16) | (R_VAL(sp) << 8) | A_VAL(sp);
sp++;
}
p += jump;
sp += sjump;
}
}
else
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
*p++ = *sp++;
p += jump;
sp += sjump;
}
}
_xr_image_put(xcbim, rs->draw, x + ox, y + oy, w, h);
}
void
_xr_render_surface_rgb_pixels_fill(Xcb_Render_Surface *rs, int sw, int sh __UNUSED__, void *pixels, int x, int y, int w, int h, int ox, int oy)
{
Xcb_Image_Image *xcbim;
unsigned int *p, *sp, *sple, *spe;
unsigned int jump, sjump;
xcbim = _xr_image_new(rs->xcbinf, w, h, rs->depth);
if (!xcbim) return;
p = (unsigned int *)xcbim->data;
sp = ((unsigned int *)pixels) + (y * sw) + x;
sjump = sw - w;
spe = sp + ((h - 1) * sw) + w;
if (rs->depth == 16)
{
/* FIXME: if rs->depth == 16 - convert */
Gfx_Func_Convert conv_func;
int swap;
jump = ((xcbim->line_bytes / 2) - w);
#ifdef WORDS_BIGENDIAN
swap = (int)(xcbim->xcbim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST);
#else
swap = (int)(xcbim->xcbim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST);
#endif
/* FIXME: swap not handled */
conv_func = evas_common_convert_func_get(sp, w, h, rs->depth,
rs->xcbinf->visual->red_mask,
rs->xcbinf->visual->green_mask,
rs->xcbinf->visual->blue_mask,
PAL_MODE_NONE, 0);
if (conv_func)
conv_func(sp, p, sjump, jump, w, h, x, y, NULL);
}
else
{
jump = ((xcbim->line_bytes / 4) - w);
if
#ifdef WORDS_BIGENDIAN
(xcbim->xcbim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST)
#else
(xcbim->xcbim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
#endif
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
{
*p++ = (*sp << 24) + ((*sp << 8) & 0xff0000) + ((*sp >> 8) & 0xff00) + 0xff;
// *p++ = ((B_VAL(sp)) << 24) | ((G_VAL(sp)) << 16) | ((R_VAL(sp)) << 8) | 0x000000ff;
sp++;
}
p += jump;
sp += sjump;
}
}
else
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
*p++ = 0xff000000 | *sp++;
p += jump;
sp += sjump;
}
}
}
_xr_image_put(xcbim, rs->draw, x + ox, y + oy, w, h);
}
void
_xr_render_surface_clips_set(Xcb_Render_Surface *rs, RGBA_Draw_Context *dc, int rx, int ry, int rw, int rh)
{
int num = 0;
xcb_rectangle_t *rect = NULL;
if ((dc) && (dc->clip.use))
{
RECTS_CLIP_TO_RECT(rx, ry, rw, rh,
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
}
if ((!dc) || (!dc->cutout.rects))
{
rect = malloc(sizeof(xcb_rectangle_t));
if (!rect) return;
rect->x = rx;
rect->y = ry;
rect->width = rw;
rect->height = rh;
num = 1;
}
else
{
Cutout_Rects *rects;
Cutout_Rect *r;
int i;
rects = evas_common_draw_context_apply_cutouts(dc);
num = rects->active;
rect = malloc(num * sizeof(xcb_rectangle_t));
if (!rect) return;
for (i = 0; i < num; i++)
{
r = rects->rects + i;
rect[i].x = r->x;
rect[i].y = r->y;
rect[i].width = r->w;
rect[i].height = r->h;
}
evas_common_draw_context_apply_clear_cutouts(rects);
}
if (!rect) return;
xcb_render_set_picture_clip_rectangles(rs->xcbinf->conn, rs->pic, 0, 0, num, rect);
free(rect);
}
/* initialized the transform to the identity */
static void
init_transform (xcb_render_transform_t *t)
{
t->matrix11 = t->matrix22 = t->matrix33 = DOUBLE_TO_FIXED(1);
t->matrix12 = t->matrix13 = t->matrix21 = t->matrix23 =
t->matrix31 = t->matrix32 = 0;
}
static void
set_transform_scale(xcb_render_transform_t *t,
int sw,
int sh,
int w,
int h,
int tx,
int ty)
{
/* if ((sw > 1) && (w > 1)) */
/* { sw--; w--; } */
/* if ((sh > 1) && (h > 1)) */
/* { sh--; h--; } */
t->matrix11 = DOUBLE_TO_FIXED((double)sw / (double)w);
t->matrix22 = DOUBLE_TO_FIXED((double)sh / (double)h);
t->matrix31 = (tx * sw) / w;
t->matrix32 = (ty * sh) / h;
}
// when color multiplier is used want: instead
// CA src IN mask SRC temp; non-CA temp OVER dst. - i think. need to check.
void
_xr_render_surface_composite(Xcb_Render_Surface *srs,
Xcb_Render_Surface *drs,
RGBA_Draw_Context *dc,
int sx,
int sy,
int sw,
int sh,
int x,
int y,
int w,
int h,
int smooth)
{
Xcb_Render_Surface *trs = NULL;
xcb_render_transform_t xf;
xcb_render_picture_t mask = XCB_NONE;
uint32_t value_mask;
uint32_t value_list[1];
int e, is_scaling;
xcb_render_pict_op_t op;
if ((sw <= 0) || (sh <= 0) || (w <= 0) || (h <= 0)) return;
is_scaling = e = (sw != w) || (sh != h);
value_mask = XCB_RENDER_CP_CLIP_MASK;
value_list[0] = 0;
xcb_render_change_picture(srs->xcbinf->conn, srs->pic, value_mask, value_list);
xcb_render_change_picture(drs->xcbinf->conn, drs->pic, value_mask, value_list);
init_transform(&xf);
op = XCB_RENDER_PICT_OP_OVER;
if (dc->render_op == _EVAS_RENDER_BLEND)
{
if (!srs->alpha) op = XCB_RENDER_PICT_OP_SRC;
}
else if (dc->render_op == _EVAS_RENDER_BLEND_REL)
op = XCB_RENDER_PICT_OP_ATOP;
else if (dc->render_op == _EVAS_RENDER_MUL)
op = XCB_RENDER_PICT_OP_IN;
else if (dc->render_op == _EVAS_RENDER_COPY)
op = XCB_RENDER_PICT_OP_SRC;
else if (dc->render_op == _EVAS_RENDER_COPY_REL)
op = XCB_RENDER_PICT_OP_IN;
else if (dc->render_op == _EVAS_RENDER_MASK)
op = XCB_RENDER_PICT_OP_IN_REVERSE;
if ((dc) && (dc->mul.use))
{
int r, g, b, a;
if ((op == XCB_RENDER_PICT_OP_OVER) && (!dc->mul.col)) return;
a = dc->mul.col >> 24;
r = (dc->mul.col >> 16) & 0xff;
g = (dc->mul.col >> 8) & 0xff;
b = dc->mul.col & 0xff;
if (dc->mul.col != 0xffffffff)
{
if ((srs->xcbinf->mul_r != r) || (srs->xcbinf->mul_g != g) ||
(srs->xcbinf->mul_b != b) || (srs->xcbinf->mul_a != a))
{
srs->xcbinf->mul_r = r;
srs->xcbinf->mul_g = g;
srs->xcbinf->mul_b = b;
srs->xcbinf->mul_a = a;
_xr_render_surface_solid_rectangle_set(srs->xcbinf->mul,
r,
g,
b,
a,
0, 0, 1, 1);
}
mask = srs->xcbinf->mul->pic;
if (dc->mul.col == (a * 0x01010101))
{
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 0;
xcb_render_change_picture(srs->xcbinf->conn, mask, value_mask, value_list);
}
else
{
if ((srs->alpha) || (a != 0xff))
trs = _xr_render_surface_new(srs->xcbinf, sw + 2, sh + 2,
srs->xcbinf->fmt32, 1);
else
trs = _xr_render_surface_new(srs->xcbinf, sw + 2, sh + 2,
srs->fmt, srs->alpha);
if (!trs) return;
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 1;
xcb_render_change_picture(srs->xcbinf->conn, mask, value_mask, value_list);
xcb_render_set_picture_transform(trs->xcbinf->conn, srs->pic, xf);
xcb_render_composite(srs->xcbinf->conn, XCB_RENDER_PICT_OP_SRC, srs->pic, mask, trs->pic,
sx, sy, sx, sy, 0, 0, sw + 2, sh + 2);
mask = XCB_NONE;
}
}
}
//#define HFW + (sw / 2)
//#define HFH + (sh / 2)
#define HFW
#define HFH
_xr_render_surface_clips_set(drs, dc, x, y, w, h);
if (trs)
{
set_filter(trs, smooth);
set_transform_scale(&xf, sw, sh, w, h, -1, -1);
xcb_render_set_picture_transform(trs->xcbinf->conn, trs->pic, xf);
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 0;
if (dc->render_op == _EVAS_RENDER_MUL)
value_list[0] = 1;
xcb_render_change_picture(trs->xcbinf->conn, trs->pic, value_mask, value_list);
xcb_render_composite(trs->xcbinf->conn, op, trs->pic, mask, drs->pic,
(w HFW) / sw, (h HFH) / sh,
(w HFW) / sw, (h HFH) / sh,
x, y, w, h);
_xr_render_surface_free(trs);
}
else
{
if (srs->bordered && is_scaling)
{
trs = _xr_render_surface_new(srs->xcbinf, sw + 2, sh + 2,
srs->fmt, srs->alpha);
if (!trs) return;
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 0;
xcb_render_change_picture(srs->xcbinf->conn, srs->pic, value_mask, value_list);
xcb_render_set_picture_transform(srs->xcbinf->conn, srs->pic, xf);
xcb_render_composite(srs->xcbinf->conn, XCB_RENDER_PICT_OP_SRC, srs->pic, XCB_NONE, trs->pic,
sx, sy, sx, sx, 0, 0, sw + 2, sh + 2);
set_filter(trs, smooth);
set_transform_scale(&xf, sw, sh, w, h, -1, -1);
xcb_render_set_picture_transform(trs->xcbinf->conn, trs->pic, xf);
if (dc->render_op == _EVAS_RENDER_MUL)
{
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 1;
xcb_render_change_picture(trs->xcbinf->conn, trs->pic, value_mask, value_list);
}
xcb_render_composite(trs->xcbinf->conn, op, trs->pic, mask, drs->pic,
(w HFW) / sw, (h HFH) / sh,
(w HFW) / sw, (h HFH) / sh,
x, y, w, h);
_xr_render_surface_free(trs);
}
else
{
set_filter(srs, smooth);
set_transform_scale(&xf, sw, sh, w, h, 0, 0);
xcb_render_set_picture_transform(srs->xcbinf->conn, srs->pic, xf);
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 0;
if (dc->render_op == _EVAS_RENDER_MUL)
value_list[0] = 1;
xcb_render_change_picture(srs->xcbinf->conn, srs->pic, value_mask, value_list);
xcb_render_composite(srs->xcbinf->conn, op, srs->pic, mask, drs->pic,
((((sx + 1) * w) HFW) / sw),
((((sy + 1) * h) HFH) / sh),
((((sx + 1) * w) HFW) / sw),
((((sy + 1) * h) HFH) / sh),
x, y, w, h);
}
}
}
void
_xr_render_surface_copy(Xcb_Render_Surface *srs, Xcb_Render_Surface *drs, int sx, int sy, int x, int y, int w, int h)
{
xcb_render_transform_t xf;
uint32_t value_mask;
uint32_t value_list[1];
if ((w <= 0) || (h <= 0) || (!srs) || (!drs)) return;
init_transform(&xf);
#ifdef BROKEN_XORG_XRENDER
/* FIXME: why do we need to change the identity matrix if the src surface
* is 1 bit deep?
*/
if (srs->depth == 1)
{
xf.matrix11 = xf.matrix22 = xf.matrix33 = 1;
}
#endif
xcb_render_set_picture_transform(srs->xcbinf->conn, srs->pic, xf);
/* set_filter(srs, 0); */
value_mask = XCB_RENDER_CP_CLIP_MASK;
value_list[0] = 0;
xcb_render_change_picture(srs->xcbinf->conn, srs->pic, value_mask, value_list);
xcb_render_change_picture(drs->xcbinf->conn, drs->pic, value_mask, value_list);
xcb_render_composite(srs->xcbinf->conn, XCB_RENDER_PICT_OP_SRC, srs->pic, XCB_NONE, drs->pic,
sx, sy, 0, 0, x, y, w, h);
}
void
_xr_render_surface_rectangle_draw(Xcb_Render_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h)
{
xcb_render_color_t col;
xcb_rectangle_t rect;
uint32_t value_mask;
uint32_t value_list;
int r, g, b, a;
xcb_render_pict_op_t op;
if ((!rs) || (!dc)) return;
if ((w <= 0) || (h <= 0)) return;
a = dc->col.col >> 24;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
col.red = (r << 8) | r;
col.green = (g << 8) | g;
col.blue = (b << 8) | b;
col.alpha = (a << 8) | a;
op = XCB_RENDER_PICT_OP_SRC;
if (dc->render_op == _EVAS_RENDER_BLEND)
{
if (!dc->col.col) return;
if (a == 0xff) op = XCB_RENDER_PICT_OP_SRC;
}
else if (dc->render_op == _EVAS_RENDER_BLEND_REL)
{
if (!dc->col.col) return;
op = XCB_RENDER_PICT_OP_ATOP;
}
else if (dc->render_op == _EVAS_RENDER_MUL)
{
if (dc->col.col == 0xffffffff) return;
op = XCB_RENDER_PICT_OP_IN;
}
else if (dc->render_op == _EVAS_RENDER_COPY)
op = XCB_RENDER_PICT_OP_SRC;
else if (dc->render_op == _EVAS_RENDER_COPY_REL)
op = XCB_RENDER_PICT_OP_IN;
else if (dc->render_op == _EVAS_RENDER_MASK)
op = XCB_RENDER_PICT_OP_IN_REVERSE;
value_mask = XCB_RENDER_CP_CLIP_MASK;
value_list = 0;
xcb_render_change_picture(rs->xcbinf->conn, rs->pic, value_mask, &value_list);
_xr_render_surface_clips_set(rs, dc, x, y, w, h);
rect.x = x;
rect.y = y;
rect.width = w;
rect.height = h;
xcb_render_fill_rectangles(rs->xcbinf->conn, op, rs->pic, col, 1, &rect);
}
void
_xr_render_surface_line_draw(Xcb_Render_Surface *rs __UNUSED__, RGBA_Draw_Context *dc __UNUSED__, int x1 __UNUSED__, int y1 __UNUSED__, int x2 __UNUSED__, int y2 __UNUSED__)
{
/* uint32_t value_mask; */
/* uint32_t value_list[1]; */
/* int op; */
/* if ((!rs) || (!dc)) return; */
/* op = XCB_RENDER_PICT_OP_SRC; */
/* value_mask = XCB_RENDER_CP_CLIP_MASK; */
/* value_list[0] = 0; */
/* xcb_render_change_picture(rs->xcbinf->conn, rs->pic, value_mask, value_list); */
/* _xr_render_surface_clips_set(rs, dc, 0, 0, rs->w, rs->h); */
/* { */
/* int r, g, b, a; */
/* XPointDouble poly[4]; */
/* int dx, dy; */
/* double len, ddx, ddy; */
/* dx = x2 - x1; */
/* dy = y2 - y1; */
/* len = sqrt((double)(dx * dx) + (double)(dy * dy)); */
/* ddx = (0.5 * dx) / len; */
/* ddy = (0.5 * dy) / len; */
/* poly[0].x = (x1 + ddx); */
/* poly[0].y = (y1 - ddy); */
/* poly[1].x = (x2 + ddx); */
/* poly[1].y = (y2 - ddy); */
/* poly[2].x = (x2 - ddx); */
/* poly[2].y = (y2 + ddy); */
/* poly[3].x = (x1 - ddx); */
/* poly[3].y = (y1 + ddy); */
/* a = (dc->col.col >> 24) & 0xff; */
/* if (a == 0) return; */
/* if (a < 0xff) op = XCB_RENDER_PICT_OP_OVER; */
/* r = (dc->col.col >> 16) & 0xff; */
/* g = (dc->col.col >> 8 ) & 0xff; */
/* b = (dc->col.col ) & 0xff; */
/* if ((rs->xcbinf->mul_r != r) || (rs->xcbinf->mul_g != g) || */
/* (rs->xcbinf->mul_b != b) || (rs->xcbinf->mul_a != a)) */
/* { */
/* rs->xcbinf->mul_r = r; */
/* rs->xcbinf->mul_g = g; */
/* rs->xcbinf->mul_b = b; */
/* rs->xcbinf->mul_a = a; */
/* _xr_render_surface_solid_rectangle_set(rs->xcbinf->mul, r, g, b, a, 0, 0, 1, 1); */
/* } */
/* XRenderCompositeDoublePoly(rs->xcbinf->conn, op, */
/* rs->xcbinf->mul->pic, rs->pic, */
/* rs->xcbinf->fmt8, 0, 0, 0, 0, */
/* poly, 4, EvenOddRule); */
/* } */
}
void
_xre_poly_draw(Xcb_Render_Surface *rs __UNUSED__, RGBA_Draw_Context *dc __UNUSED__, RGBA_Polygon_Point *points __UNUSED__)
{
/* RGBA_Polygon_Point *pt; */
/* int i, num; */
/* XPointDouble *pts; */
/* int r, g, b, a; */
/* uint32_t value_mask; */
/* uint32_t value_list[1]; */
/* int op; */
/* if ((!rs) || (!dc)) return; */
/* num = 0; EINA_INLIST_FOREACH(points, pt) num++; */
/* if (num < 3) return; */
/* a = (dc->col.col >> 24) & 0xff; */
/* if (a == 0) return; */
/* op = XCB_RENDER_PICT_OP_OVER; */
/* r = (dc->col.col >> 16) & 0xff; */
/* g = (dc->col.col >> 8 ) & 0xff; */
/* b = (dc->col.col ) & 0xff; */
/* if ((rs->xcbinf->mul_r != r) || (rs->xcbinf->mul_g != g) || */
/* (rs->xcbinf->mul_b != b) || (rs->xcbinf->mul_a != a)) */
/* { */
/* rs->xcbinf->mul_r = r; */
/* rs->xcbinf->mul_g = g; */
/* rs->xcbinf->mul_b = b; */
/* rs->xcbinf->mul_a = a; */
/* _xr_render_surface_solid_rectangle_set(rs->xcbinf->mul, r, g, b, a, 0, 0, 1, 1); */
/* } */
/* pts = malloc(num * sizeof(XPointDouble)); */
/* if (!pts) return; */
/* i = 0; */
/* EINA_INLIST_FOREACH(points, pt) */
/* { */
/* if (i < num) */
/* { */
/* pts[i].x = pt->x; */
/* pts[i].y = pt->y; */
/* i++; */
/* } */
/* } */
/* value_mask = XCB_RENDER_CP_CLIP_MASK; */
/* value_list[0] = 0; */
/* xcb_render_change_picture(rs->xcbinf->conn, rs->pic, value_mask, value_list); */
/* _xr_render_surface_clips_set(rs, dc, 0, 0, rs->w, rs->h); */
/* XRenderCompositeDoublePoly(rs->xcbinf->conn, op, */
/* rs->xcbinf->mul->pic, rs->pic, */
/* rs->xcbinf->fmt8, 0, 0, 0, 0, */
/* pts, num, Complex); */
/* free(pts); */
}