largepixmap: Implement infrastructure for large pixmap.
Added infrastructure for largepixmap, this commit implemented: 1. Create/Destroy large pixmap. 2. Upload/Download large pixmap. 3. Implement basic repeat normal support. 3. tile/fill/copyarea large pixmap get supported. The most complicated part glamor_composite still not implemented. Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
parent
ace35e408c
commit
e96ea02010
|
@ -42,6 +42,7 @@ libglamor_la_SOURCES = \
|
||||||
glamor_glyphblt.c\
|
glamor_glyphblt.c\
|
||||||
glamor_polyops.c\
|
glamor_polyops.c\
|
||||||
glamor_pixmap.c\
|
glamor_pixmap.c\
|
||||||
|
glamor_largepixmap.c\
|
||||||
glamor_picture.c\
|
glamor_picture.c\
|
||||||
glamor_window.c\
|
glamor_window.c\
|
||||||
glamor_gl_dispatch.c\
|
glamor_gl_dispatch.c\
|
||||||
|
|
|
@ -141,9 +141,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
|
||||||
if (w > 32767 || h > 32767)
|
if (w > 32767 || h > 32767)
|
||||||
return NullPixmap;
|
return NullPixmap;
|
||||||
|
|
||||||
if (usage == GLAMOR_CREATE_PIXMAP_CPU
|
if ((usage == GLAMOR_CREATE_PIXMAP_CPU
|
||||||
|| (w == 0 && h == 0)
|
|| (w == 0 && h == 0)
|
||||||
|| !glamor_check_pixmap_fbo_depth(depth))
|
|| !glamor_check_pixmap_fbo_depth(depth))
|
||||||
|
|| (!GLAMOR_TEXTURED_LARGE_PIXMAP &&
|
||||||
|
!glamor_check_fbo_size(glamor_priv, w, h)))
|
||||||
return fbCreatePixmap(screen, w, h, depth, usage);
|
return fbCreatePixmap(screen, w, h, depth, usage);
|
||||||
else
|
else
|
||||||
pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
|
pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
|
||||||
|
@ -161,10 +163,24 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
|
||||||
|
|
||||||
pixmap_priv->base.pixmap = pixmap;
|
pixmap_priv->base.pixmap = pixmap;
|
||||||
pixmap_priv->base.glamor_priv = glamor_priv;
|
pixmap_priv->base.glamor_priv = glamor_priv;
|
||||||
pixmap_priv->type = type;
|
|
||||||
|
|
||||||
gl_iformat_for_depth(depth, &format);
|
gl_iformat_for_depth(depth, &format);
|
||||||
fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
|
|
||||||
|
pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
|
||||||
|
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
|
||||||
|
|
||||||
|
if (type == GLAMOR_MEMORY_MAP || glamor_check_fbo_size(glamor_priv, w, h)) {
|
||||||
|
pixmap_priv->type = type;
|
||||||
|
fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUGF("Create LARGE pixmap %p width %d height %d\n", pixmap, w, h);
|
||||||
|
pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
|
||||||
|
fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
|
||||||
|
glamor_priv->max_fbo_size,
|
||||||
|
glamor_priv->max_fbo_size,
|
||||||
|
pixmap_priv);
|
||||||
|
}
|
||||||
|
|
||||||
if (fbo == NULL) {
|
if (fbo == NULL) {
|
||||||
fbDestroyPixmap(pixmap);
|
fbDestroyPixmap(pixmap);
|
||||||
|
@ -174,8 +190,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
|
||||||
|
|
||||||
glamor_pixmap_attach_fbo(pixmap, fbo);
|
glamor_pixmap_attach_fbo(pixmap, fbo);
|
||||||
|
|
||||||
pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
|
|
||||||
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
|
|
||||||
return pixmap;
|
return pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,13 +200,8 @@ glamor_destroy_textured_pixmap(PixmapPtr pixmap)
|
||||||
glamor_pixmap_private *pixmap_priv;
|
glamor_pixmap_private *pixmap_priv;
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
if (pixmap_priv != NULL) {
|
if (pixmap_priv != NULL)
|
||||||
glamor_pixmap_fbo *fbo;
|
glamor_pixmap_destroy_fbo(pixmap_priv);
|
||||||
fbo = glamor_pixmap_detach_fbo(pixmap_priv);
|
|
||||||
if (fbo)
|
|
||||||
glamor_destroy_fbo(fbo);
|
|
||||||
free(pixmap_priv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,6 +324,9 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
glamor_gl_has_extension("GL_EXT_framebuffer_blit");
|
glamor_gl_has_extension("GL_EXT_framebuffer_blit");
|
||||||
glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
|
glamor_priv->_dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE,
|
||||||
&glamor_priv->max_fbo_size);
|
&glamor_priv->max_fbo_size);
|
||||||
|
#ifdef MAX_FBO_SIZE
|
||||||
|
glamor_priv->max_fbo_size = MAX_FBO_SIZE;
|
||||||
|
#endif
|
||||||
|
|
||||||
glamor_set_debug_level(&glamor_debug_level);
|
glamor_set_debug_level(&glamor_debug_level);
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,13 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
|
||||||
ScreenPtr screen = dst->pScreen;
|
ScreenPtr screen = dst->pScreen;
|
||||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||||
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
||||||
glamor_pixmap_private *src_pixmap_priv;
|
glamor_pixmap_private *src_pixmap_priv, *dst_pixmap_priv;
|
||||||
glamor_screen_private *glamor_priv =
|
glamor_screen_private *glamor_priv =
|
||||||
glamor_get_screen_private(screen);
|
glamor_get_screen_private(screen);
|
||||||
glamor_gl_dispatch *dispatch;
|
glamor_gl_dispatch *dispatch;
|
||||||
int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
|
int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
|
||||||
|
int fbo_x_off, fbo_y_off;
|
||||||
|
int src_fbo_x_off, src_fbo_y_off;
|
||||||
|
|
||||||
if (!glamor_priv->has_fbo_blit) {
|
if (!glamor_priv->has_fbo_blit) {
|
||||||
glamor_delayed_fallback(screen,
|
glamor_delayed_fallback(screen,
|
||||||
|
@ -52,17 +54,13 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||||
|
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||||
|
|
||||||
if (gc) {
|
if (gc) {
|
||||||
if (gc->alu != GXcopy) {
|
if (gc->alu != GXcopy) {
|
||||||
glamor_delayed_fallback(screen, "non-copy ALU\n");
|
glamor_delayed_fallback(screen, "non-copy ALU\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!glamor_pm_is_solid(dst, gc->planemask)) {
|
|
||||||
glamor_delayed_fallback(screen,
|
|
||||||
"non-solid planemask\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
|
||||||
|
@ -73,6 +71,9 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
|
||||||
if (glamor_set_destination_pixmap(dst_pixmap))
|
if (glamor_set_destination_pixmap(dst_pixmap))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off);
|
||||||
|
pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off);
|
||||||
|
|
||||||
dispatch = glamor_get_dispatch(glamor_priv);
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
|
dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
|
||||||
src_pixmap_priv->base.fbo->fb);
|
src_pixmap_priv->base.fbo->fb);
|
||||||
|
@ -80,7 +81,10 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
|
||||||
&dst_y_off);
|
&dst_y_off);
|
||||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
|
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
|
||||||
&src_y_off);
|
&src_y_off);
|
||||||
src_y_off += dy;
|
dst_x_off += fbo_x_off;
|
||||||
|
dst_y_off += fbo_y_off;
|
||||||
|
src_y_off += dy + src_fbo_y_off;
|
||||||
|
src_x_off += src_fbo_x_off;
|
||||||
|
|
||||||
for (i = 0; i < nbox; i++) {
|
for (i = 0; i < nbox; i++) {
|
||||||
if (glamor_priv->yInverted) {
|
if (glamor_priv->yInverted) {
|
||||||
|
@ -154,17 +158,11 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||||
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
||||||
enum glamor_pixmap_status src_status = GLAMOR_NONE;
|
enum glamor_pixmap_status src_status = GLAMOR_NONE;
|
||||||
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
|
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
|
||||||
int alu = GXcopy;
|
|
||||||
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
|
if (!src_pixmap_priv->base.gl_fbo) {
|
||||||
glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!src_pixmap_priv || !src_pixmap_priv->base.gl_fbo) {
|
|
||||||
#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
|
#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
|
||||||
glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
|
glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -177,11 +175,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gc) {
|
|
||||||
if (!glamor_set_planemask(dst_pixmap, gc->planemask))
|
|
||||||
return FALSE;
|
|
||||||
alu = gc->alu;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
|
pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
|
||||||
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
|
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
|
||||||
|
@ -191,10 +184,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||||
|
|
||||||
dispatch = glamor_get_dispatch(glamor_priv);
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
|
|
||||||
if (!glamor_set_alu(dispatch, alu)) {
|
|
||||||
glamor_put_dispatch(glamor_priv);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
|
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
|
||||||
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||||
|
@ -239,8 +228,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||||
|
|
||||||
for (i = 0; i < nbox; i++) {
|
for (i = 0; i < nbox; i++) {
|
||||||
|
|
||||||
glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale,
|
glamor_set_normalize_vcoords(dst_pixmap_priv,
|
||||||
dst_yscale,
|
dst_xscale, dst_yscale,
|
||||||
box[i].x1 + dst_x_off,
|
box[i].x1 + dst_x_off,
|
||||||
box[i].y1 + dst_y_off,
|
box[i].y1 + dst_y_off,
|
||||||
box[i].x2 + dst_x_off,
|
box[i].x2 + dst_x_off,
|
||||||
|
@ -248,7 +237,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||||
glamor_priv->yInverted,
|
glamor_priv->yInverted,
|
||||||
vertices);
|
vertices);
|
||||||
|
|
||||||
glamor_set_normalize_tcoords(src_pixmap_priv, src_xscale,
|
glamor_set_normalize_tcoords(src_pixmap_priv,
|
||||||
|
src_xscale,
|
||||||
src_yscale,
|
src_yscale,
|
||||||
box[i].x1 + dx,
|
box[i].x1 + dx,
|
||||||
box[i].y1 + dy,
|
box[i].y1 + dy,
|
||||||
|
@ -271,18 +261,17 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
_glamor_copy_n_to_n(DrawablePtr src,
|
__glamor_copy_n_to_n(DrawablePtr src,
|
||||||
DrawablePtr dst,
|
DrawablePtr dst,
|
||||||
GCPtr gc,
|
GCPtr gc,
|
||||||
BoxPtr box,
|
BoxPtr box,
|
||||||
int nbox,
|
int nbox,
|
||||||
int dx,
|
int dx,
|
||||||
int dy,
|
int dy,
|
||||||
Bool reverse,
|
Bool reverse,
|
||||||
Bool upsidedown, Pixel bitplane,
|
Bool upsidedown, Pixel bitplane,
|
||||||
void *closure, Bool fallback)
|
void *closure)
|
||||||
{
|
{
|
||||||
glamor_access_t dst_access;
|
|
||||||
PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
|
PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
|
||||||
DrawablePtr temp_src = src;
|
DrawablePtr temp_src = src;
|
||||||
glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
|
glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
|
||||||
|
@ -296,32 +285,20 @@ _glamor_copy_n_to_n(DrawablePtr src,
|
||||||
int overlaped = 0;
|
int overlaped = 0;
|
||||||
Bool ret = FALSE;
|
Bool ret = FALSE;
|
||||||
|
|
||||||
if (nbox == 0)
|
|
||||||
return TRUE;
|
|
||||||
dst_pixmap = glamor_get_drawable_pixmap(dst);
|
dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||||
src_pixmap = glamor_get_drawable_pixmap(src);
|
src_pixmap = glamor_get_drawable_pixmap(src);
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||||
screen = dst_pixmap->drawable.pScreen;
|
screen = dst_pixmap->drawable.pScreen;
|
||||||
glamor_priv = glamor_get_screen_private(dst->pScreen);
|
glamor_priv = glamor_get_screen_private(dst->pScreen);
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
|
|
||||||
glamor_fallback("dest pixmap %p has no fbo. \n",
|
|
||||||
dst_pixmap);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!src_pixmap_priv) {
|
|
||||||
glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY);
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
|
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
|
||||||
&src_y_off);
|
&src_y_off);
|
||||||
|
|
||||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
|
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
|
||||||
&dst_y_off);
|
&dst_y_off);
|
||||||
|
|
||||||
if (src_pixmap_priv->base.fbo && src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->fb) {
|
if (src_pixmap_priv->base.fbo
|
||||||
|
&& src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->fb) {
|
||||||
int x_shift = abs(src_x_off - dx - dst_x_off);
|
int x_shift = abs(src_x_off - dx - dst_x_off);
|
||||||
int y_shift = abs(src_y_off - dy - dst_y_off);
|
int y_shift = abs(src_y_off - dy - dst_y_off);
|
||||||
for (i = 0; i < nbox; i++) {
|
for (i = 0; i < nbox; i++) {
|
||||||
|
@ -332,6 +309,11 @@ _glamor_copy_n_to_n(DrawablePtr src,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
|
||||||
|
box[0].x1, box[0].y1,
|
||||||
|
box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
|
||||||
|
dx, dy,
|
||||||
|
src_pixmap, dst_pixmap);
|
||||||
#ifndef GLAMOR_GLES2
|
#ifndef GLAMOR_GLES2
|
||||||
if ((overlaped
|
if ((overlaped
|
||||||
|| !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
|
|| !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
|
||||||
|
@ -345,10 +327,13 @@ _glamor_copy_n_to_n(DrawablePtr src,
|
||||||
|
|
||||||
/* Overlaped indicate the src and dst are the same pixmap. */
|
/* Overlaped indicate the src and dst are the same pixmap. */
|
||||||
if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)
|
if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)
|
||||||
&& ((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
|
&& (((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
|
||||||
* 4 >
|
* 4 >
|
||||||
src_pixmap->drawable.width *
|
src_pixmap->drawable.width *
|
||||||
src_pixmap->drawable.height))) {
|
src_pixmap->drawable.height)
|
||||||
|
|| !(glamor_check_fbo_size(glamor_priv,
|
||||||
|
src_pixmap->drawable.width,
|
||||||
|
src_pixmap->drawable.height))))) {
|
||||||
|
|
||||||
temp_pixmap = glamor_create_pixmap(screen,
|
temp_pixmap = glamor_create_pixmap(screen,
|
||||||
bound.x2 - bound.x1,
|
bound.x2 - bound.x1,
|
||||||
|
@ -357,9 +342,11 @@ _glamor_copy_n_to_n(DrawablePtr src,
|
||||||
drawable.depth,
|
drawable.depth,
|
||||||
overlaped ? 0 :
|
overlaped ? 0 :
|
||||||
GLAMOR_CREATE_PIXMAP_CPU);
|
GLAMOR_CREATE_PIXMAP_CPU);
|
||||||
|
assert(bound.x2 - bound.x1 <= glamor_priv->max_fbo_size);
|
||||||
|
assert(bound.y2 - bound.y1 <= glamor_priv->max_fbo_size);
|
||||||
if (!temp_pixmap)
|
if (!temp_pixmap)
|
||||||
goto fail;
|
goto done;
|
||||||
glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
|
glamor_translate_boxes(box, nbox, -bound.x1, -bound.y1);
|
||||||
temp_src = &temp_pixmap->drawable;
|
temp_src = &temp_pixmap->drawable;
|
||||||
|
|
||||||
if (overlaped)
|
if (overlaped)
|
||||||
|
@ -371,7 +358,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
|
||||||
fbCopyNtoN(src, temp_src, gc, box, nbox,
|
fbCopyNtoN(src, temp_src, gc, box, nbox,
|
||||||
temp_dx + bound.x1, temp_dy + bound.y1,
|
temp_dx + bound.x1, temp_dy + bound.y1,
|
||||||
reverse, upsidedown, bitplane, closure);
|
reverse, upsidedown, bitplane, closure);
|
||||||
glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
|
glamor_translate_boxes(box, nbox, bound.x1, bound.y1);
|
||||||
temp_dx = -bound.x1;
|
temp_dx = -bound.x1;
|
||||||
temp_dy = -bound.y1;
|
temp_dy = -bound.y1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -383,12 +370,220 @@ _glamor_copy_n_to_n(DrawablePtr src,
|
||||||
if (glamor_copy_n_to_n_textured
|
if (glamor_copy_n_to_n_textured
|
||||||
(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
|
(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
goto done;
|
}
|
||||||
|
done:
|
||||||
|
if (temp_src != src)
|
||||||
|
glamor_destroy_pixmap(temp_pixmap);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
_glamor_copy_n_to_n(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
GCPtr gc,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
Bool reverse,
|
||||||
|
Bool upsidedown, Pixel bitplane,
|
||||||
|
void *closure, Bool fallback)
|
||||||
|
{
|
||||||
|
glamor_access_t dst_access;
|
||||||
|
PixmapPtr dst_pixmap, src_pixmap;
|
||||||
|
glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
|
||||||
|
glamor_screen_private *glamor_priv;
|
||||||
|
glamor_gl_dispatch *dispatch;
|
||||||
|
BoxPtr extent;
|
||||||
|
RegionRec region;
|
||||||
|
ScreenPtr screen;
|
||||||
|
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
||||||
|
Bool ret = FALSE;
|
||||||
|
int ok = TRUE;
|
||||||
|
int force_clip = 0;
|
||||||
|
|
||||||
|
if (nbox == 0)
|
||||||
|
return TRUE;
|
||||||
|
dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||||
|
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||||
|
src_pixmap = glamor_get_drawable_pixmap(src);
|
||||||
|
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||||
|
screen = dst_pixmap->drawable.pScreen;
|
||||||
|
|
||||||
|
glamor_priv = glamor_get_screen_private(dst->pScreen);
|
||||||
|
|
||||||
|
DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
|
||||||
|
box[0].x1, box[0].y1,
|
||||||
|
box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
|
||||||
|
dx, dy,
|
||||||
|
src_pixmap, dst_pixmap);
|
||||||
|
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
|
||||||
|
goto fall_back;
|
||||||
|
|
||||||
|
if (gc) {
|
||||||
|
if (!glamor_set_planemask(dst_pixmap, gc->planemask))
|
||||||
|
goto fail;
|
||||||
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
|
if (!glamor_set_alu(dispatch, gc->alu)) {
|
||||||
|
glamor_put_dispatch(glamor_priv);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
glamor_put_dispatch(glamor_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!src_pixmap_priv) {
|
||||||
|
glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY);
|
||||||
|
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||||
|
}
|
||||||
|
|
||||||
fail:
|
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
|
||||||
|
&src_y_off);
|
||||||
|
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
|
||||||
|
&dst_y_off);
|
||||||
|
|
||||||
|
RegionInitBoxes(®ion, box, nbox);
|
||||||
|
extent = RegionExtents(®ion);
|
||||||
|
|
||||||
|
if (!glamor_check_fbo_size(glamor_priv,
|
||||||
|
extent->x2 - extent->x1, extent->y2 - extent->y1)
|
||||||
|
&& (src_pixmap_priv->type == GLAMOR_MEMORY
|
||||||
|
|| (src_pixmap_priv == dst_pixmap_priv))) {
|
||||||
|
force_clip = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
|
||||||
|
|| src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
glamor_pixmap_clipped_regions *clipped_dst_regions;
|
||||||
|
int n_dst_region, i, j;
|
||||||
|
PixmapPtr temp_source_pixmap;
|
||||||
|
glamor_pixmap_private *temp_source_priv = NULL;
|
||||||
|
int temp_dx = 0, temp_dy = 0;
|
||||||
|
|
||||||
|
RegionTranslate(®ion, dst_x_off, dst_y_off);
|
||||||
|
if (!force_clip)
|
||||||
|
clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
|
||||||
|
®ion, &n_dst_region, 0);
|
||||||
|
else
|
||||||
|
clipped_dst_regions = glamor_compute_clipped_regions_ext(dst_pixmap_priv,
|
||||||
|
®ion, &n_dst_region,
|
||||||
|
glamor_priv->max_fbo_size,
|
||||||
|
glamor_priv->max_fbo_size);
|
||||||
|
for(i = 0; i < n_dst_region; i++)
|
||||||
|
{
|
||||||
|
int n_src_region;
|
||||||
|
glamor_pixmap_clipped_regions *clipped_src_regions;
|
||||||
|
BoxPtr current_boxes;
|
||||||
|
int n_current_boxes;
|
||||||
|
|
||||||
|
SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, clipped_dst_regions[i].block_idx);
|
||||||
|
|
||||||
|
temp_source_pixmap = NULL;
|
||||||
|
if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
RegionTranslate(clipped_dst_regions[i].region,
|
||||||
|
-dst_x_off + src_x_off + dx, -dst_y_off + src_y_off + dy);
|
||||||
|
clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv,
|
||||||
|
clipped_dst_regions[i].region,
|
||||||
|
&n_src_region, 0);
|
||||||
|
DEBUGF("Source is large pixmap.\n");
|
||||||
|
for (j = 0; j < n_src_region; j++)
|
||||||
|
{
|
||||||
|
if (src_pixmap_priv != dst_pixmap_priv)
|
||||||
|
SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, clipped_src_regions[j].block_idx);
|
||||||
|
else if (src_pixmap_priv == dst_pixmap_priv &&
|
||||||
|
clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx) {
|
||||||
|
/* source and the dest are the same, but need different block_idx.
|
||||||
|
* we create a empty pixmap and fill the required source fbo and box to
|
||||||
|
* it. It's a little hacky, but avoid extra copy. */
|
||||||
|
temp_source_pixmap = glamor_create_pixmap(src->pScreen, 0, 0,
|
||||||
|
src->depth, 0);
|
||||||
|
if (!temp_source_pixmap)
|
||||||
|
goto fail;
|
||||||
|
src->pScreen->ModifyPixmapHeader(temp_source_pixmap,
|
||||||
|
src_pixmap->drawable.width,
|
||||||
|
src_pixmap->drawable.height,
|
||||||
|
0, 0, src_pixmap->devKind, NULL);
|
||||||
|
temp_source_priv = glamor_get_pixmap_private(temp_source_pixmap);
|
||||||
|
*temp_source_priv = *src_pixmap_priv;
|
||||||
|
temp_source_priv->large.box = src_pixmap_priv->large.box_array[clipped_src_regions[j].block_idx];
|
||||||
|
temp_source_priv->base.fbo = src_pixmap_priv->large.fbo_array[clipped_src_regions[j].block_idx];
|
||||||
|
/* XXX need revisit here. */
|
||||||
|
temp_dx = dx/* - src_x_off*/;
|
||||||
|
temp_dy = dy/* - src_y_off*/;
|
||||||
|
}
|
||||||
|
assert(temp_source_pixmap || !(src_pixmap_priv == dst_pixmap_priv
|
||||||
|
&& (clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx)));
|
||||||
|
|
||||||
|
RegionTranslate(clipped_src_regions[j].region,
|
||||||
|
-src_x_off - dx,
|
||||||
|
-src_y_off - dy);
|
||||||
|
current_boxes = RegionRects(clipped_src_regions[j].region);
|
||||||
|
n_current_boxes = RegionNumRects(clipped_src_regions[j].region);
|
||||||
|
DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n",
|
||||||
|
clipped_dst_regions[i].block_idx,
|
||||||
|
clipped_src_regions[j].block_idx);
|
||||||
|
DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
|
||||||
|
current_boxes[0].x1, current_boxes[0].y1,
|
||||||
|
current_boxes[0].x2, current_boxes[0].y2,
|
||||||
|
dx, dy, src_pixmap, dst_pixmap);
|
||||||
|
if (!temp_source_pixmap)
|
||||||
|
ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
|
||||||
|
n_current_boxes, dx, dy, reverse,
|
||||||
|
upsidedown, bitplane, closure);
|
||||||
|
else {
|
||||||
|
ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable, dst, gc, current_boxes,
|
||||||
|
n_current_boxes, temp_dx, temp_dy, reverse,
|
||||||
|
upsidedown, bitplane, closure);
|
||||||
|
temp_source_priv->type = GLAMOR_MEMORY;
|
||||||
|
temp_source_priv->base.fbo = NULL;
|
||||||
|
glamor_destroy_pixmap(temp_source_pixmap);
|
||||||
|
temp_source_pixmap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionDestroy(clipped_src_regions[j].region);
|
||||||
|
if (!ok) {
|
||||||
|
assert(0);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(clipped_src_regions);
|
||||||
|
} else {
|
||||||
|
RegionTranslate(clipped_dst_regions[i].region,
|
||||||
|
- dst_x_off,
|
||||||
|
- dst_y_off);
|
||||||
|
current_boxes = RegionRects(clipped_dst_regions[i].region);
|
||||||
|
n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
|
||||||
|
|
||||||
|
DEBUGF("dest pixmap fbo idx %d \n",
|
||||||
|
clipped_dst_regions[i].block_idx);
|
||||||
|
DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
|
||||||
|
current_boxes[0].x1, current_boxes[0].y1,
|
||||||
|
current_boxes[0].x2, current_boxes[0].y2,
|
||||||
|
dx, dy, src_pixmap, dst_pixmap);
|
||||||
|
|
||||||
|
ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
|
||||||
|
n_current_boxes, dx, dy, reverse,
|
||||||
|
upsidedown, bitplane, closure);
|
||||||
|
|
||||||
|
}
|
||||||
|
RegionDestroy(clipped_dst_regions[i].region);
|
||||||
|
}
|
||||||
|
free(clipped_dst_regions);
|
||||||
|
RegionUninit(®ion);
|
||||||
|
} else {
|
||||||
|
ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy,
|
||||||
|
reverse, upsidedown, bitplane,
|
||||||
|
closure);
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
|
glamor_set_alu(dispatch, GXcopy);
|
||||||
|
glamor_put_dispatch(glamor_priv);
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
return TRUE;
|
||||||
|
fall_back:
|
||||||
if (!fallback
|
if (!fallback
|
||||||
&& glamor_ddx_fallback_check_pixmap(src)
|
&& glamor_ddx_fallback_check_pixmap(src)
|
||||||
&& glamor_ddx_fallback_check_pixmap(dst))
|
&& glamor_ddx_fallback_check_pixmap(dst))
|
||||||
|
@ -428,8 +623,6 @@ _glamor_copy_n_to_n(DrawablePtr src,
|
||||||
done:
|
done:
|
||||||
glamor_clear_delayed_fallbacks(src->pScreen);
|
glamor_clear_delayed_fallbacks(src->pScreen);
|
||||||
glamor_clear_delayed_fallbacks(dst->pScreen);
|
glamor_clear_delayed_fallbacks(dst->pScreen);
|
||||||
if (temp_src != src)
|
|
||||||
glamor_destroy_pixmap(temp_pixmap);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,8 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
|
||||||
|
|
||||||
if (fbo->fb == 0 || n_format == -1
|
if (fbo->fb == 0 || n_format == -1
|
||||||
|| fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
|
|| fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
|
||||||
fbo->glamor_priv->tick ++;
|
fbo->glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
|
||||||
|
glamor_fbo_expire(fbo->glamor_priv);
|
||||||
glamor_purge_fbo(fbo);
|
glamor_purge_fbo(fbo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -404,6 +405,92 @@ no_tex:
|
||||||
return fbo;
|
return fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static glamor_pixmap_fbo *
|
||||||
|
_glamor_create_fbo_array(glamor_screen_private *glamor_priv,
|
||||||
|
int w, int h, GLenum format, int flag,
|
||||||
|
int block_w, int block_h,
|
||||||
|
glamor_pixmap_private *pixmap_priv,
|
||||||
|
int has_fbo)
|
||||||
|
{
|
||||||
|
int block_wcnt;
|
||||||
|
int block_hcnt;
|
||||||
|
glamor_pixmap_fbo **fbo_array;
|
||||||
|
BoxPtr box_array;
|
||||||
|
int i,j;
|
||||||
|
glamor_pixmap_private_large_t *priv;
|
||||||
|
|
||||||
|
priv = &pixmap_priv->large;
|
||||||
|
|
||||||
|
block_wcnt = (w + block_w - 1) / block_w;
|
||||||
|
block_hcnt = (h + block_h - 1) / block_h;
|
||||||
|
|
||||||
|
box_array = calloc(block_wcnt * block_hcnt, sizeof(box_array[0]));
|
||||||
|
if (box_array == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fbo_array = calloc(block_wcnt * block_hcnt, sizeof(glamor_pixmap_fbo*));
|
||||||
|
if (fbo_array == NULL) {
|
||||||
|
free(box_array);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
for(i = 0; i < block_hcnt; i++)
|
||||||
|
{
|
||||||
|
int block_y1, block_y2;
|
||||||
|
int fbo_w, fbo_h;
|
||||||
|
|
||||||
|
block_y1 = i * block_h;
|
||||||
|
block_y2 = (block_y1 + block_h) > h ? h : (block_y1 + block_h);
|
||||||
|
fbo_h = block_y2 - block_y1;
|
||||||
|
|
||||||
|
for (j = 0; j < block_wcnt; j++)
|
||||||
|
{
|
||||||
|
box_array[i * block_wcnt + j].x1 = j * block_w;
|
||||||
|
box_array[i * block_wcnt + j].y1 = block_y1;
|
||||||
|
box_array[i * block_wcnt + j].x2 = (j + 1) * block_w > w ? w : (j + 1) * block_w;
|
||||||
|
box_array[i * block_wcnt + j].y2 = block_y2;
|
||||||
|
fbo_w = box_array[i * block_wcnt + j].x2 - box_array[i * block_wcnt + j].x1;
|
||||||
|
if (!has_fbo)
|
||||||
|
fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv,
|
||||||
|
fbo_w, fbo_h, format,
|
||||||
|
GLAMOR_CREATE_PIXMAP_FIXUP);
|
||||||
|
else
|
||||||
|
fbo_array[i * block_wcnt + j] = priv->base.fbo;
|
||||||
|
if (fbo_array[i * block_wcnt + j] == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->box = box_array[0];
|
||||||
|
priv->box_array = box_array;
|
||||||
|
priv->fbo_array = fbo_array;
|
||||||
|
priv->block_wcnt = block_wcnt;
|
||||||
|
priv->block_hcnt = block_hcnt;
|
||||||
|
return fbo_array[0];
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
for(i = 0; i < block_wcnt * block_hcnt; i++)
|
||||||
|
if ((fbo_array)[i])
|
||||||
|
glamor_destroy_fbo((fbo_array)[i]);
|
||||||
|
free(box_array);
|
||||||
|
free(fbo_array);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a fbo array to cover the w*h region, by using block_w*block_h
|
||||||
|
* block.*/
|
||||||
|
glamor_pixmap_fbo *
|
||||||
|
glamor_create_fbo_array(glamor_screen_private *glamor_priv,
|
||||||
|
int w, int h, GLenum format, int flag,
|
||||||
|
int block_w, int block_h,
|
||||||
|
glamor_pixmap_private *pixmap_priv)
|
||||||
|
{
|
||||||
|
pixmap_priv->large.block_w = block_w;
|
||||||
|
pixmap_priv->large.block_h = block_h;
|
||||||
|
return _glamor_create_fbo_array(glamor_priv, w, h, format, flag,
|
||||||
|
block_w, block_h, pixmap_priv, 0);
|
||||||
|
}
|
||||||
|
|
||||||
glamor_pixmap_fbo *
|
glamor_pixmap_fbo *
|
||||||
glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
|
glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
|
||||||
{
|
{
|
||||||
|
@ -428,23 +515,13 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
|
||||||
if (pixmap_priv == NULL) {
|
|
||||||
glamor_screen_private *glamor_priv;
|
|
||||||
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
|
|
||||||
pixmap_priv = calloc(1, sizeof(*pixmap_priv));
|
|
||||||
dixSetPrivate(&pixmap->devPrivates,
|
|
||||||
glamor_pixmap_private_key, pixmap_priv);
|
|
||||||
pixmap_priv->base.pixmap = pixmap;
|
|
||||||
pixmap_priv->base.glamor_priv = glamor_priv;
|
|
||||||
pixmap_priv->type = GLAMOR_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixmap_priv->base.fbo)
|
if (pixmap_priv->base.fbo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pixmap_priv->base.fbo = fbo;
|
pixmap_priv->base.fbo = fbo;
|
||||||
|
|
||||||
switch (pixmap_priv->type) {
|
switch (pixmap_priv->type) {
|
||||||
|
case GLAMOR_TEXTURE_LARGE:
|
||||||
case GLAMOR_TEXTURE_ONLY:
|
case GLAMOR_TEXTURE_ONLY:
|
||||||
case GLAMOR_TEXTURE_DRM:
|
case GLAMOR_TEXTURE_DRM:
|
||||||
pixmap_priv->base.gl_fbo = 1;
|
pixmap_priv->base.gl_fbo = 1;
|
||||||
|
@ -462,6 +539,23 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
|
||||||
|
{
|
||||||
|
glamor_pixmap_fbo *fbo;
|
||||||
|
if (priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
int i;
|
||||||
|
glamor_pixmap_private_large_t *large = &priv->large;
|
||||||
|
for(i = 0; i < large->block_wcnt * large->block_hcnt; i++)
|
||||||
|
glamor_destroy_fbo(large->fbo_array[i]);
|
||||||
|
free(large->fbo_array);
|
||||||
|
} else {
|
||||||
|
fbo = glamor_pixmap_detach_fbo(priv);
|
||||||
|
if (fbo)
|
||||||
|
glamor_destroy_fbo(fbo);
|
||||||
|
free(priv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
|
glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
|
||||||
|
@ -472,7 +566,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
|
||||||
|
|
||||||
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
|
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
if (pixmap_priv == NULL || pixmap_priv->base.fbo == NULL) {
|
if (pixmap_priv->base.fbo == NULL) {
|
||||||
|
|
||||||
fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
|
fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
|
||||||
pixmap->drawable.height,
|
pixmap->drawable.height,
|
||||||
|
@ -492,7 +586,6 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
|
||||||
glamor_pixmap_ensure_fb(pixmap_priv->base.fbo);
|
glamor_pixmap_ensure_fb(pixmap_priv->base.fbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,10 +180,9 @@ glamor_fini_solid_shader(ScreenPtr screen)
|
||||||
glamor_put_dispatch(glamor_priv);
|
glamor_put_dispatch(glamor_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
static void
|
||||||
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
_glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||||
unsigned char alu, unsigned long planemask,
|
float *color)
|
||||||
unsigned long fg_pixel)
|
|
||||||
{
|
{
|
||||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
glamor_screen_private *glamor_priv =
|
glamor_screen_private *glamor_priv =
|
||||||
|
@ -195,14 +194,49 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||||
int x2 = x + width;
|
int x2 = x + width;
|
||||||
int y1 = y;
|
int y1 = y;
|
||||||
int y2 = y + height;
|
int y2 = y + height;
|
||||||
GLfloat color[4];
|
|
||||||
float vertices[8];
|
float vertices[8];
|
||||||
GLfloat xscale, yscale;
|
GLfloat xscale, yscale;
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
|
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
||||||
glamor_fallback("dest %p has no fbo.\n", pixmap);
|
|
||||||
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
|
dispatch->glUseProgram(glamor_priv->solid_prog);
|
||||||
|
|
||||||
|
dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
|
||||||
|
1, color);
|
||||||
|
|
||||||
|
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||||
|
GL_FALSE, 2 * sizeof(float),
|
||||||
|
vertices);
|
||||||
|
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
|
||||||
|
|
||||||
|
glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
|
||||||
|
x1, y1,
|
||||||
|
x2, y2,
|
||||||
|
glamor_priv->yInverted, vertices);
|
||||||
|
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
dispatch->glUseProgram(0);
|
||||||
|
glamor_put_dispatch(glamor_priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||||
|
unsigned char alu, unsigned long planemask,
|
||||||
|
unsigned long fg_pixel)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
|
glamor_screen_private *glamor_priv =
|
||||||
|
glamor_get_screen_private(screen);
|
||||||
|
glamor_pixmap_private *pixmap_priv;
|
||||||
|
glamor_gl_dispatch *dispatch;
|
||||||
|
GLfloat color[4];
|
||||||
|
|
||||||
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
if (!glamor_set_planemask(pixmap, planemask)) {
|
if (!glamor_set_planemask(pixmap, planemask)) {
|
||||||
glamor_fallback
|
glamor_fallback
|
||||||
|
@ -216,8 +250,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||||
&color[2],
|
&color[2],
|
||||||
&color[3], format_for_pixmap(pixmap));
|
&color[3], format_for_pixmap(pixmap));
|
||||||
|
|
||||||
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
|
||||||
|
|
||||||
dispatch = glamor_get_dispatch(glamor_priv);
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
if (!glamor_set_alu(dispatch, alu)) {
|
if (!glamor_set_alu(dispatch, alu)) {
|
||||||
if (alu == GXclear)
|
if (alu == GXclear)
|
||||||
|
@ -228,23 +260,47 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dispatch->glUseProgram(glamor_priv->solid_prog);
|
|
||||||
|
|
||||||
dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
|
if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
1, color);
|
RegionRec region;
|
||||||
|
BoxRec box;
|
||||||
|
int n_region;
|
||||||
|
glamor_pixmap_clipped_regions *clipped_regions;
|
||||||
|
int i,j;
|
||||||
|
|
||||||
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
box.x1 = x;
|
||||||
GL_FALSE, 2 * sizeof(float),
|
box.y1 = y;
|
||||||
vertices);
|
box.x2 = x + width;
|
||||||
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
box.y2 = y + height;
|
||||||
pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
|
RegionInitBoxes(®ion, &box, 1);
|
||||||
|
clipped_regions = glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region, 0);
|
||||||
|
for(i = 0; i < n_region; i++)
|
||||||
|
{
|
||||||
|
BoxPtr boxes;
|
||||||
|
int nbox;
|
||||||
|
SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
|
||||||
|
|
||||||
|
boxes = RegionRects(clipped_regions[i].region);
|
||||||
|
nbox = RegionNumRects(clipped_regions[i].region);
|
||||||
|
for(j = 0; j < nbox; j++)
|
||||||
|
{
|
||||||
|
_glamor_solid(pixmap, boxes[j].x1, boxes[j].y1,
|
||||||
|
boxes[j].x2 - boxes[j].x1,
|
||||||
|
boxes[j].y2 - boxes[j].y1, color);
|
||||||
|
}
|
||||||
|
RegionDestroy(clipped_regions[i].region);
|
||||||
|
}
|
||||||
|
free(clipped_regions);
|
||||||
|
RegionUninit(®ion);
|
||||||
|
} else
|
||||||
|
_glamor_solid(pixmap,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width, height,
|
||||||
|
color);
|
||||||
|
|
||||||
glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale, x1, y1, x2, y2,
|
|
||||||
glamor_priv->yInverted, vertices);
|
|
||||||
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
||||||
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
|
||||||
dispatch->glUseProgram(0);
|
|
||||||
glamor_set_alu(dispatch, GXcopy);
|
glamor_set_alu(dispatch, GXcopy);
|
||||||
glamor_put_dispatch(glamor_priv);
|
glamor_put_dispatch(glamor_priv);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
412
glamor/glamor_largepixmap.c
Normal file
412
glamor/glamor_largepixmap.c
Normal file
|
@ -0,0 +1,412 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "glamor_priv.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clip the boxes regards to each pixmap's block array.
|
||||||
|
*
|
||||||
|
* Should translate the region to relative coords to the pixmap,
|
||||||
|
* start at (0,0).
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
//#define DEBUGF(str, ...) do {} while(0)
|
||||||
|
#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__)
|
||||||
|
//#define DEBUGRegionPrint(x) do {} while (0)
|
||||||
|
#define DEBUGRegionPrint RegionPrint
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static glamor_pixmap_clipped_regions *
|
||||||
|
__glamor_compute_clipped_regions(int block_w,
|
||||||
|
int block_h,
|
||||||
|
int block_stride,
|
||||||
|
int x, int y,
|
||||||
|
int w, int h,
|
||||||
|
RegionPtr region,
|
||||||
|
int *n_region,
|
||||||
|
int repeat)
|
||||||
|
{
|
||||||
|
glamor_pixmap_clipped_regions * clipped_regions;
|
||||||
|
BoxPtr extent;
|
||||||
|
int start_x, start_y, end_x, end_y;
|
||||||
|
int start_block_x, start_block_y;
|
||||||
|
int end_block_x, end_block_y;
|
||||||
|
int i, j;
|
||||||
|
int width, height;
|
||||||
|
RegionRec temp_region;
|
||||||
|
RegionPtr current_region;
|
||||||
|
int block_idx;
|
||||||
|
int k = 0;
|
||||||
|
int temp_block_idx;
|
||||||
|
|
||||||
|
extent = RegionExtents(region);
|
||||||
|
start_x = MAX(x, extent->x1);
|
||||||
|
start_y = MAX(y, extent->y1);
|
||||||
|
end_x = MIN(x + w, extent->x2);
|
||||||
|
end_y = MIN(y + h, extent->y2);
|
||||||
|
|
||||||
|
DEBUGF("start compute clipped regions:\n");
|
||||||
|
DEBUGF("block w %d h %d x %d y %d w %d h %d, block_stride %d \n",
|
||||||
|
block_w, block_h, x, y, w, h, block_stride);
|
||||||
|
DEBUGRegionPrint(region);
|
||||||
|
|
||||||
|
DEBUGF("start_x %d start_y %d end_x %d end_y %d \n", start_x, start_y, end_x, end_y);
|
||||||
|
|
||||||
|
if (start_x >= end_x || start_y >= end_y) {
|
||||||
|
*n_region = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = end_x - start_x;
|
||||||
|
height = end_y - start_y;
|
||||||
|
start_block_x = (start_x - x)/ block_w;
|
||||||
|
start_block_y = (start_y - y)/ block_h;
|
||||||
|
end_block_x = (end_x - x)/ block_w;
|
||||||
|
end_block_y = (end_y - y)/ block_h;
|
||||||
|
|
||||||
|
clipped_regions = calloc((end_block_x - start_block_x + 1)
|
||||||
|
* (end_block_y - start_block_y + 1),
|
||||||
|
sizeof(*clipped_regions));
|
||||||
|
|
||||||
|
block_idx = (start_block_y - 1) * block_stride;
|
||||||
|
|
||||||
|
DEBUGF("startx %d starty %d endx %d endy %d \n",
|
||||||
|
start_x, start_y, end_x, end_y);
|
||||||
|
DEBUGF("start_block_x %d end_block_x %d \n", start_block_x, end_block_x);
|
||||||
|
DEBUGF("start_block_y %d end_block_y %d \n", start_block_y, end_block_y);
|
||||||
|
|
||||||
|
for(j = start_block_y; j <= end_block_y; j++)
|
||||||
|
{
|
||||||
|
block_idx += block_stride;
|
||||||
|
temp_block_idx = block_idx + start_block_x;
|
||||||
|
for(i = start_block_x;
|
||||||
|
i <= end_block_x; i++, temp_block_idx++)
|
||||||
|
{
|
||||||
|
BoxRec temp_box;
|
||||||
|
temp_box.x1 = x + i * block_w;
|
||||||
|
temp_box.y1 = y + j * block_h;
|
||||||
|
temp_box.x2 = MIN(temp_box.x1 + block_w, end_x);
|
||||||
|
temp_box.y2 = MIN(temp_box.y1 + block_h, end_y);
|
||||||
|
RegionInitBoxes(&temp_region, &temp_box, 1);
|
||||||
|
DEBUGF("block idx %d \n",temp_block_idx);
|
||||||
|
DEBUGRegionPrint(&temp_region);
|
||||||
|
current_region = RegionCreate(NULL, 4);
|
||||||
|
RegionIntersect(current_region, &temp_region, region);
|
||||||
|
DEBUGF("i %d j %d region: \n",i ,j);
|
||||||
|
DEBUGRegionPrint(current_region);
|
||||||
|
if (RegionNumRects(current_region)) {
|
||||||
|
clipped_regions[k].region = current_region;
|
||||||
|
clipped_regions[k].block_idx = temp_block_idx;
|
||||||
|
k++;
|
||||||
|
} else
|
||||||
|
RegionDestroy(current_region);
|
||||||
|
RegionUninit(&temp_region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*n_region = k;
|
||||||
|
return clipped_regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do a two round clipping,
|
||||||
|
* first is to clip the region regard to current pixmap's
|
||||||
|
* block array. Then for each clipped region, do a inner
|
||||||
|
* block clipping. This is to make sure the final result
|
||||||
|
* will be shapped by inner_block_w and inner_block_h, and
|
||||||
|
* the final region also will not cross the pixmap's block
|
||||||
|
* boundary.
|
||||||
|
*
|
||||||
|
* This is mainly used by transformation support when do
|
||||||
|
* compositing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
glamor_pixmap_clipped_regions *
|
||||||
|
glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
|
||||||
|
RegionPtr region,
|
||||||
|
int *n_region,
|
||||||
|
int inner_block_w, int inner_block_h)
|
||||||
|
{
|
||||||
|
glamor_pixmap_clipped_regions * clipped_regions, *inner_regions, *result_regions;
|
||||||
|
int i, j, x, y, k, inner_n_regions;
|
||||||
|
int width, height;
|
||||||
|
glamor_pixmap_private_large_t *priv;
|
||||||
|
priv = &pixmap_priv->large;
|
||||||
|
|
||||||
|
DEBUGF("ext called \n");
|
||||||
|
|
||||||
|
if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
|
||||||
|
clipped_regions = calloc(1, sizeof(*clipped_regions));
|
||||||
|
if (clipped_regions == NULL) {
|
||||||
|
*n_region = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
clipped_regions[0].region = RegionCreate(NULL, 1);
|
||||||
|
clipped_regions[0].block_idx = 0;
|
||||||
|
RegionCopy(clipped_regions[0].region, region);
|
||||||
|
*n_region = 1;
|
||||||
|
priv->block_w = priv->base.pixmap->drawable.width;
|
||||||
|
priv->block_h = priv->base.pixmap->drawable.height;
|
||||||
|
priv->box_array = &priv->box;
|
||||||
|
priv->box.x1 = priv->box.y1 = 0;
|
||||||
|
priv->box.x2 = priv->block_w;
|
||||||
|
priv->box.y2 = priv->block_h;
|
||||||
|
} else {
|
||||||
|
clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
|
||||||
|
priv->block_h,
|
||||||
|
priv->block_wcnt,
|
||||||
|
0, 0,
|
||||||
|
priv->base.pixmap->drawable.width,
|
||||||
|
priv->base.pixmap->drawable.height,
|
||||||
|
region, n_region, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (clipped_regions == NULL) {
|
||||||
|
*n_region = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (inner_block_w >= priv->block_w
|
||||||
|
&& inner_block_h >= priv->block_h)
|
||||||
|
return clipped_regions;
|
||||||
|
result_regions = calloc(*n_region
|
||||||
|
* ((priv->block_w + inner_block_w - 1)/inner_block_w)
|
||||||
|
* ((priv->block_h + inner_block_h - 1)/ inner_block_h),
|
||||||
|
sizeof(*result_regions));
|
||||||
|
k = 0;
|
||||||
|
for(i = 0; i < *n_region; i++)
|
||||||
|
{
|
||||||
|
x = priv->box_array[clipped_regions[i].block_idx].x1;
|
||||||
|
y = priv->box_array[clipped_regions[i].block_idx].y1;
|
||||||
|
width = priv->box_array[clipped_regions[i].block_idx].x2 - x;
|
||||||
|
height = priv->box_array[clipped_regions[i].block_idx].y2 - y;
|
||||||
|
inner_regions = __glamor_compute_clipped_regions(inner_block_w,
|
||||||
|
inner_block_h,
|
||||||
|
0, x, y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
clipped_regions[i].region,
|
||||||
|
&inner_n_regions, 0);
|
||||||
|
for(j = 0; j < inner_n_regions; j++)
|
||||||
|
{
|
||||||
|
result_regions[k].region = inner_regions[j].region;
|
||||||
|
result_regions[k].block_idx = clipped_regions[i].block_idx;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
free(inner_regions);
|
||||||
|
}
|
||||||
|
*n_region = k;
|
||||||
|
free(clipped_regions);
|
||||||
|
return result_regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clip the boxes regards to each pixmap's block array.
|
||||||
|
*
|
||||||
|
* Should translate the region to relative coords to the pixmap,
|
||||||
|
* start at (0,0).
|
||||||
|
*
|
||||||
|
* @is_transform: if it is set, it has a transform matrix.
|
||||||
|
*
|
||||||
|
* XXX Not support repeatPad currently.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static glamor_pixmap_clipped_regions *
|
||||||
|
_glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
||||||
|
RegionPtr region, int *n_region,
|
||||||
|
int repeat_type, int is_transform)
|
||||||
|
{
|
||||||
|
glamor_pixmap_clipped_regions * clipped_regions;
|
||||||
|
BoxPtr extent;
|
||||||
|
int i, j;
|
||||||
|
int width, height;
|
||||||
|
RegionPtr current_region;
|
||||||
|
int pixmap_width, pixmap_height;
|
||||||
|
int m;
|
||||||
|
BoxRec repeat_box;
|
||||||
|
RegionRec repeat_region;
|
||||||
|
int right_shift = 0;
|
||||||
|
int down_shift = 0;
|
||||||
|
int x_center_shift = 0, y_center_shift = 0;
|
||||||
|
glamor_pixmap_private_large_t *priv;
|
||||||
|
priv = &pixmap_priv->large;
|
||||||
|
|
||||||
|
DEBUGRegionPrint(region);
|
||||||
|
if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
|
||||||
|
clipped_regions = calloc(1, sizeof(*clipped_regions));
|
||||||
|
clipped_regions[0].region = RegionCreate(NULL, 1);
|
||||||
|
clipped_regions[0].block_idx = 0;
|
||||||
|
RegionCopy(clipped_regions[0].region, region);
|
||||||
|
*n_region = 1;
|
||||||
|
return clipped_regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixmap_width = priv->base.pixmap->drawable.width;
|
||||||
|
pixmap_height = priv->base.pixmap->drawable.height;
|
||||||
|
if (repeat_type == 0) {
|
||||||
|
clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
|
||||||
|
priv->block_h,
|
||||||
|
priv->block_wcnt,
|
||||||
|
0, 0,
|
||||||
|
priv->base.pixmap->drawable.width,
|
||||||
|
priv->base.pixmap->drawable.height,
|
||||||
|
region, n_region, 0
|
||||||
|
);
|
||||||
|
return clipped_regions;
|
||||||
|
} else if (repeat_type != RepeatNormal) {
|
||||||
|
*n_region = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
extent = RegionExtents(region);
|
||||||
|
|
||||||
|
x_center_shift = extent->x1 / pixmap_width;
|
||||||
|
if (x_center_shift < 0)
|
||||||
|
x_center_shift--;
|
||||||
|
if (abs(x_center_shift) & 1)
|
||||||
|
x_center_shift++;
|
||||||
|
y_center_shift = extent->y1 / pixmap_height;
|
||||||
|
if (y_center_shift < 0)
|
||||||
|
y_center_shift--;
|
||||||
|
if (abs(y_center_shift) & 1)
|
||||||
|
y_center_shift++;
|
||||||
|
|
||||||
|
if (extent->x1 < 0)
|
||||||
|
right_shift = ((-extent->x1 + pixmap_width - 1) / pixmap_width );
|
||||||
|
if (extent->y1 < 0)
|
||||||
|
down_shift = ((-extent->y1 + pixmap_height - 1) / pixmap_height );
|
||||||
|
|
||||||
|
if (right_shift != 0 || down_shift != 0) {
|
||||||
|
if (repeat_type == RepeatReflect) {
|
||||||
|
right_shift = (right_shift + 1)&~1;
|
||||||
|
down_shift = (down_shift + 1)&~1;
|
||||||
|
}
|
||||||
|
RegionTranslate(region, right_shift * pixmap_width, down_shift * pixmap_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
extent = RegionExtents(region);
|
||||||
|
width = extent->x2 - extent->x1;
|
||||||
|
height = extent->y2 - extent->y1;
|
||||||
|
/* Tile a large pixmap to another large pixmap.
|
||||||
|
* We can't use the target large pixmap as the
|
||||||
|
* loop variable, instead we need to loop for all
|
||||||
|
* the blocks in the tile pixmap.
|
||||||
|
*
|
||||||
|
* simulate repeat each single block to cover the
|
||||||
|
* target's blocks. Two special case:
|
||||||
|
* a block_wcnt == 1 or block_hcnt ==1, then we
|
||||||
|
* only need to loop one direction as the other
|
||||||
|
* direction is fully included in the first block.
|
||||||
|
*
|
||||||
|
* For the other cases, just need to start
|
||||||
|
* from a proper shiftx/shifty, and then increase
|
||||||
|
* y by tile_height each time to walk trhough the
|
||||||
|
* target block and then walk trhough the target
|
||||||
|
* at x direction by increate tile_width each time.
|
||||||
|
*
|
||||||
|
* This way, we can consolidate all the sub blocks
|
||||||
|
* of the target boxes into one tile source's block.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
m = 0;
|
||||||
|
clipped_regions = calloc(priv->block_wcnt * priv->block_hcnt,
|
||||||
|
sizeof(*clipped_regions));
|
||||||
|
if (clipped_regions == NULL) {
|
||||||
|
*n_region = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (right_shift != 0 || down_shift != 0) {
|
||||||
|
DEBUGF("region to be repeated shifted \n");
|
||||||
|
DEBUGRegionPrint(region);
|
||||||
|
}
|
||||||
|
DEBUGF("repeat pixmap width %d height %d \n", pixmap_width, pixmap_height);
|
||||||
|
DEBUGF("extent x1 %d y1 %d x2 %d y2 %d \n", extent->x1, extent->y1, extent->x2, extent->y2);
|
||||||
|
for(j = 0; j < priv->block_hcnt; j++)
|
||||||
|
{
|
||||||
|
for(i = 0; i < priv->block_wcnt; i++)
|
||||||
|
{
|
||||||
|
int dx = pixmap_width;
|
||||||
|
int dy = pixmap_height;
|
||||||
|
int idx;
|
||||||
|
int shift_x;
|
||||||
|
int shift_y;
|
||||||
|
int saved_y1, saved_y2;
|
||||||
|
int x_idx = 0, y_idx = 0;
|
||||||
|
RegionRec temp_region;
|
||||||
|
|
||||||
|
shift_x = (extent->x1 / pixmap_width) * pixmap_width;
|
||||||
|
shift_y = (extent->y1 / pixmap_height) * pixmap_height;
|
||||||
|
idx = j * priv->block_wcnt + i;
|
||||||
|
if (repeat_type == RepeatReflect) {
|
||||||
|
x_idx = (extent->x1 / pixmap_width);
|
||||||
|
y_idx = (extent->y1 / pixmap_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Construct a rect to clip the target region. */
|
||||||
|
repeat_box.x1 = shift_x + priv->box_array[idx].x1;
|
||||||
|
repeat_box.y1 = shift_y + priv->box_array[idx].y1;
|
||||||
|
if (priv->block_wcnt == 1)
|
||||||
|
repeat_box.x2 = extent->x2;
|
||||||
|
else
|
||||||
|
repeat_box.x2 = shift_x + priv->box_array[idx].x2;
|
||||||
|
if (priv->block_hcnt == 1)
|
||||||
|
repeat_box.y2 = extent->y2;
|
||||||
|
else
|
||||||
|
repeat_box.y2 = shift_y + priv->box_array[idx].y2;
|
||||||
|
|
||||||
|
current_region = RegionCreate(NULL, 4);
|
||||||
|
RegionInit(&temp_region, NULL, 4);
|
||||||
|
DEBUGF("init repeat box %d %d %d %d \n",
|
||||||
|
repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2);
|
||||||
|
|
||||||
|
if (repeat_type == RepeatNormal) {
|
||||||
|
saved_y1 = repeat_box.y1;
|
||||||
|
saved_y2 = repeat_box.y2;
|
||||||
|
for(; repeat_box.x1 < extent->x2;
|
||||||
|
repeat_box.x1 += dx, repeat_box.x2 += dx)
|
||||||
|
{
|
||||||
|
repeat_box.y1 = saved_y1;
|
||||||
|
repeat_box.y2 = saved_y2;
|
||||||
|
for( repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2;
|
||||||
|
repeat_box.y1 < extent->y2;
|
||||||
|
repeat_box.y1 += dy, repeat_box.y2 += dy)
|
||||||
|
{
|
||||||
|
|
||||||
|
RegionInitBoxes(&repeat_region, &repeat_box, 1);
|
||||||
|
DEBUGF("Start to clip repeat region: \n");
|
||||||
|
DEBUGRegionPrint(&repeat_region);
|
||||||
|
RegionIntersect(&temp_region, &repeat_region, region);
|
||||||
|
DEBUGF("clip result:\n");
|
||||||
|
DEBUGRegionPrint(&temp_region);
|
||||||
|
RegionAppend(current_region, &temp_region);
|
||||||
|
RegionUninit(&repeat_region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUGF("dx %d dy %d \n", dx, dy);
|
||||||
|
|
||||||
|
if (RegionNumRects(current_region)) {
|
||||||
|
|
||||||
|
if ((right_shift != 0 || down_shift != 0))
|
||||||
|
RegionTranslate(current_region,
|
||||||
|
-right_shift * pixmap_width,
|
||||||
|
-down_shift * pixmap_height);
|
||||||
|
clipped_regions[m].region = current_region;
|
||||||
|
clipped_regions[m].block_idx = idx;
|
||||||
|
m++;
|
||||||
|
} else
|
||||||
|
RegionDestroy(current_region);
|
||||||
|
RegionUninit(&temp_region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right_shift != 0 || down_shift != 0)
|
||||||
|
RegionTranslate(region, -right_shift * pixmap_width, -down_shift * pixmap_height);
|
||||||
|
*n_region = m;
|
||||||
|
|
||||||
|
return clipped_regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_pixmap_clipped_regions *
|
||||||
|
glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, int *n_region, int repeat_type)
|
||||||
|
{
|
||||||
|
return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, 0);
|
||||||
|
}
|
|
@ -83,9 +83,11 @@ glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0, int w
|
||||||
void
|
void
|
||||||
glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
|
glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
|
||||||
{
|
{
|
||||||
|
int w,h;
|
||||||
|
|
||||||
|
PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h);
|
||||||
glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0,
|
glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0,
|
||||||
pixmap_priv->base.pixmap->drawable.width,
|
w, h);
|
||||||
pixmap_priv->base.pixmap->drawable.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -489,16 +491,23 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, GLenum ty
|
||||||
}
|
}
|
||||||
|
|
||||||
ready_to_upload:
|
ready_to_upload:
|
||||||
|
|
||||||
/* Try fast path firstly, upload the pixmap to the texture attached
|
/* Try fast path firstly, upload the pixmap to the texture attached
|
||||||
* to the fbo directly. */
|
* to the fbo directly. */
|
||||||
if (no_alpha == 0
|
if (no_alpha == 0
|
||||||
&& revert == REVERT_NONE
|
&& revert == REVERT_NONE
|
||||||
&& swap_rb == SWAP_NONE_UPLOADING
|
&& swap_rb == SWAP_NONE_UPLOADING
|
||||||
&& !need_flip) {
|
&& !need_flip) {
|
||||||
|
int fbo_x_off, fbo_y_off;
|
||||||
assert(pixmap_priv->base.fbo->tex);
|
assert(pixmap_priv->base.fbo->tex);
|
||||||
|
pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
|
||||||
|
|
||||||
|
assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
|
||||||
|
assert(x + fbo_x_off + w <= pixmap_priv->base.fbo->width);
|
||||||
|
assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height);
|
||||||
__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
|
__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
|
||||||
format, type,
|
format, type,
|
||||||
x, y, w, h,
|
x + fbo_x_off, y + fbo_y_off, w, h,
|
||||||
bits, pbo);
|
bits, pbo);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -515,7 +524,6 @@ ready_to_upload:
|
||||||
x + w, y + h,
|
x + w, y + h,
|
||||||
glamor_priv->yInverted,
|
glamor_priv->yInverted,
|
||||||
vertices);
|
vertices);
|
||||||
|
|
||||||
/* Slow path, we need to flip y or wire alpha to 1. */
|
/* Slow path, we need to flip y or wire alpha to 1. */
|
||||||
dispatch = glamor_get_dispatch(glamor_priv);
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||||
|
@ -586,6 +594,9 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
|
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||||
|
|
||||||
|
if (pixmap_priv->base.gl_fbo)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (pixmap_priv->base.fbo
|
if (pixmap_priv->base.fbo
|
||||||
&& (pixmap_priv->base.fbo->width < pixmap->drawable.width
|
&& (pixmap_priv->base.fbo->width < pixmap->drawable.width
|
||||||
|| pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
|
|| pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
|
||||||
|
@ -605,8 +616,10 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
|
||||||
flag = GLAMOR_CREATE_FBO_NO_FBO;
|
flag = GLAMOR_CREATE_FBO_NO_FBO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flag == 0 && pixmap_priv && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
|
if ((flag == GLAMOR_CREATE_FBO_NO_FBO
|
||||||
|| (flag != 0 && pixmap_priv && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
|
&& pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
|
||||||
|
|| (flag == 0
|
||||||
|
&& pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
|
||||||
|
@ -614,35 +627,63 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
|
||||||
else
|
else
|
||||||
iformat = format;
|
iformat = format;
|
||||||
|
|
||||||
if (pixmap_priv == NULL || pixmap_priv->base.fbo == NULL) {
|
if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
|
||||||
|
return -1;
|
||||||
fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
|
|
||||||
pixmap->drawable.height,
|
|
||||||
iformat,
|
|
||||||
flag);
|
|
||||||
if (fbo == NULL) {
|
|
||||||
glamor_fallback
|
|
||||||
("upload failed, depth %d x %d @depth %d \n",
|
|
||||||
pixmap->drawable.width, pixmap->drawable.height,
|
|
||||||
pixmap->drawable.depth);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_pixmap_attach_fbo(pixmap, fbo);
|
|
||||||
} else {
|
|
||||||
/* We do have a fbo, but it may lack of fb or tex. */
|
|
||||||
glamor_pixmap_ensure_fbo(pixmap, iformat, flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* upload sub region to a large region.
|
||||||
|
* */
|
||||||
|
static void
|
||||||
|
glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits,
|
||||||
|
int src_stride, int bpp,
|
||||||
|
int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
int byte_per_pixel;
|
||||||
|
|
||||||
|
byte_per_pixel = bpp / 8;
|
||||||
|
src_bits += y * src_stride + (x * byte_per_pixel);
|
||||||
|
|
||||||
|
for(j = y; j < y + h; j++)
|
||||||
|
{
|
||||||
|
memcpy(dst_bits, src_bits, w * byte_per_pixel);
|
||||||
|
src_bits += src_stride;
|
||||||
|
dst_bits += dst_stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* download sub region from a large region.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
glamor_get_bits(char *dst_bits, int dst_stride, char *src_bits,
|
||||||
|
int src_stride, int bpp,
|
||||||
|
int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
int byte_per_pixel;
|
||||||
|
|
||||||
|
byte_per_pixel = bpp / 8;
|
||||||
|
dst_bits += y * dst_stride + x * byte_per_pixel;
|
||||||
|
|
||||||
|
for(j = y; j < y + h; j++)
|
||||||
|
{
|
||||||
|
memcpy(dst_bits, src_bits, w * byte_per_pixel);
|
||||||
|
src_bits += src_stride;
|
||||||
|
dst_bits += dst_stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h,
|
glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||||
int stride, void *bits, int pbo)
|
int stride, void *bits, int pbo)
|
||||||
{
|
{
|
||||||
GLenum format, type;
|
GLenum format, type;
|
||||||
int no_alpha, revert, swap_rb;
|
int no_alpha, revert, swap_rb;
|
||||||
|
glamor_pixmap_private *pixmap_priv;
|
||||||
|
|
||||||
if (glamor_get_tex_format_type_from_pixmap(pixmap,
|
if (glamor_get_tex_format_type_from_pixmap(pixmap,
|
||||||
&format,
|
&format,
|
||||||
|
@ -657,7 +698,77 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h
|
||||||
if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
|
if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha, revert, swap_rb,
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
RegionRec region;
|
||||||
|
BoxRec box;
|
||||||
|
int n_region;
|
||||||
|
glamor_pixmap_clipped_regions *clipped_regions;
|
||||||
|
void *sub_bits;
|
||||||
|
int i,j;
|
||||||
|
|
||||||
|
sub_bits = malloc(h * stride);
|
||||||
|
if (sub_bits == NULL)
|
||||||
|
return FALSE;
|
||||||
|
box.x1 = x;
|
||||||
|
box.y1 = y;
|
||||||
|
box.x2 = x + w;
|
||||||
|
box.y2 = y + h;
|
||||||
|
RegionInitBoxes(®ion, &box, 1);
|
||||||
|
clipped_regions = glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region, 0);
|
||||||
|
DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
|
||||||
|
for(i = 0; i < n_region; i++)
|
||||||
|
{
|
||||||
|
BoxPtr boxes;
|
||||||
|
int nbox;
|
||||||
|
int temp_stride;
|
||||||
|
void *temp_bits;
|
||||||
|
|
||||||
|
assert(pbo == 0);
|
||||||
|
|
||||||
|
SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
|
||||||
|
|
||||||
|
boxes = RegionRects(clipped_regions[i].region);
|
||||||
|
nbox = RegionNumRects(clipped_regions[i].region);
|
||||||
|
DEBUGF("split to %d boxes\n", nbox);
|
||||||
|
for(j = 0; j < nbox; j++)
|
||||||
|
{
|
||||||
|
temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
|
||||||
|
pixmap->drawable.depth);
|
||||||
|
|
||||||
|
if (boxes[j].x1 == x && temp_stride == stride) {
|
||||||
|
temp_bits = (char*)bits + (boxes[j].y1 - y) * stride;
|
||||||
|
} else {
|
||||||
|
temp_bits = sub_bits;
|
||||||
|
glamor_put_bits(temp_bits, temp_stride, bits, stride,
|
||||||
|
pixmap->drawable.bitsPerPixel,
|
||||||
|
boxes[j].x1 - x, boxes[j].y1 - y,
|
||||||
|
boxes[j].x2 - boxes[j].x1,
|
||||||
|
boxes[j].y2 - boxes[j].y1);
|
||||||
|
}
|
||||||
|
DEBUGF("upload x %d y %d w %d h %d temp stride %d \n",
|
||||||
|
boxes[j].x1 - x, boxes[j].y1 - y,
|
||||||
|
boxes[j].x2 - boxes[j].x1,
|
||||||
|
boxes[j].y2 - boxes[j].y1, temp_stride);
|
||||||
|
if (_glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha,
|
||||||
|
revert, swap_rb, boxes[j].x1, boxes[j].y1,
|
||||||
|
boxes[j].x2 - boxes[j].x1,
|
||||||
|
boxes[j].y2 - boxes[j].y1,
|
||||||
|
temp_stride, temp_bits, pbo) == FALSE) {
|
||||||
|
RegionUninit(®ion);
|
||||||
|
free(sub_bits);
|
||||||
|
assert(0);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RegionDestroy(clipped_regions[i].region);
|
||||||
|
}
|
||||||
|
free(sub_bits);
|
||||||
|
free(clipped_regions);
|
||||||
|
RegionUninit(®ion);
|
||||||
|
return TRUE;
|
||||||
|
} else
|
||||||
|
return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha, revert, swap_rb,
|
||||||
x, y, w, h, stride, bits, pbo);
|
x, y, w, h, stride, bits, pbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,8 +782,7 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
|
||||||
if (pixmap_priv
|
if ((pixmap_priv->base.fbo)
|
||||||
&& (pixmap_priv->base.fbo)
|
|
||||||
&& (pixmap_priv->base.fbo->pbo_valid)) {
|
&& (pixmap_priv->base.fbo->pbo_valid)) {
|
||||||
data = NULL;
|
data = NULL;
|
||||||
pbo = pixmap_priv->base.fbo->pbo;
|
pbo = pixmap_priv->base.fbo->pbo;
|
||||||
|
@ -737,7 +847,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
|
||||||
temp_xscale = 1.0 / w;
|
temp_xscale = 1.0 / w;
|
||||||
temp_yscale = 1.0 / h;
|
temp_yscale = 1.0 / h;
|
||||||
|
|
||||||
glamor_set_normalize_vcoords((glamor_pixmap_private *)NULL, temp_xscale,
|
glamor_set_normalize_vcoords((struct glamor_pixmap_private*)NULL,temp_xscale,
|
||||||
temp_yscale,
|
temp_yscale,
|
||||||
0, 0,
|
0, 0,
|
||||||
w, h,
|
w, h,
|
||||||
|
@ -793,13 +903,15 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
|
||||||
* The pixmap must have a valid FBO, otherwise return a NULL.
|
* The pixmap must have a valid FBO, otherwise return a NULL.
|
||||||
* */
|
* */
|
||||||
|
|
||||||
void *
|
static void *
|
||||||
glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
_glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
|
||||||
int stride, void *bits, int pbo, glamor_access_t access)
|
GLenum type, int no_alpha,
|
||||||
|
int revert, int swap_rb,
|
||||||
|
int x, int y, int w, int h,
|
||||||
|
int stride, void *bits, int pbo, glamor_access_t access)
|
||||||
{
|
{
|
||||||
glamor_pixmap_private *pixmap_priv;
|
glamor_pixmap_private *pixmap_priv;
|
||||||
GLenum format, type, gl_access = 0, gl_usage = 0;
|
GLenum gl_access = 0, gl_usage = 0;
|
||||||
int no_alpha, revert, swap_rb;
|
|
||||||
void *data, *read;
|
void *data, *read;
|
||||||
ScreenPtr screen;
|
ScreenPtr screen;
|
||||||
glamor_screen_private *glamor_priv =
|
glamor_screen_private *glamor_priv =
|
||||||
|
@ -808,6 +920,7 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||||
glamor_pixmap_fbo *temp_fbo = NULL;
|
glamor_pixmap_fbo *temp_fbo = NULL;
|
||||||
int need_post_conversion = 0;
|
int need_post_conversion = 0;
|
||||||
int need_free_data = 0;
|
int need_free_data = 0;
|
||||||
|
int fbo_x_off, fbo_y_off;
|
||||||
|
|
||||||
data = bits;
|
data = bits;
|
||||||
screen = pixmap->drawable.pScreen;
|
screen = pixmap->drawable.pScreen;
|
||||||
|
@ -831,18 +944,6 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glamor_get_tex_format_type_from_pixmap(pixmap,
|
|
||||||
&format,
|
|
||||||
&type,
|
|
||||||
&no_alpha,
|
|
||||||
&revert,
|
|
||||||
&swap_rb, 0)) {
|
|
||||||
ErrorF("Unknown pixmap depth %d.\n",
|
|
||||||
pixmap->drawable.depth);
|
|
||||||
assert(0); // Should never happen.
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
||||||
|
|
||||||
need_post_conversion = (revert > REVERT_NORMAL);
|
need_post_conversion = (revert > REVERT_NORMAL);
|
||||||
|
@ -857,6 +958,8 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
|
||||||
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
|
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
|
||||||
&& !need_post_conversion
|
&& !need_post_conversion
|
||||||
&& (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
|
&& (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
|
||||||
|
@ -868,6 +971,8 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||||
}
|
}
|
||||||
x = 0;
|
x = 0;
|
||||||
y = 0;
|
y = 0;
|
||||||
|
fbo_x_off = 0;
|
||||||
|
fbo_y_off = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch = glamor_get_dispatch(glamor_priv);
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
|
@ -890,7 +995,7 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||||
NULL, gl_usage);
|
NULL, gl_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch->glReadPixels(x, y, w, h, format, type, data);
|
dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data);
|
||||||
|
|
||||||
if (!glamor_priv->yInverted) {
|
if (!glamor_priv->yInverted) {
|
||||||
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
|
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
|
||||||
|
@ -913,7 +1018,7 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||||
stride *
|
stride *
|
||||||
h,
|
h,
|
||||||
NULL, GL_STREAM_READ);
|
NULL, GL_STREAM_READ);
|
||||||
dispatch->glReadPixels(0, 0, w, h,
|
dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h,
|
||||||
format, type, 0);
|
format, type, 0);
|
||||||
read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
|
read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
|
||||||
GL_READ_ONLY);
|
GL_READ_ONLY);
|
||||||
|
@ -946,6 +1051,107 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
||||||
|
int stride, void *bits, int pbo, glamor_access_t access)
|
||||||
|
{
|
||||||
|
GLenum format, type;
|
||||||
|
int no_alpha, revert, swap_rb;
|
||||||
|
glamor_pixmap_private *pixmap_priv;
|
||||||
|
|
||||||
|
if (glamor_get_tex_format_type_from_pixmap(pixmap,
|
||||||
|
&format,
|
||||||
|
&type,
|
||||||
|
&no_alpha,
|
||||||
|
&revert,
|
||||||
|
&swap_rb, 1)) {
|
||||||
|
glamor_fallback("Unknown pixmap depth %d.\n",
|
||||||
|
pixmap->drawable.depth);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
|
||||||
|
RegionRec region;
|
||||||
|
BoxRec box;
|
||||||
|
int n_region;
|
||||||
|
glamor_pixmap_clipped_regions *clipped_regions;
|
||||||
|
void *sub_bits;
|
||||||
|
int i,j;
|
||||||
|
|
||||||
|
sub_bits = malloc(h * stride);
|
||||||
|
if (sub_bits == NULL)
|
||||||
|
return FALSE;
|
||||||
|
box.x1 = x;
|
||||||
|
box.y1 = y;
|
||||||
|
box.x2 = x + w;
|
||||||
|
box.y2 = y + h;
|
||||||
|
RegionInitBoxes(®ion, &box, 1);
|
||||||
|
clipped_regions = glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region, 0);
|
||||||
|
DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h);
|
||||||
|
for(i = 0; i < n_region; i++)
|
||||||
|
{
|
||||||
|
BoxPtr boxes;
|
||||||
|
int nbox;
|
||||||
|
int temp_stride;
|
||||||
|
void *temp_bits;
|
||||||
|
|
||||||
|
assert(pbo == 0);
|
||||||
|
SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
|
||||||
|
|
||||||
|
boxes = RegionRects(clipped_regions[i].region);
|
||||||
|
nbox = RegionNumRects(clipped_regions[i].region);
|
||||||
|
for(j = 0; j < nbox; j++)
|
||||||
|
{
|
||||||
|
temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
|
||||||
|
pixmap->drawable.depth);
|
||||||
|
|
||||||
|
if (boxes[j].x1 == x && temp_stride == stride) {
|
||||||
|
temp_bits = (char*)bits + (boxes[j].y1 - y) * stride;
|
||||||
|
} else {
|
||||||
|
temp_bits = sub_bits;
|
||||||
|
}
|
||||||
|
DEBUGF("download x %d y %d w %d h %d temp stride %d \n",
|
||||||
|
boxes[j].x1, boxes[j].y1,
|
||||||
|
boxes[j].x2 - boxes[j].x1,
|
||||||
|
boxes[j].y2 - boxes[j].y1, temp_stride);
|
||||||
|
|
||||||
|
/* For large pixmap, we don't support pbo currently.*/
|
||||||
|
assert(pbo == 0);
|
||||||
|
if (_glamor_download_sub_pixmap_to_cpu(pixmap, format, type, no_alpha,
|
||||||
|
revert, swap_rb, boxes[j].x1, boxes[j].y1,
|
||||||
|
boxes[j].x2 - boxes[j].x1,
|
||||||
|
boxes[j].y2 - boxes[j].y1,
|
||||||
|
temp_stride, temp_bits, pbo, access) == FALSE) {
|
||||||
|
RegionUninit(®ion);
|
||||||
|
free(sub_bits);
|
||||||
|
assert(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (boxes[j].x1 != x || temp_stride != stride)
|
||||||
|
glamor_get_bits(bits, stride, temp_bits, temp_stride,
|
||||||
|
pixmap->drawable.bitsPerPixel,
|
||||||
|
boxes[j].x1 - x , boxes[j].y1 - y,
|
||||||
|
boxes[j].x2 - boxes[j].x1,
|
||||||
|
boxes[j].y2 - boxes[j].y1);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionDestroy(clipped_regions[i].region);
|
||||||
|
}
|
||||||
|
free(sub_bits);
|
||||||
|
free(clipped_regions);
|
||||||
|
RegionUninit(®ion);
|
||||||
|
return bits;
|
||||||
|
} else
|
||||||
|
return _glamor_download_sub_pixmap_to_cpu(pixmap, format, type, no_alpha, revert, swap_rb,
|
||||||
|
x, y, w, h, stride,
|
||||||
|
bits, pbo, access);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move a pixmap to CPU memory.
|
* Move a pixmap to CPU memory.
|
||||||
|
@ -984,7 +1190,8 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
||||||
|
|
||||||
if (access == GLAMOR_ACCESS_WO
|
if (access == GLAMOR_ACCESS_WO
|
||||||
|| glamor_priv->gl_flavor == GLAMOR_GL_ES2
|
|| glamor_priv->gl_flavor == GLAMOR_GL_ES2
|
||||||
|| (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)) {
|
|| (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)
|
||||||
|
|| pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
data = malloc(stride * pixmap->drawable.height);
|
data = malloc(stride * pixmap->drawable.height);
|
||||||
} else {
|
} else {
|
||||||
dispatch = glamor_get_dispatch(glamor_priv);
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
|
@ -1024,6 +1231,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fixup a fbo to the exact size as the pixmap. */
|
/* fixup a fbo to the exact size as the pixmap. */
|
||||||
|
/* XXX LARGE pixmap? */
|
||||||
Bool
|
Bool
|
||||||
glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
|
glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
|
||||||
{
|
{
|
||||||
|
@ -1038,8 +1246,7 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
|
||||||
|
|
||||||
drawable = &pixmap_priv->base.pixmap->drawable;
|
drawable = &pixmap_priv->base.pixmap->drawable;
|
||||||
|
|
||||||
if (pixmap_priv->base.pixmap->drawable.width == pixmap_priv->base.fbo->width
|
if (!GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))
|
||||||
&& pixmap_priv->base.pixmap->drawable.height == pixmap_priv->base.fbo->height)
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
old_fbo = pixmap_priv->base.fbo;
|
old_fbo = pixmap_priv->base.fbo;
|
||||||
|
@ -1058,7 +1265,7 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
|
||||||
|
|
||||||
scratch_priv = glamor_get_pixmap_private(scratch);
|
scratch_priv = glamor_get_pixmap_private(scratch);
|
||||||
|
|
||||||
if (!scratch_priv || !scratch_priv->base.fbo)
|
if (!scratch_priv->base.fbo)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
ValidateGC(&scratch->drawable, gc);
|
ValidateGC(&scratch->drawable, gc);
|
||||||
|
@ -1111,14 +1318,13 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
|
||||||
void *data;
|
void *data;
|
||||||
int pbo;
|
int pbo;
|
||||||
int flag;
|
int flag;
|
||||||
|
if (x < 0 || y < 0)
|
||||||
assert(x >= 0 && y >= 0);
|
return NULL;
|
||||||
w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
|
w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
|
||||||
h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
|
h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
|
||||||
if (access == GLAMOR_ACCESS_WO) {
|
if (access == GLAMOR_ACCESS_WO) {
|
||||||
sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
|
sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
|
||||||
pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
|
pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
|
||||||
ErrorF("WO\n");
|
|
||||||
return sub_pixmap;
|
return sub_pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1127,7 +1333,7 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2)
|
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 || pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
|
||||||
flag = GLAMOR_CREATE_PIXMAP_CPU;
|
flag = GLAMOR_CREATE_PIXMAP_CPU;
|
||||||
else
|
else
|
||||||
flag = GLAMOR_CREATE_PIXMAP_MAP;
|
flag = GLAMOR_CREATE_PIXMAP_MAP;
|
||||||
|
@ -1141,17 +1347,16 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
|
||||||
sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
|
sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
|
||||||
pbo = sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base.fbo->pbo : 0): 0;
|
pbo = sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base.fbo->pbo : 0): 0;
|
||||||
|
|
||||||
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
|
if (pixmap_priv->base.is_picture) {
|
||||||
sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
|
sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
|
||||||
sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
|
sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pbo)
|
if (pbo)
|
||||||
data = NULL;
|
data = NULL;
|
||||||
else {
|
else
|
||||||
data = sub_pixmap->devPrivate.ptr;
|
data = sub_pixmap->devPrivate.ptr;
|
||||||
assert(flag != GLAMOR_CREATE_PIXMAP_MAP);
|
|
||||||
}
|
|
||||||
data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, sub_pixmap->devKind,
|
data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, sub_pixmap->devKind,
|
||||||
data, pbo, access);
|
data, pbo, access);
|
||||||
if (pbo) {
|
if (pbo) {
|
||||||
|
@ -1173,7 +1378,7 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
|
||||||
|
|
||||||
new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
|
new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
|
||||||
pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
|
pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
|
||||||
glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap, NULL, &box, 1, dx, dy, 0, 0, 0, NULL);
|
glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap->drawable, NULL, &box, 1, dx, dy, 0, 0, 0, NULL);
|
||||||
glamor_compare_pixmaps(new_sub_pixmap, sub_pixmap, 0, 0, w, h, 1, 1);
|
glamor_compare_pixmaps(new_sub_pixmap, sub_pixmap, 0, 0, w, h, 1, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1188,8 +1393,7 @@ glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int
|
||||||
glamor_pixmap_private *sub_pixmap_priv;
|
glamor_pixmap_private *sub_pixmap_priv;
|
||||||
if (access != GLAMOR_ACCESS_RO) {
|
if (access != GLAMOR_ACCESS_RO) {
|
||||||
sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
|
sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
|
||||||
if (sub_pixmap_priv
|
if (sub_pixmap_priv->base.fbo
|
||||||
&& sub_pixmap_priv->base.fbo
|
|
||||||
&& sub_pixmap_priv->base.fbo->pbo_valid) {
|
&& sub_pixmap_priv->base.fbo->pbo_valid) {
|
||||||
bits = NULL;
|
bits = NULL;
|
||||||
pbo = sub_pixmap_priv->base.fbo->pbo;
|
pbo = sub_pixmap_priv->base.fbo->pbo;
|
||||||
|
|
|
@ -927,6 +927,9 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
|
||||||
#ifndef GLAMOR_GLES2
|
#ifndef GLAMOR_GLES2
|
||||||
#define GLAMOR_GRADIENT_SHADER
|
#define GLAMOR_GRADIENT_SHADER
|
||||||
#endif
|
#endif
|
||||||
#define GLAMOR_TEXTURED_LARGE_PIXMAP 1
|
#define GLAMOR_TEXTURED_LARGE_PIXMAP 0
|
||||||
|
#if 0
|
||||||
|
#define MAX_FBO_SIZE 512 /* For test purpose only. */
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* GLAMOR_PRIV_H */
|
#endif /* GLAMOR_PRIV_H */
|
||||||
|
|
|
@ -37,7 +37,12 @@
|
||||||
#ifdef RENDER
|
#ifdef RENDER
|
||||||
#include "mipict.h"
|
#include "mipict.h"
|
||||||
#include "fbpict.h"
|
#include "fbpict.h"
|
||||||
|
#if 0
|
||||||
|
//#define DEBUGF(str, ...) do {} while(0)
|
||||||
|
#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__)
|
||||||
|
//#define DEBUGRegionPrint(x) do {} while (0)
|
||||||
|
#define DEBUGRegionPrint RegionPrint
|
||||||
|
#endif
|
||||||
struct shader_key {
|
struct shader_key {
|
||||||
enum shader_source source;
|
enum shader_source source;
|
||||||
enum shader_mask mask;
|
enum shader_mask mask;
|
||||||
|
@ -606,18 +611,20 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
|
||||||
#endif
|
#endif
|
||||||
/* XXX may be we can eaxctly check whether we need to touch
|
/* XXX may be we can eaxctly check whether we need to touch
|
||||||
* the out-of-box area then determine whether we need to fix.
|
* the out-of-box area then determine whether we need to fix.
|
||||||
* */
|
**/
|
||||||
if (repeat_type != RepeatNone)
|
/*if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE)*/ {
|
||||||
repeat_type += RepeatFix;
|
if (repeat_type != RepeatNone)
|
||||||
else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
|
|
||||||
if (picture->transform
|
|
||||||
|| (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)))
|
|
||||||
repeat_type += RepeatFix;
|
repeat_type += RepeatFix;
|
||||||
}
|
else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
|
||||||
|
|| pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
if (repeat_type >= RepeatFix) {
|
if (picture->transform
|
||||||
glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
|
|| (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv)))
|
||||||
dispatch->glUniform2fv(wh_location, 1, wh);
|
repeat_type += RepeatFix;
|
||||||
|
}
|
||||||
|
if (repeat_type >= RepeatFix) {
|
||||||
|
glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
|
||||||
|
dispatch->glUniform2fv(wh_location, 1, wh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dispatch->glUniform1i(repeat_location, repeat_type);
|
dispatch->glUniform1i(repeat_location, repeat_type);
|
||||||
glamor_put_dispatch(glamor_priv);
|
glamor_put_dispatch(glamor_priv);
|
||||||
|
@ -687,53 +694,44 @@ glamor_composite_with_copy(CARD8 op,
|
||||||
INT16 x_source,
|
INT16 x_source,
|
||||||
INT16 y_source,
|
INT16 y_source,
|
||||||
INT16 x_dest,
|
INT16 x_dest,
|
||||||
INT16 y_dest, CARD16 width, CARD16 height)
|
INT16 y_dest,
|
||||||
|
RegionPtr region)
|
||||||
{
|
{
|
||||||
RegionRec region;
|
|
||||||
int ret = FALSE;
|
int ret = FALSE;
|
||||||
|
|
||||||
if (!source->pDrawable)
|
if (!source->pDrawable)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!compatible_formats(op, dest, source))
|
if (!compatible_formats(op, dest, source))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (source->repeat || source->transform)
|
if (source->repeat || source->transform) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
x_dest += dest->pDrawable->x;
|
x_dest += dest->pDrawable->x;
|
||||||
y_dest += dest->pDrawable->y;
|
y_dest += dest->pDrawable->y;
|
||||||
x_source += source->pDrawable->x;
|
x_source += source->pDrawable->x;
|
||||||
y_source += source->pDrawable->y;
|
y_source += source->pDrawable->y;
|
||||||
if (!miComputeCompositeRegion(®ion,
|
|
||||||
source, NULL, dest,
|
|
||||||
x_source, y_source,
|
|
||||||
0, 0, x_dest, y_dest, width, height))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (PICT_FORMAT_A(source->format) == 0) {
|
if (PICT_FORMAT_A(source->format) == 0) {
|
||||||
/* Fallback if we sample outside the source so that we
|
/* Fallback if we sample outside the source so that we
|
||||||
* swizzle the correct clear color for out-of-bounds texels.
|
* swizzle the correct clear color for out-of-bounds texels.
|
||||||
*/
|
*/
|
||||||
if (region.extents.x1 + x_source - x_dest < 0)
|
if (region->extents.x1 + x_source - x_dest < 0)
|
||||||
goto cleanup_region;
|
goto cleanup_region;
|
||||||
if (region.extents.x2 + x_source - x_dest > source->pDrawable->width)
|
if (region->extents.x2 + x_source - x_dest > source->pDrawable->width)
|
||||||
goto cleanup_region;
|
goto cleanup_region;
|
||||||
|
|
||||||
if (region.extents.y1 + y_source - y_dest < 0)
|
if (region->extents.y1 + y_source - y_dest < 0)
|
||||||
goto cleanup_region;
|
goto cleanup_region;
|
||||||
if (region.extents.y2 + y_source - y_dest > source->pDrawable->height)
|
if (region->extents.y2 + y_source - y_dest > source->pDrawable->height)
|
||||||
goto cleanup_region;
|
goto cleanup_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = glamor_copy_n_to_n_nf(source->pDrawable,
|
ret = glamor_copy_n_to_n_nf(source->pDrawable,
|
||||||
dest->pDrawable, NULL,
|
dest->pDrawable, NULL,
|
||||||
REGION_RECTS(®ion),
|
RegionRects(region), RegionNumRects(region),
|
||||||
REGION_NUM_RECTS(®ion),
|
|
||||||
x_source - x_dest, y_source - y_dest,
|
x_source - x_dest, y_source - y_dest,
|
||||||
FALSE, FALSE, 0, NULL);
|
FALSE, FALSE, 0, NULL);
|
||||||
cleanup_region:
|
cleanup_region:
|
||||||
REGION_UNINIT(dest->pDrawable->pScreen, ®ion);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -929,12 +927,44 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
|
||||||
|
int repeat_type,
|
||||||
|
float *matrix,
|
||||||
|
float xscale, float yscale,
|
||||||
|
int x1, int y1, int x2, int y2,
|
||||||
|
int yInverted, float *texcoords)
|
||||||
|
{
|
||||||
|
if (!matrix && repeat_type == RepeatNone)
|
||||||
|
glamor_set_normalize_tcoords(priv, xscale, yscale,
|
||||||
|
x1, y1,
|
||||||
|
x2, y2,
|
||||||
|
yInverted,
|
||||||
|
texcoords);
|
||||||
|
else if (matrix && repeat_type == RepeatNone)
|
||||||
|
glamor_set_transformed_normalize_tcoords(priv, matrix, xscale,
|
||||||
|
yscale, x1, y1,
|
||||||
|
x2, y2,
|
||||||
|
yInverted,
|
||||||
|
texcoords);
|
||||||
|
else if (!matrix && repeat_type != RepeatNone)
|
||||||
|
glamor_set_repeat_normalize_tcoords(priv, repeat_type,
|
||||||
|
xscale, yscale,
|
||||||
|
x1, y1,
|
||||||
|
x2, y2,
|
||||||
|
yInverted,
|
||||||
|
texcoords);
|
||||||
|
else if (matrix && repeat_type != RepeatNone)
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
glamor_composite_with_shader(CARD8 op,
|
glamor_composite_with_shader(CARD8 op,
|
||||||
PicturePtr source,
|
PicturePtr source,
|
||||||
PicturePtr mask,
|
PicturePtr mask,
|
||||||
PicturePtr dest,
|
PicturePtr dest,
|
||||||
int nrect, glamor_composite_rect_t * rects)
|
int nrect,
|
||||||
|
glamor_composite_rect_t * rects)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = dest->pDrawable->pScreen;
|
ScreenPtr screen = dest->pDrawable->pScreen;
|
||||||
glamor_screen_private *glamor_priv =
|
glamor_screen_private *glamor_priv =
|
||||||
|
@ -959,6 +989,7 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
enum glamor_pixmap_status mask_status = GLAMOR_NONE;
|
enum glamor_pixmap_status mask_status = GLAMOR_NONE;
|
||||||
PictFormatShort saved_source_format = 0;
|
PictFormatShort saved_source_format = 0;
|
||||||
float src_matrix[9], mask_matrix[9];
|
float src_matrix[9], mask_matrix[9];
|
||||||
|
float *psrc_matrix = NULL, *pmask_matrix = NULL;
|
||||||
GLfloat source_solid_color[4], mask_solid_color[4];
|
GLfloat source_solid_color[4], mask_solid_color[4];
|
||||||
int vert_stride = 4;
|
int vert_stride = 4;
|
||||||
int nrect_max;
|
int nrect_max;
|
||||||
|
@ -970,20 +1001,23 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
memset(&key, 0, sizeof(key));
|
memset(&key, 0, sizeof(key));
|
||||||
if (!source->pDrawable) {
|
if (!source) {
|
||||||
if (source->pSourcePict->type == SourcePictTypeSolidFill) {
|
key.source = SHADER_SOURCE_SOLID;
|
||||||
key.source = SHADER_SOURCE_SOLID;
|
source_solid_color[0] = 0.0;
|
||||||
glamor_get_rgba_from_pixel(source->
|
source_solid_color[1] = 0.0;
|
||||||
pSourcePict->solidFill.
|
source_solid_color[2] = 0.0;
|
||||||
color,
|
source_solid_color[3] = 0.0;
|
||||||
&source_solid_color[0],
|
} else if (!source->pDrawable) {
|
||||||
&source_solid_color[1],
|
if (source->pSourcePict->type == SourcePictTypeSolidFill) {
|
||||||
&source_solid_color[2],
|
key.source = SHADER_SOURCE_SOLID;
|
||||||
&source_solid_color[3],
|
glamor_get_rgba_from_pixel(source->
|
||||||
PICT_a8r8g8b8);
|
pSourcePict->solidFill.
|
||||||
} else {
|
color,
|
||||||
glamor_fallback("gradient source\n");
|
&source_solid_color[0],
|
||||||
goto fail;
|
&source_solid_color[1],
|
||||||
|
&source_solid_color[2],
|
||||||
|
&source_solid_color[3],
|
||||||
|
PICT_a8r8g8b8);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
key.source = SHADER_SOURCE_TEXTURE_ALPHA;
|
key.source = SHADER_SOURCE_TEXTURE_ALPHA;
|
||||||
|
@ -999,9 +1033,6 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
&mask_solid_color[1],
|
&mask_solid_color[1],
|
||||||
&mask_solid_color[2],
|
&mask_solid_color[2],
|
||||||
&mask_solid_color[3], PICT_a8r8g8b8);
|
&mask_solid_color[3], PICT_a8r8g8b8);
|
||||||
} else {
|
|
||||||
glamor_fallback("gradient mask\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
key.mask = SHADER_MASK_TEXTURE_ALPHA;
|
key.mask = SHADER_MASK_TEXTURE_ALPHA;
|
||||||
|
@ -1029,7 +1060,7 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
key.in = SHADER_IN_SOURCE_ONLY;
|
key.in = SHADER_IN_SOURCE_ONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source->alphaMap) {
|
if (source && source->alphaMap) {
|
||||||
glamor_fallback("source alphaMap\n");
|
glamor_fallback("source alphaMap\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1044,10 +1075,11 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
source_pixmap_priv =
|
source_pixmap_priv =
|
||||||
glamor_get_pixmap_private(source_pixmap);
|
glamor_get_pixmap_private(source_pixmap);
|
||||||
if (source_pixmap == dest_pixmap) {
|
if (source_pixmap == dest_pixmap) {
|
||||||
|
/* XXX source and the dest share the same texture.
|
||||||
|
* Does it need special handle? */
|
||||||
glamor_fallback("source == dest\n");
|
glamor_fallback("source == dest\n");
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
if (!source_pixmap_priv || source_pixmap_priv->base.gl_fbo == 0) {
|
if (source_pixmap_priv->base.gl_fbo == 0) {
|
||||||
/* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex
|
/* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex
|
||||||
* equal to zero when the pixmap is screen pixmap. Then we may
|
* equal to zero when the pixmap is screen pixmap. Then we may
|
||||||
* refer the tex zero directly latter in the composition.
|
* refer the tex zero directly latter in the composition.
|
||||||
|
@ -1068,7 +1100,7 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
glamor_fallback("mask == dest\n");
|
glamor_fallback("mask == dest\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!mask_pixmap_priv || mask_pixmap_priv->base.gl_fbo == 0) {
|
if (mask_pixmap_priv->base.gl_fbo == 0) {
|
||||||
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
|
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
|
||||||
mask_status = GLAMOR_UPLOAD_PENDING;
|
mask_status = GLAMOR_UPLOAD_PENDING;
|
||||||
#else
|
#else
|
||||||
|
@ -1095,8 +1127,8 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source->format != saved_source_format) {
|
if (source->format != saved_source_format) {
|
||||||
glamor_picture_format_fixup(source,
|
//glamor_picture_format_fixup(source,
|
||||||
source_pixmap_priv);
|
// source_pixmap_priv);
|
||||||
}
|
}
|
||||||
/* XXX
|
/* XXX
|
||||||
* By default, glamor_upload_picture_to_texture will wire alpha to 1
|
* By default, glamor_upload_picture_to_texture will wire alpha to 1
|
||||||
|
@ -1156,13 +1188,15 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
* transformed source and mask, if the transform is not int translate. */
|
* transformed source and mask, if the transform is not int translate. */
|
||||||
if (key.source != SHADER_SOURCE_SOLID
|
if (key.source != SHADER_SOURCE_SOLID
|
||||||
&& source->transform
|
&& source->transform
|
||||||
&& !pixman_transform_is_int_translate(source->transform)) {
|
&& !pixman_transform_is_int_translate(source->transform)
|
||||||
|
&& source_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
|
||||||
if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
|
if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID
|
if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID
|
||||||
&& mask->transform
|
&& mask->transform
|
||||||
&& !pixman_transform_is_int_translate(mask->transform)) {
|
&& !pixman_transform_is_int_translate(mask->transform)
|
||||||
|
&& mask_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
|
||||||
if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
|
if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1217,7 +1251,10 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
&source_y_off);
|
&source_y_off);
|
||||||
pixmap_priv_get_scale(source_pixmap_priv, &src_xscale,
|
pixmap_priv_get_scale(source_pixmap_priv, &src_xscale,
|
||||||
&src_yscale);
|
&src_yscale);
|
||||||
glamor_picture_get_matrixf(source, src_matrix);
|
if (source->transform) {
|
||||||
|
psrc_matrix = src_matrix;
|
||||||
|
glamor_picture_get_matrixf(source, psrc_matrix);
|
||||||
|
}
|
||||||
vert_stride += 4;
|
vert_stride += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1226,7 +1263,10 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
&mask_x_off, &mask_y_off);
|
&mask_x_off, &mask_y_off);
|
||||||
pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
|
pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale,
|
||||||
&mask_yscale);
|
&mask_yscale);
|
||||||
glamor_picture_get_matrixf(mask, mask_matrix);
|
if (mask->transform) {
|
||||||
|
pmask_matrix = mask_matrix;
|
||||||
|
glamor_picture_get_matrixf(mask, pmask_matrix);
|
||||||
|
}
|
||||||
vert_stride += 4;
|
vert_stride += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1252,13 +1292,16 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
|
|
||||||
x_dest = rects->x_dst + dest_x_off;
|
x_dest = rects->x_dst + dest_x_off;
|
||||||
y_dest = rects->y_dst + dest_y_off;
|
y_dest = rects->y_dst + dest_y_off;
|
||||||
x_source = rects->x_src + source_x_off;;
|
x_source = rects->x_src + source_x_off;
|
||||||
y_source = rects->y_src + source_y_off;
|
y_source = rects->y_src + source_y_off;
|
||||||
x_mask = rects->x_mask + mask_x_off;
|
x_mask = rects->x_mask + mask_x_off;
|
||||||
y_mask = rects->y_mask + mask_y_off;
|
y_mask = rects->y_mask + mask_y_off;
|
||||||
width = rects->width;
|
width = rects->width;
|
||||||
height = rects->height;
|
height = rects->height;
|
||||||
|
|
||||||
|
DEBUGF("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n",
|
||||||
|
x_dest, y_dest, x_source, y_source,x_mask,y_mask,width,height);
|
||||||
|
|
||||||
glamor_set_normalize_vcoords(dest_pixmap_priv, dst_xscale,
|
glamor_set_normalize_vcoords(dest_pixmap_priv, dst_xscale,
|
||||||
dst_yscale,
|
dst_yscale,
|
||||||
x_dest, y_dest,
|
x_dest, y_dest,
|
||||||
|
@ -1266,41 +1309,21 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
glamor_priv->yInverted,
|
glamor_priv->yInverted,
|
||||||
vertices);
|
vertices);
|
||||||
|
|
||||||
if (key.source != SHADER_SOURCE_SOLID) {
|
if (key.source != SHADER_SOURCE_SOLID)
|
||||||
if (source->transform)
|
glamor_set_normalize_tcoords_generic(
|
||||||
glamor_set_transformed_normalize_tcoords
|
source_pixmap_priv, source->repeatType, psrc_matrix,
|
||||||
(source_pixmap_priv, src_matrix, src_xscale,
|
src_xscale, src_yscale, x_source, y_source,
|
||||||
src_yscale, x_source, y_source,
|
x_source + width, y_source + height,
|
||||||
x_source + width, y_source + height,
|
glamor_priv->yInverted, source_texcoords);
|
||||||
glamor_priv->yInverted,
|
|
||||||
source_texcoords);
|
|
||||||
else
|
|
||||||
glamor_set_normalize_tcoords
|
|
||||||
(source_pixmap_priv, src_xscale, src_yscale,
|
|
||||||
x_source, y_source,
|
|
||||||
x_source + width, y_source + height,
|
|
||||||
glamor_priv->yInverted,
|
|
||||||
source_texcoords);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key.mask != SHADER_MASK_NONE
|
if (key.mask != SHADER_MASK_NONE
|
||||||
&& key.mask != SHADER_MASK_SOLID) {
|
&& key.mask != SHADER_MASK_SOLID)
|
||||||
if (mask->transform)
|
glamor_set_normalize_tcoords_generic(
|
||||||
glamor_set_transformed_normalize_tcoords
|
mask_pixmap_priv, mask->repeatType, pmask_matrix,
|
||||||
(mask_pixmap_priv, mask_matrix,
|
mask_xscale, mask_yscale, x_mask, y_mask,
|
||||||
mask_xscale,
|
x_mask + width, y_mask + height,
|
||||||
mask_yscale, x_mask, y_mask,
|
glamor_priv->yInverted, mask_texcoords);
|
||||||
x_mask + width, y_mask + height,
|
|
||||||
glamor_priv->yInverted,
|
|
||||||
mask_texcoords);
|
|
||||||
else
|
|
||||||
glamor_set_normalize_tcoords
|
|
||||||
(mask_pixmap_priv, mask_xscale,
|
|
||||||
mask_yscale, x_mask, y_mask,
|
|
||||||
x_mask + width, y_mask + height,
|
|
||||||
glamor_priv->yInverted,
|
|
||||||
mask_texcoords);
|
|
||||||
}
|
|
||||||
glamor_emit_composite_rect(screen,
|
glamor_emit_composite_rect(screen,
|
||||||
source_texcoords,
|
source_texcoords,
|
||||||
mask_texcoords,
|
mask_texcoords,
|
||||||
|
@ -1323,6 +1346,7 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
dispatch->glActiveTexture(GL_TEXTURE1);
|
dispatch->glActiveTexture(GL_TEXTURE1);
|
||||||
dispatch->glDisable(GL_TEXTURE_2D);
|
dispatch->glDisable(GL_TEXTURE_2D);
|
||||||
#endif
|
#endif
|
||||||
|
DEBUGF("finish rendering.\n");
|
||||||
dispatch->glUseProgram(0);
|
dispatch->glUseProgram(0);
|
||||||
if (saved_source_format)
|
if (saved_source_format)
|
||||||
source->format = saved_source_format;
|
source->format = saved_source_format;
|
||||||
|
@ -1398,17 +1422,18 @@ glamor_convert_gradient_picture(ScreenPtr screen,
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
Bool
|
||||||
_glamor_composite(CARD8 op,
|
glamor_composite_clipped_region(CARD8 op,
|
||||||
PicturePtr source,
|
PicturePtr source,
|
||||||
PicturePtr mask,
|
PicturePtr mask,
|
||||||
PicturePtr dest,
|
PicturePtr dest,
|
||||||
INT16 x_source,
|
RegionPtr region,
|
||||||
INT16 y_source,
|
int x_source,
|
||||||
INT16 x_mask,
|
int y_source,
|
||||||
INT16 y_mask,
|
int x_mask,
|
||||||
INT16 x_dest, INT16 y_dest,
|
int y_mask,
|
||||||
CARD16 width, CARD16 height, Bool fallback)
|
int x_dest,
|
||||||
|
int y_dest)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = dest->pDrawable->pScreen;
|
ScreenPtr screen = dest->pDrawable->pScreen;
|
||||||
glamor_pixmap_private *dest_pixmap_priv;
|
glamor_pixmap_private *dest_pixmap_priv;
|
||||||
|
@ -1419,80 +1444,63 @@ _glamor_composite(CARD8 op,
|
||||||
PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
|
PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
|
||||||
PicturePtr temp_src = source, temp_mask = mask;
|
PicturePtr temp_src = source, temp_mask = mask;
|
||||||
int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
|
int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
|
||||||
|
|
||||||
|
BoxPtr extent;
|
||||||
glamor_composite_rect_t rect[10];
|
glamor_composite_rect_t rect[10];
|
||||||
glamor_composite_rect_t *prect = rect;
|
glamor_composite_rect_t *prect = rect;
|
||||||
int prect_size = ARRAY_SIZE(rect);
|
int prect_size = ARRAY_SIZE(rect);
|
||||||
glamor_screen_private *glamor_priv =
|
int ok = FALSE;
|
||||||
glamor_get_screen_private(screen);
|
int i;
|
||||||
Bool ret = TRUE;
|
int width;
|
||||||
RegionRec region;
|
int height;
|
||||||
BoxPtr box;
|
BoxPtr box;
|
||||||
int nbox, i, ok = FALSE;
|
int nbox;
|
||||||
PixmapPtr sub_dest_pixmap = NULL;
|
extent = RegionExtents(region);
|
||||||
PixmapPtr sub_source_pixmap = NULL;
|
box = RegionRects(region);
|
||||||
PixmapPtr sub_mask_pixmap = NULL;
|
nbox = RegionNumRects(region);
|
||||||
int dest_x_off, dest_y_off, saved_dest_x = 0, saved_dest_y = 0;
|
width = extent->x2 - extent->x1;
|
||||||
int source_x_off, source_y_off, saved_source_x = 0, saved_source_y = 0;
|
height = extent->y2 - extent->y1;
|
||||||
int mask_x_off, mask_y_off, saved_mask_x = 0, saved_mask_y = 0;
|
|
||||||
DrawablePtr saved_dest_drawable = NULL;
|
|
||||||
DrawablePtr saved_source_drawable = NULL;
|
|
||||||
DrawablePtr saved_mask_drawable = NULL;
|
|
||||||
|
|
||||||
x_temp_src = x_source;
|
x_temp_src = x_source;
|
||||||
y_temp_src = y_source;
|
y_temp_src = y_source;
|
||||||
x_temp_mask = x_mask;
|
x_temp_mask = x_mask;
|
||||||
y_temp_mask = y_mask;
|
y_temp_mask = y_mask;
|
||||||
|
DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
|
||||||
DEBUGF("Composite Src: (%d, %d)\n"
|
x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
|
||||||
" Mask: (%d, %d)\n"
|
DEBUGF("dest pixmap %p ", dest_pixmap);
|
||||||
" to dst: (%d, %d), size: %d X %d \n",
|
|
||||||
x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
|
|
||||||
|
|
||||||
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
|
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
|
||||||
/* Currently. Always fallback to cpu if destination is in CPU memory. */
|
/* Currently. Always fallback to cpu if destination is in CPU memory. */
|
||||||
|
|
||||||
if (source->pDrawable) {
|
if (source && source->pDrawable) {
|
||||||
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
|
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
|
||||||
source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
|
source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
|
||||||
if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask && mask->pDrawable) {
|
if (mask && mask->pDrawable) {
|
||||||
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
|
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
|
||||||
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
|
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
|
||||||
if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
|
/* XXX is it possible source mask have non-zero drawable.x/y? */
|
||||||
goto fail;
|
if (source
|
||||||
}
|
&& ((!source->pDrawable
|
||||||
|
|
||||||
if (op >= ARRAY_SIZE(composite_op_info))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if ((!source->pDrawable
|
|
||||||
&& (source->pSourcePict->type != SourcePictTypeSolidFill))
|
&& (source->pSourcePict->type != SourcePictTypeSolidFill))
|
||||||
|| (source->pDrawable
|
|| (source->pDrawable
|
||||||
&& !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv)
|
&& !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv)
|
||||||
&&
|
&& (source_pixmap->drawable.width != width
|
||||||
((width * height * 4 <
|
|| source_pixmap->drawable.height != height)))) {
|
||||||
(source_pixmap->drawable.width *
|
|
||||||
source_pixmap->drawable.height))
|
|
||||||
||
|
|
||||||
!(glamor_check_fbo_size
|
|
||||||
(glamor_priv, source_pixmap->drawable.width,
|
|
||||||
source_pixmap->drawable.height))))) {
|
|
||||||
temp_src =
|
temp_src =
|
||||||
glamor_convert_gradient_picture(screen, source,
|
glamor_convert_gradient_picture(screen, source,
|
||||||
x_source, y_source,
|
extent->x1 + x_source - x_dest,
|
||||||
|
extent->y1 + y_source - y_dest,
|
||||||
width, height);
|
width, height);
|
||||||
if (!temp_src) {
|
if (!temp_src) {
|
||||||
temp_src = source;
|
temp_src = source;
|
||||||
goto fail;
|
goto out;
|
||||||
}
|
}
|
||||||
x_temp_src = y_temp_src = 0;
|
x_temp_src = - extent->x1 + x_dest;
|
||||||
|
y_temp_src = - extent->y1 + y_dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask
|
if (mask
|
||||||
|
@ -1500,26 +1508,22 @@ _glamor_composite(CARD8 op,
|
||||||
((!mask->pDrawable
|
((!mask->pDrawable
|
||||||
&& (mask->pSourcePict->type != SourcePictTypeSolidFill))
|
&& (mask->pSourcePict->type != SourcePictTypeSolidFill))
|
||||||
|| (mask->pDrawable
|
|| (mask->pDrawable
|
||||||
&& (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv))
|
&& !GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv)
|
||||||
&&
|
&& (mask_pixmap->drawable.width != width
|
||||||
((width * height * 4 <
|
|| mask_pixmap->drawable.height != height)))) {
|
||||||
(mask_pixmap->drawable.width *
|
|
||||||
mask_pixmap->drawable.height))
|
|
||||||
||
|
|
||||||
!(glamor_check_fbo_size
|
|
||||||
(glamor_priv, mask_pixmap->drawable.width,
|
|
||||||
mask_pixmap->drawable.height)))))) {
|
|
||||||
/* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity
|
/* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity
|
||||||
* to do reduce one convertion. */
|
* to do reduce one convertion. */
|
||||||
temp_mask =
|
temp_mask =
|
||||||
glamor_convert_gradient_picture(screen, mask,
|
glamor_convert_gradient_picture(screen, mask,
|
||||||
x_mask, y_mask,
|
extent->x1 + x_mask - x_dest,
|
||||||
|
extent->y1 + y_mask - y_dest,
|
||||||
width, height);
|
width, height);
|
||||||
if (!temp_mask) {
|
if (!temp_mask) {
|
||||||
temp_mask = mask;
|
temp_mask = mask;
|
||||||
goto fail;
|
goto out;
|
||||||
}
|
}
|
||||||
x_temp_mask = y_temp_mask = 0;
|
x_temp_mask = - extent->x1 + x_dest;
|
||||||
|
y_temp_mask = - extent->y1 + y_dest;
|
||||||
}
|
}
|
||||||
/* Do two-pass PictOpOver componentAlpha, until we enable
|
/* Do two-pass PictOpOver componentAlpha, until we enable
|
||||||
* dual source color blending.
|
* dual source color blending.
|
||||||
|
@ -1527,43 +1531,38 @@ _glamor_composite(CARD8 op,
|
||||||
|
|
||||||
if (mask && mask->componentAlpha) {
|
if (mask && mask->componentAlpha) {
|
||||||
if (op == PictOpOver) {
|
if (op == PictOpOver) {
|
||||||
glamor_composite(PictOpOutReverse,
|
glamor_composite_clipped_region(PictOpOutReverse,
|
||||||
temp_src, temp_mask, dest,
|
temp_src, temp_mask, dest,
|
||||||
x_temp_src, y_temp_src,
|
region,
|
||||||
x_temp_mask, y_temp_mask,
|
x_temp_src, y_temp_src,
|
||||||
x_dest, y_dest, width, height);
|
x_temp_mask, y_temp_mask,
|
||||||
glamor_composite(PictOpAdd,
|
x_dest, y_dest);
|
||||||
temp_src, temp_mask, dest,
|
|
||||||
x_temp_src, y_temp_src,
|
|
||||||
x_temp_mask, y_temp_mask,
|
|
||||||
x_dest, y_dest, width, height);
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
} else if (op == PictOpAtop
|
glamor_composite_clipped_region(PictOpAdd,
|
||||||
|| op == PictOpAtopReverse
|
temp_src, temp_mask, dest,
|
||||||
|| op == PictOpXor
|
region,
|
||||||
|| op >= PictOpSaturate) {
|
x_temp_src, y_temp_src,
|
||||||
glamor_fallback
|
x_temp_mask, y_temp_mask,
|
||||||
("glamor_composite(): component alpha op %x\n", op);
|
x_dest, y_dest);
|
||||||
goto fail;
|
ok = TRUE;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mask) {
|
if (!mask && temp_src) {
|
||||||
if (glamor_composite_with_copy(op, temp_src, dest,
|
if (glamor_composite_with_copy(op, temp_src, dest,
|
||||||
x_temp_src, y_temp_src,
|
x_temp_src, y_temp_src,
|
||||||
x_dest, y_dest, width,
|
x_dest, y_dest, region)) {
|
||||||
height))
|
ok = TRUE;
|
||||||
goto done;
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*XXXXX, maybe we can make a copy of dest pixmap.*/
|
/*XXXXX, self copy?*/
|
||||||
if (source_pixmap == dest_pixmap)
|
|
||||||
goto full_fallback;
|
|
||||||
|
|
||||||
x_dest += dest->pDrawable->x;
|
x_dest += dest->pDrawable->x;
|
||||||
y_dest += dest->pDrawable->y;
|
y_dest += dest->pDrawable->y;
|
||||||
if (temp_src->pDrawable) {
|
if (temp_src && temp_src->pDrawable) {
|
||||||
x_temp_src += temp_src->pDrawable->x;
|
x_temp_src += temp_src->pDrawable->x;
|
||||||
y_temp_src += temp_src->pDrawable->y;
|
y_temp_src += temp_src->pDrawable->y;
|
||||||
}
|
}
|
||||||
|
@ -1571,16 +1570,6 @@ _glamor_composite(CARD8 op,
|
||||||
x_temp_mask += temp_mask->pDrawable->x;
|
x_temp_mask += temp_mask->pDrawable->x;
|
||||||
y_temp_mask += temp_mask->pDrawable->y;
|
y_temp_mask += temp_mask->pDrawable->y;
|
||||||
}
|
}
|
||||||
if (!miComputeCompositeRegion(®ion,
|
|
||||||
temp_src, temp_mask, dest,
|
|
||||||
x_temp_src, y_temp_src,
|
|
||||||
x_temp_mask, y_temp_mask,
|
|
||||||
x_dest, y_dest, width,
|
|
||||||
height))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
box = REGION_RECTS(®ion);
|
|
||||||
nbox = REGION_NUM_RECTS(®ion);
|
|
||||||
|
|
||||||
if (nbox > ARRAY_SIZE(rect)) {
|
if (nbox > ARRAY_SIZE(rect)) {
|
||||||
prect = calloc(nbox, sizeof(*prect));
|
prect = calloc(nbox, sizeof(*prect));
|
||||||
|
@ -1612,10 +1601,148 @@ _glamor_composite(CARD8 op,
|
||||||
box += box_cnt;
|
box += box_cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prect != rect)
|
||||||
|
free(prect);
|
||||||
|
out:
|
||||||
|
if (temp_src != source)
|
||||||
|
FreePicture(temp_src, 0);
|
||||||
|
if (temp_mask != mask)
|
||||||
|
FreePicture(temp_mask, 0);
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
_glamor_composite(CARD8 op,
|
||||||
|
PicturePtr source,
|
||||||
|
PicturePtr mask,
|
||||||
|
PicturePtr dest,
|
||||||
|
INT16 x_source,
|
||||||
|
INT16 y_source,
|
||||||
|
INT16 x_mask,
|
||||||
|
INT16 y_mask,
|
||||||
|
INT16 x_dest, INT16 y_dest,
|
||||||
|
CARD16 width, CARD16 height, Bool fallback)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = dest->pDrawable->pScreen;
|
||||||
|
glamor_pixmap_private *dest_pixmap_priv;
|
||||||
|
glamor_pixmap_private *source_pixmap_priv =
|
||||||
|
NULL, *mask_pixmap_priv = NULL;
|
||||||
|
PixmapPtr dest_pixmap =
|
||||||
|
glamor_get_drawable_pixmap(dest->pDrawable);
|
||||||
|
PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
|
||||||
|
glamor_screen_private *glamor_priv =
|
||||||
|
glamor_get_screen_private(screen);
|
||||||
|
Bool ret = TRUE;
|
||||||
|
RegionRec region;
|
||||||
|
BoxPtr box, extent;
|
||||||
|
int nbox, ok = FALSE;
|
||||||
|
PixmapPtr sub_dest_pixmap = NULL;
|
||||||
|
PixmapPtr sub_source_pixmap = NULL;
|
||||||
|
PixmapPtr sub_mask_pixmap = NULL;
|
||||||
|
int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y;
|
||||||
|
int source_x_off, source_y_off, saved_source_x, saved_source_y;
|
||||||
|
int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y;
|
||||||
|
DrawablePtr saved_dest_drawable;
|
||||||
|
DrawablePtr saved_source_drawable;
|
||||||
|
DrawablePtr saved_mask_drawable;
|
||||||
|
int force_clip = 0;
|
||||||
|
|
||||||
|
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
|
||||||
|
|
||||||
|
if (source->pDrawable) {
|
||||||
|
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
|
||||||
|
source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
|
||||||
|
if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask && mask->pDrawable) {
|
||||||
|
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
|
||||||
|
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
|
||||||
|
if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGF("source pixmap %p (%d %d) mask(%d %d) dest(%d %d) width %d height %d \n",
|
||||||
|
source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
|
||||||
|
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op >= ARRAY_SIZE(composite_op_info))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (mask && mask->componentAlpha) {
|
||||||
|
if (op == PictOpAtop
|
||||||
|
|| op == PictOpAtopReverse
|
||||||
|
|| op == PictOpXor
|
||||||
|
|| op >= PictOpSaturate) {
|
||||||
|
glamor_fallback
|
||||||
|
("glamor_composite(): component alpha op %x\n", op);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!miComputeCompositeRegion(®ion,
|
||||||
|
source, mask, dest,
|
||||||
|
x_source + (source_pixmap ? source->pDrawable->x : 0),
|
||||||
|
y_source + (source_pixmap ? source->pDrawable->y : 0),
|
||||||
|
x_mask + (mask_pixmap ? mask->pDrawable->x : 0),
|
||||||
|
y_mask + (mask_pixmap ? mask->pDrawable->y : 0),
|
||||||
|
x_dest + dest->pDrawable->x,
|
||||||
|
y_dest + dest->pDrawable->y,
|
||||||
|
width,
|
||||||
|
height)) {
|
||||||
|
ret = TRUE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
box = REGION_RECTS(®ion);
|
||||||
|
nbox = REGION_NUM_RECTS(®ion);
|
||||||
|
DEBUGF("first clipped when compositing.\n");
|
||||||
|
DEBUGRegionPrint(®ion);
|
||||||
|
extent = RegionExtents(®ion);
|
||||||
|
if (nbox == 0) {
|
||||||
|
ret = TRUE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* If destination is not a large pixmap, but the region is larger
|
||||||
|
* than texture size limitation, and source or mask is memory pixmap,
|
||||||
|
* then there may be need to load a large memory pixmap to a
|
||||||
|
* texture, and this is not permitted. Then we force to clip the
|
||||||
|
* destination and make sure latter will not upload a large memory
|
||||||
|
* pixmap. */
|
||||||
|
if (!glamor_check_fbo_size(glamor_priv,
|
||||||
|
extent->x2 - extent->x1, extent->y2 - extent->y1)
|
||||||
|
&& (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE)
|
||||||
|
&& ((source_pixmap_priv
|
||||||
|
&& source_pixmap_priv->type == GLAMOR_MEMORY)
|
||||||
|
|| (mask_pixmap_priv
|
||||||
|
&& mask_pixmap_priv->type == GLAMOR_MEMORY)
|
||||||
|
|| (!source_pixmap_priv
|
||||||
|
&& (source->pSourcePict->type != SourcePictTypeSolidFill))
|
||||||
|
|| (!mask_pixmap_priv && mask
|
||||||
|
&& mask->pSourcePict->type != SourcePictTypeSolidFill)))
|
||||||
|
force_clip = 1;
|
||||||
|
|
||||||
|
if (force_clip || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
|
||||||
|
|| (source_pixmap_priv
|
||||||
|
&& source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
|
||||||
|
|| (mask_pixmap_priv
|
||||||
|
&& mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE))
|
||||||
|
goto fail;
|
||||||
|
else
|
||||||
|
ok = glamor_composite_clipped_region(op, source,
|
||||||
|
mask, dest, ®ion,
|
||||||
|
x_source, y_source,
|
||||||
|
x_mask, y_mask,
|
||||||
|
x_dest, y_dest);
|
||||||
|
|
||||||
REGION_UNINIT(dest->pDrawable->pScreen, ®ion);
|
REGION_UNINIT(dest->pDrawable->pScreen, ®ion);
|
||||||
if (ok)
|
if (ok)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
if (!fallback
|
if (!fallback
|
||||||
|
@ -1662,13 +1789,11 @@ fail:
|
||||||
x_ ##p = 0; \
|
x_ ##p = 0; \
|
||||||
y_ ##p = 0; \
|
y_ ##p = 0; \
|
||||||
} } while(0)
|
} } while(0)
|
||||||
|
|
||||||
GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
|
GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
|
||||||
if (source->pDrawable)
|
if (source->pDrawable && !source->transform)
|
||||||
GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
|
GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
|
||||||
if (mask && mask->pDrawable)
|
if (mask && mask->pDrawable && !mask->transform)
|
||||||
GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
|
GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
|
||||||
|
|
||||||
full_fallback:
|
full_fallback:
|
||||||
if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
|
if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
|
||||||
if (source_pixmap == dest_pixmap || glamor_prepare_access_picture
|
if (source_pixmap == dest_pixmap || glamor_prepare_access_picture
|
||||||
|
@ -1711,12 +1836,6 @@ full_fallback:
|
||||||
PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
|
PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
|
||||||
PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
|
PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
|
||||||
done:
|
done:
|
||||||
if (temp_src != source)
|
|
||||||
FreePicture(temp_src, 0);
|
|
||||||
if (temp_mask != mask)
|
|
||||||
FreePicture(temp_mask, 0);
|
|
||||||
if (prect != rect)
|
|
||||||
free(prect);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1754,9 +1873,6 @@ glamor_composite_nf(CARD8 op,
|
||||||
FALSE);
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an appropriate picture to upload our alpha mask into (which
|
* Creates an appropriate picture to upload our alpha mask into (which
|
||||||
* we calculated in system memory)
|
* we calculated in system memory)
|
||||||
|
@ -1912,8 +2028,12 @@ glamor_composite_glyph_rects(CARD8 op,
|
||||||
ValidatePicture(src);
|
ValidatePicture(src);
|
||||||
ValidatePicture(dst);
|
ValidatePicture(dst);
|
||||||
|
|
||||||
if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects))
|
if (!(glamor_is_large_picture(src)
|
||||||
return;
|
|| (mask && glamor_is_large_picture(mask))
|
||||||
|
|| glamor_is_large_picture(dst))) {
|
||||||
|
if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
n = nrect;
|
n = nrect;
|
||||||
r = rects;
|
r = rects;
|
||||||
|
|
|
@ -102,10 +102,9 @@ glamor_fini_tile_shader(ScreenPtr screen)
|
||||||
glamor_put_dispatch(glamor_priv);
|
glamor_put_dispatch(glamor_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
static void
|
||||||
glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
_glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
int x, int y, int width, int height,
|
int x, int y, int width, int height,
|
||||||
unsigned char alu, unsigned long planemask,
|
|
||||||
int tile_x, int tile_y)
|
int tile_x, int tile_y)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
|
@ -126,48 +125,17 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
glamor_pixmap_private *src_pixmap_priv;
|
glamor_pixmap_private *src_pixmap_priv;
|
||||||
glamor_pixmap_private *dst_pixmap_priv;
|
glamor_pixmap_private *dst_pixmap_priv;
|
||||||
float wh[2];
|
float wh[2];
|
||||||
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(tile);
|
src_pixmap_priv = glamor_get_pixmap_private(tile);
|
||||||
dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
|
dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
|
||||||
if (src_pixmap_priv == NULL || dst_pixmap_priv == NULL)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (glamor_priv->tile_prog == 0) {
|
|
||||||
glamor_fallback("Tiling unsupported\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
|
|
||||||
glamor_fallback("dest has no fbo.\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
|
|
||||||
/* XXX dynamic uploading candidate. */
|
|
||||||
glamor_fallback("Non-texture tile pixmap\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!glamor_set_planemask(pixmap, planemask)) {
|
|
||||||
glamor_fallback("unsupported planemask %lx\n", planemask);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
|
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
|
||||||
pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
|
pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
|
||||||
|
|
||||||
dispatch = glamor_get_dispatch(glamor_priv);
|
|
||||||
if (!glamor_set_alu(dispatch, alu)) {
|
|
||||||
glamor_put_dispatch(glamor_priv);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
|
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale,
|
||||||
&src_yscale);
|
&src_yscale);
|
||||||
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
dispatch->glUseProgram(glamor_priv->tile_prog);
|
dispatch->glUseProgram(glamor_priv->tile_prog);
|
||||||
|
|
||||||
glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
|
glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
|
||||||
|
|
||||||
dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
|
dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
|
||||||
dispatch->glActiveTexture(GL_TEXTURE0);
|
dispatch->glActiveTexture(GL_TEXTURE0);
|
||||||
dispatch->glBindTexture(GL_TEXTURE_2D,
|
dispatch->glBindTexture(GL_TEXTURE_2D,
|
||||||
|
@ -185,21 +153,23 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
#ifndef GLAMOR_GLES2
|
#ifndef GLAMOR_GLES2
|
||||||
dispatch->glEnable(GL_TEXTURE_2D);
|
dispatch->glEnable(GL_TEXTURE_2D);
|
||||||
#endif
|
#endif
|
||||||
glamor_set_normalize_tcoords(src_pixmap_priv, src_xscale,
|
glamor_set_repeat_normalize_tcoords
|
||||||
src_yscale,
|
(src_pixmap_priv, RepeatNormal,
|
||||||
tile_x1, tile_y1,
|
src_xscale, src_yscale,
|
||||||
tile_x2, tile_y2,
|
tile_x1, tile_y1,
|
||||||
glamor_priv->yInverted,
|
tile_x2, tile_y2,
|
||||||
source_texcoords);
|
glamor_priv->yInverted,
|
||||||
|
source_texcoords);
|
||||||
|
|
||||||
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
|
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
|
||||||
GL_FLOAT, GL_FALSE,
|
GL_FLOAT, GL_FALSE,
|
||||||
2 * sizeof(float),
|
2 * sizeof(float),
|
||||||
source_texcoords);
|
source_texcoords);
|
||||||
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||||
|
|
||||||
glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale,
|
glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale,
|
||||||
dst_yscale,
|
x1, y1,
|
||||||
x1, y1, x2, y2,
|
x2, y2,
|
||||||
glamor_priv->yInverted, vertices);
|
glamor_priv->yInverted, vertices);
|
||||||
|
|
||||||
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||||
|
@ -214,11 +184,139 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
#endif
|
#endif
|
||||||
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
dispatch->glUseProgram(0);
|
dispatch->glUseProgram(0);
|
||||||
|
glamor_put_dispatch(glamor_priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
||||||
|
int x, int y, int width, int height,
|
||||||
|
unsigned char alu, unsigned long planemask,
|
||||||
|
int tile_x, int tile_y)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
|
glamor_screen_private *glamor_priv =
|
||||||
|
glamor_get_screen_private(screen);
|
||||||
|
glamor_pixmap_private *dst_pixmap_priv;
|
||||||
|
glamor_pixmap_private *src_pixmap_priv;
|
||||||
|
glamor_gl_dispatch *dispatch;
|
||||||
|
|
||||||
|
dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
src_pixmap_priv = glamor_get_pixmap_private(tile);
|
||||||
|
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (glamor_priv->tile_prog == 0) {
|
||||||
|
glamor_fallback("Tiling unsupported\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
|
||||||
|
/* XXX dynamic uploading candidate. */
|
||||||
|
glamor_fallback("Non-texture tile pixmap\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!glamor_set_planemask(pixmap, planemask)) {
|
||||||
|
glamor_fallback("unsupported planemask %lx\n", planemask);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch = glamor_get_dispatch(glamor_priv);
|
||||||
|
if (!glamor_set_alu(dispatch, alu)) {
|
||||||
|
glamor_fallback("unsupported alu %x\n", alu);
|
||||||
|
glamor_put_dispatch(glamor_priv);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
|
||||||
|
|| src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
glamor_pixmap_clipped_regions *clipped_dst_regions;
|
||||||
|
int n_dst_region, i, j, k;
|
||||||
|
BoxRec box;
|
||||||
|
RegionRec region;
|
||||||
|
|
||||||
|
box.x1 = x;
|
||||||
|
box.y1 = y;
|
||||||
|
box.x2 = x + width;
|
||||||
|
box.y2 = y + height;
|
||||||
|
RegionInitBoxes(®ion, &box, 1);
|
||||||
|
clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
|
||||||
|
®ion, &n_dst_region, 0);
|
||||||
|
for(i = 0; i < n_dst_region; i++)
|
||||||
|
{
|
||||||
|
int n_src_region;
|
||||||
|
glamor_pixmap_clipped_regions *clipped_src_regions;
|
||||||
|
BoxPtr current_boxes;
|
||||||
|
int n_current_boxes;
|
||||||
|
|
||||||
|
SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, clipped_dst_regions[i].block_idx);
|
||||||
|
|
||||||
|
if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
RegionTranslate(clipped_dst_regions[i].region,
|
||||||
|
tile_x - x, tile_y - y);
|
||||||
|
DEBUGF("tiled a large src pixmap. %dx%d \n", tile->drawable.width, tile->drawable.height);
|
||||||
|
clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv,
|
||||||
|
clipped_dst_regions[i].region,
|
||||||
|
&n_src_region, 1);
|
||||||
|
DEBUGF("got %d src regions %d \n", n_src_region);
|
||||||
|
for (j = 0; j < n_src_region; j++)
|
||||||
|
{
|
||||||
|
|
||||||
|
SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, clipped_src_regions[j].block_idx);
|
||||||
|
|
||||||
|
RegionTranslate(clipped_src_regions[j].region,
|
||||||
|
x - tile_x,
|
||||||
|
y - tile_y);
|
||||||
|
current_boxes = RegionRects(clipped_src_regions[j].region);
|
||||||
|
n_current_boxes = RegionNumRects(clipped_src_regions[j].region);
|
||||||
|
for(k = 0; k < n_current_boxes; k++)
|
||||||
|
{
|
||||||
|
DEBUGF("Tile on %d %d %d %d dst block id %d tile block id %d tilex %d tiley %d\n",
|
||||||
|
current_boxes[k].x1, current_boxes[k].y1,
|
||||||
|
current_boxes[k].x2 - current_boxes[k].x1,
|
||||||
|
current_boxes[k].y2 - current_boxes[k].y1,
|
||||||
|
clipped_dst_regions[i].block_idx,
|
||||||
|
clipped_src_regions[j].block_idx,
|
||||||
|
(tile_x + (current_boxes[k].x1 - x)),
|
||||||
|
tile_y + (current_boxes[k].y1 - y));
|
||||||
|
|
||||||
|
_glamor_tile(pixmap, tile,
|
||||||
|
current_boxes[k].x1, current_boxes[k].y1,
|
||||||
|
current_boxes[k].x2 - current_boxes[k].x1,
|
||||||
|
current_boxes[k].y2 - current_boxes[k].y1,
|
||||||
|
(tile_x + (current_boxes[k].x1 - x)),
|
||||||
|
(tile_y + (current_boxes[k].y1 - y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionDestroy(clipped_src_regions[j].region);
|
||||||
|
}
|
||||||
|
free(clipped_src_regions);
|
||||||
|
} else {
|
||||||
|
current_boxes = RegionRects(clipped_dst_regions[i].region);
|
||||||
|
n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
|
||||||
|
for(k = 0; k < n_current_boxes; k++)
|
||||||
|
{
|
||||||
|
_glamor_tile(pixmap, tile,
|
||||||
|
current_boxes[k].x1, current_boxes[k].y1,
|
||||||
|
current_boxes[k].x2 - current_boxes[k].x1,
|
||||||
|
current_boxes[k].y2 - current_boxes[k].y1,
|
||||||
|
(tile_x + (current_boxes[k].x1 - x)),
|
||||||
|
(tile_y + (current_boxes[k].y1 - y)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RegionDestroy(clipped_dst_regions[i].region);
|
||||||
|
}
|
||||||
|
free(clipped_dst_regions);
|
||||||
|
RegionUninit(®ion);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
|
||||||
|
|
||||||
glamor_set_alu(dispatch, GXcopy);
|
glamor_set_alu(dispatch, GXcopy);
|
||||||
glamor_set_planemask(pixmap, ~0);
|
|
||||||
glamor_put_dispatch(glamor_priv);
|
glamor_put_dispatch(glamor_priv);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
fail:
|
||||||
fail:
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,10 @@
|
||||||
|
|
||||||
#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
|
#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
|
||||||
do { \
|
do { \
|
||||||
*(_pxscale_) = 1.0 / (_pixmap_priv_)->base.pixmap->drawable.width; \
|
int w,h; \
|
||||||
*(_pyscale_) = 1.0 / (_pixmap_priv_)->base.pixmap->drawable.height; \
|
PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, w, h); \
|
||||||
|
*(_pxscale_) = 1.0 / w; \
|
||||||
|
*(_pyscale_) = 1.0 / h; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
|
#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
|
||||||
|
@ -106,6 +108,52 @@
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define _glamor_get_repeat_coords(priv, repeat_type, tx1, \
|
||||||
|
ty1, tx2, ty2, \
|
||||||
|
_x1_, _y1_, _x2_, \
|
||||||
|
_y2_, c, d, odd_x, odd_y) \
|
||||||
|
do { \
|
||||||
|
if (repeat_type == RepeatReflect) { \
|
||||||
|
assert(0); \
|
||||||
|
} else if (repeat_type == RepeatNormal) { \
|
||||||
|
tx1 = (c - priv->box.x1); \
|
||||||
|
ty1 = (d - priv->box.y1); \
|
||||||
|
tx2 = tx1 + ((_x2_) - (_x1_)); \
|
||||||
|
ty2 = ty1 + ((_y2_) - (_y1_)); \
|
||||||
|
} else { \
|
||||||
|
assert(0); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* _x1_ ... _y2_ must be integer. */
|
||||||
|
#define glamor_get_repeat_coords(priv, repeat_type, tx1, \
|
||||||
|
ty1, tx2, ty2, _x1_, _y1_, _x2_, \
|
||||||
|
_y2_) \
|
||||||
|
do { \
|
||||||
|
int c, d; \
|
||||||
|
int odd_x = 0, odd_y = 0; \
|
||||||
|
DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \
|
||||||
|
(priv)->base.pixmap->drawable.width, \
|
||||||
|
priv->box.x1, priv->box.x2, \
|
||||||
|
priv->box.y1, priv->box.y2); \
|
||||||
|
modulus((_x1_), (priv)->base.pixmap->drawable.width, c); \
|
||||||
|
modulus((_y1_), (priv)->base.pixmap->drawable.height, d); \
|
||||||
|
DEBUGF("c %d d %d \n", c, d); \
|
||||||
|
if (repeat_type == RepeatReflect) { \
|
||||||
|
odd_x = abs((_x1_ - c) \
|
||||||
|
/ (priv->base.pixmap->drawable.width)) & 1; \
|
||||||
|
odd_y = abs((_y1_ - d) \
|
||||||
|
/ (priv->base.pixmap->drawable.height)) & 1; \
|
||||||
|
} \
|
||||||
|
_glamor_get_repeat_coords(priv, repeat_type, tx1, ty1, tx2, ty2,\
|
||||||
|
_x1_, _y1_, _x2_, _y2_, c, d, \
|
||||||
|
odd_x, odd_y); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define glamor_transform_point(matrix, tx, ty, x, y) \
|
#define glamor_transform_point(matrix, tx, ty, x, y) \
|
||||||
do { \
|
do { \
|
||||||
int i; \
|
int i; \
|
||||||
|
@ -213,6 +261,24 @@
|
||||||
tx2, ty2, yInverted, vertices); \
|
tx2, ty2, yInverted, vertices); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \
|
||||||
|
xscale, yscale, \
|
||||||
|
_x1_, _y1_, _x2_, _y2_, \
|
||||||
|
yInverted, vertices) \
|
||||||
|
do { \
|
||||||
|
float tx1, tx2, ty1, ty2; \
|
||||||
|
if (priv->type == GLAMOR_TEXTURE_LARGE) \
|
||||||
|
glamor_get_repeat_coords((&priv->large), repeat_type, \
|
||||||
|
tx1, ty1, tx2, ty2, \
|
||||||
|
_x1_, _y1_, _x2_, _y2_); \
|
||||||
|
else { \
|
||||||
|
tx1 = _x1_; tx2 = _x2_; ty1 = _y1_; ty2 = _y2_; \
|
||||||
|
} \
|
||||||
|
_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
|
||||||
|
tx2, ty2, yInverted, vertices); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
#define glamor_set_tcoords(width, height, x1, y1, x2, y2, \
|
#define glamor_set_tcoords(width, height, x1, y1, x2, y2, \
|
||||||
yInverted, vertices) \
|
yInverted, vertices) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -303,7 +369,7 @@ glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void
|
inline static void
|
||||||
glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
|
glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nbox; i++) {
|
for (i = 0; i < nbox; i++) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user