glamor_largepixmap: first commit for large pixmap.

This is the first commit to add support for large pixmap.
The large here means a pixmap is larger than the texutre's
size limitation thus can't fit into one single texutre.

The previous implementation will simply fallback to use a
in memory pixmap to contain the large pixmap which is
very slow in practice.

The basic idea here is to use an array of texture to hold
the large pixmap. And when we need to get a specific area
of the pixmap, we just need to compute/clip the correct
region and find the corresponding fbo.

We need to implement some auxiliary routines to clip every
rendering operations into small pieces which can fit into
one texture.

The complex part is the transformation/repeat/repeatReflect
and repeat pad and their comination. We will support all of
them step by step.

This commit just add some necessary data structure to represent
the large pixmap, and doesn't change any rendering process.
This commit doesn't add real large pixmap support.

Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
Zhigang Gong 2012-06-11 01:02:30 +08:00 committed by Eric Anholt
parent 4c174f4c9c
commit ace35e408c
15 changed files with 439 additions and 170 deletions

View File

@ -73,8 +73,8 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
if (pixmap_priv == NULL) {
pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
glamor_set_pixmap_private(pixmap, pixmap_priv);
pixmap_priv->container = pixmap;
pixmap_priv->glamor_priv = glamor_priv;
pixmap_priv->base.pixmap = pixmap;
pixmap_priv->base.glamor_priv = glamor_priv;
}
pixmap_priv->type = type;
}
@ -91,7 +91,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
glamor_priv = glamor_get_screen_private(screen);
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (pixmap_priv->fbo) {
if (pixmap_priv->base.fbo) {
fbo = glamor_pixmap_detach_fbo(pixmap_priv);
glamor_destroy_fbo(fbo);
}
@ -117,10 +117,10 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen);
pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
glamor_priv->screen_fbo = pixmap_priv->fbo->fb;
glamor_priv->screen_fbo = pixmap_priv->base.fbo->fb;
pixmap_priv->fbo->width = screen_pixmap->drawable.width;
pixmap_priv->fbo->height = screen_pixmap->drawable.height;
pixmap_priv->base.fbo->width = screen_pixmap->drawable.width;
pixmap_priv->base.fbo->height = screen_pixmap->drawable.height;
glamor_priv->back_pixmap = back_pixmap;
}
@ -159,8 +159,8 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
if (usage == GLAMOR_CREATE_PIXMAP_MAP)
type = GLAMOR_MEMORY_MAP;
pixmap_priv->container = pixmap;
pixmap_priv->glamor_priv = glamor_priv;
pixmap_priv->base.pixmap = pixmap;
pixmap_priv->base.glamor_priv = glamor_priv;
pixmap_priv->type = type;
gl_iformat_for_depth(depth, &format);

View File

@ -55,7 +55,9 @@ typedef enum glamor_pixmap_type {
GLAMOR_TEXTURE_DRM,
GLAMOR_SEPARATE_TEXTURE,
GLAMOR_DRM_ONLY,
GLAMOR_TEXTURE_ONLY
GLAMOR_TEXTURE_ONLY,
GLAMOR_TEXTURE_LARGE,
GLAMOR_TEXTURE_PACK
} glamor_pixmap_type_t;
#define GLAMOR_EGL_EXTERNAL_BUFFER 3

View File

@ -75,7 +75,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
dispatch = glamor_get_dispatch(glamor_priv);
dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT,
src_pixmap_priv->fbo->fb);
src_pixmap_priv->base.fbo->fb);
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
&dst_y_off);
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off,
@ -164,7 +164,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
return FALSE;
}
if (!src_pixmap_priv || !src_pixmap_priv->gl_fbo) {
if (!src_pixmap_priv || !src_pixmap_priv->base.gl_fbo) {
#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
return FALSE;
@ -209,7 +209,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
dispatch->glActiveTexture(GL_TEXTURE0);
dispatch->glBindTexture(GL_TEXTURE_2D,
src_pixmap_priv->fbo->tex);
src_pixmap_priv->base.fbo->tex);
#ifndef GLAMOR_GLES2
dispatch->glEnable(GL_TEXTURE_2D);
dispatch->glTexParameteri(GL_TEXTURE_2D,
@ -239,7 +239,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
for (i = 0; i < nbox; i++) {
glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale,
dst_yscale,
box[i].x1 + dst_x_off,
box[i].y1 + dst_y_off,
box[i].x2 + dst_x_off,
@ -247,7 +248,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
glamor_priv->yInverted,
vertices);
glamor_set_normalize_tcoords(src_xscale,
glamor_set_normalize_tcoords(src_pixmap_priv, src_xscale,
src_yscale,
box[i].x1 + dx,
box[i].y1 + dy,
@ -320,7 +321,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off,
&dst_y_off);
if (src_pixmap_priv->fbo && src_pixmap_priv->fbo->fb == dst_pixmap_priv->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 y_shift = abs(src_y_off - dy - dst_y_off);
for (i = 0; i < nbox; i++) {
@ -333,7 +334,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
}
#ifndef GLAMOR_GLES2
if ((overlaped
|| !src_pixmap_priv->gl_tex || !dst_pixmap_priv->gl_tex)
|| !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
&& glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx,
dy)) {
ret = TRUE;

View File

@ -43,9 +43,9 @@ glamor_get_drawable_location(const DrawablePtr drawable)
glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(drawable->pScreen);
if (pixmap_priv == NULL || pixmap_priv->gl_fbo == 0)
if (pixmap_priv == NULL || pixmap_priv->base.gl_fbo == 0)
return 'm';
if (pixmap_priv->fbo->fb == glamor_priv->screen_fbo)
if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo)
return 's';
else
return 'f';
@ -327,7 +327,7 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
glamor_restore_pixmap_to_texture(pixmap);
}
if (pixmap_priv->fbo->pbo != 0 && pixmap_priv->fbo->pbo_valid) {
if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) {
glamor_gl_dispatch *dispatch;
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
@ -335,20 +335,20 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
dispatch = glamor_get_dispatch(glamor_priv);
dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
dispatch->glDeleteBuffers(1, &pixmap_priv->fbo->pbo);
dispatch->glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
glamor_put_dispatch(glamor_priv);
pixmap_priv->fbo->pbo_valid = FALSE;
pixmap_priv->fbo->pbo = 0;
pixmap_priv->base.fbo->pbo_valid = FALSE;
pixmap_priv->base.fbo->pbo = 0;
} else {
free(pixmap->devPrivate.ptr);
}
if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
pixmap->devKind = pixmap_priv->drm_stride;
pixmap->devKind = pixmap_priv->base.drm_stride;
if (pixmap_priv->gl_fbo == GLAMOR_FBO_DOWNLOADED)
pixmap_priv->gl_fbo = GLAMOR_FBO_NORMAL;
if (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED)
pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
pixmap->devPrivate.ptr = NULL;
}

View File

@ -107,8 +107,10 @@ AbortServer(void)
_glamor_priv_->delayed_fallback_string); \
_glamor_priv_->delayed_fallback_pending = 0; } } while(0)
#define DEBUGF(str, ...)
#define DEBUGF(str, ...) do {} while(0)
//#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__)
#define DEBUGRegionPrint(x) do {} while (0)
//#define DEBUGRegionPrint RegionPrint
#endif

View File

@ -412,11 +412,11 @@ glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
if (pixmap_priv == NULL)
return NULL;
fbo = pixmap_priv->fbo;
fbo = pixmap_priv->base.fbo;
if (fbo == NULL)
return NULL;
pixmap_priv->fbo = NULL;
pixmap_priv->base.fbo = NULL;
return fbo;
}
@ -434,25 +434,25 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
pixmap_priv = calloc(1, sizeof(*pixmap_priv));
dixSetPrivate(&pixmap->devPrivates,
glamor_pixmap_private_key, pixmap_priv);
pixmap_priv->container = pixmap;
pixmap_priv->glamor_priv = glamor_priv;
pixmap_priv->base.pixmap = pixmap;
pixmap_priv->base.glamor_priv = glamor_priv;
pixmap_priv->type = GLAMOR_MEMORY;
}
if (pixmap_priv->fbo)
if (pixmap_priv->base.fbo)
return;
pixmap_priv->fbo = fbo;
pixmap_priv->base.fbo = fbo;
switch (pixmap_priv->type) {
case GLAMOR_TEXTURE_ONLY:
case GLAMOR_TEXTURE_DRM:
pixmap_priv->gl_fbo = 1;
pixmap_priv->base.gl_fbo = 1;
if (fbo->tex != 0)
pixmap_priv->gl_tex = 1;
pixmap_priv->base.gl_tex = 1;
else {
/* XXX For the Xephyr only, may be broken now.*/
pixmap_priv->gl_tex = 0;
pixmap_priv->base.gl_tex = 0;
}
case GLAMOR_MEMORY_MAP:
pixmap->devPrivate.ptr = NULL;
@ -472,7 +472,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (pixmap_priv == NULL || pixmap_priv->fbo == NULL) {
if (pixmap_priv == NULL || pixmap_priv->base.fbo == NULL) {
fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
pixmap->drawable.height,
@ -484,12 +484,12 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
glamor_pixmap_attach_fbo(pixmap, fbo);
} else {
/* We do have a fbo, but it may lack of fb or tex. */
if (!pixmap_priv->fbo->tex)
pixmap_priv->fbo->tex = _glamor_create_tex(glamor_priv, pixmap->drawable.width,
if (!pixmap_priv->base.fbo->tex)
pixmap_priv->base.fbo->tex = _glamor_create_tex(glamor_priv, pixmap->drawable.width,
pixmap->drawable.height, format);
if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
glamor_pixmap_ensure_fb(pixmap_priv->fbo);
if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0)
glamor_pixmap_ensure_fb(pixmap_priv->base.fbo);
}
pixmap_priv = glamor_get_pixmap_private(pixmap);
@ -504,7 +504,7 @@ glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back)
front_priv = glamor_get_pixmap_private(front);
back_priv = glamor_get_pixmap_private(back);
temp_fbo = front_priv->fbo;
front_priv->fbo = back_priv->fbo;
back_priv->fbo = temp_fbo;
temp_fbo = front_priv->base.fbo;
front_priv->base.fbo = back_priv->base.fbo;
back_priv->base.fbo = temp_fbo;
}

View File

@ -239,7 +239,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
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);

View File

@ -806,14 +806,14 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
*xscale, *yscale, x_source, y_source,
dst_picture->pDrawable->width, dst_picture->pDrawable->height);
glamor_set_normalize_vcoords(*xscale, *yscale,
glamor_set_normalize_vcoords(pixmap_priv, *xscale, *yscale,
0, 0,
(INT16)(dst_picture->pDrawable->width),
(INT16)(dst_picture->pDrawable->height),
glamor_priv->yInverted, vertices);
if (tex_normalize) {
glamor_set_normalize_tcoords(*xscale, *yscale,
glamor_set_normalize_tcoords(pixmap_priv, *xscale, *yscale,
x_source, y_source,
(INT16)(dst_picture->pDrawable->width + x_source),
(INT16)(dst_picture->pDrawable->height + y_source),

View File

@ -101,8 +101,8 @@ glamor_create_picture(PicturePtr picture)
}
}
pixmap_priv->is_picture = 1;
pixmap_priv->pict_format = picture->format;
pixmap_priv->base.is_picture = 1;
pixmap_priv->base.picture = picture;
return miCreatePicture(picture);
}
@ -123,8 +123,8 @@ glamor_destroy_picture(PicturePtr picture)
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (pixmap_priv) {
pixmap_priv->is_picture = 0;
pixmap_priv->pict_format = 0;
pixmap_priv->base.is_picture = 0;
pixmap_priv->base.picture = NULL;
}
miDestroyPicture(picture);
}
@ -133,5 +133,5 @@ void
glamor_picture_format_fixup(PicturePtr picture,
glamor_pixmap_private * pixmap_priv)
{
pixmap_priv->pict_format = picture->format;
pixmap_priv->base.picture = picture;
}

View File

@ -83,9 +83,9 @@ glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0, int w
void
glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private * pixmap_priv)
{
glamor_set_destination_pixmap_fbo(pixmap_priv->fbo, 0, 0,
pixmap_priv->container->drawable.width,
pixmap_priv->container->drawable.height);
glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0,
pixmap_priv->base.pixmap->drawable.width,
pixmap_priv->base.pixmap->drawable.height);
}
int
@ -495,8 +495,8 @@ ready_to_upload:
&& revert == REVERT_NONE
&& swap_rb == SWAP_NONE_UPLOADING
&& !need_flip) {
assert(pixmap_priv->fbo->tex);
__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
assert(pixmap_priv->base.fbo->tex);
__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
format, type,
x, y, w, h,
bits, pbo);
@ -509,7 +509,7 @@ ready_to_upload:
ptexcoords = texcoords_inv;
pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
glamor_set_normalize_vcoords(dst_xscale,
glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
dst_yscale,
x, y,
x + w, y + h,
@ -586,14 +586,14 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
if (pixmap_priv->fbo
&& (pixmap_priv->fbo->width < pixmap->drawable.width
|| pixmap_priv->fbo->height < pixmap->drawable.height)) {
if (pixmap_priv->base.fbo
&& (pixmap_priv->base.fbo->width < pixmap->drawable.width
|| pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
fbo = glamor_pixmap_detach_fbo(pixmap_priv);
glamor_destroy_fbo(fbo);
}
if (pixmap_priv->fbo && pixmap_priv->fbo->fb)
if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)
return 0;
if (!(no_alpha
@ -605,8 +605,8 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
flag = GLAMOR_CREATE_FBO_NO_FBO;
}
if ((flag == 0 && pixmap_priv && pixmap_priv->fbo && pixmap_priv->fbo->tex)
|| (flag != 0 && pixmap_priv && pixmap_priv->fbo && pixmap_priv->fbo->fb))
if ((flag == 0 && pixmap_priv && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
|| (flag != 0 && pixmap_priv && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
return 0;
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
@ -614,7 +614,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
else
iformat = format;
if (pixmap_priv == NULL || pixmap_priv->fbo == NULL) {
if (pixmap_priv == NULL || pixmap_priv->base.fbo == NULL) {
fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
pixmap->drawable.height,
@ -672,10 +672,10 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (pixmap_priv
&& (pixmap_priv->fbo)
&& (pixmap_priv->fbo->pbo_valid)) {
&& (pixmap_priv->base.fbo)
&& (pixmap_priv->base.fbo->pbo_valid)) {
data = NULL;
pbo = pixmap_priv->fbo->pbo;
pbo = pixmap_priv->base.fbo->pbo;
} else {
data = pixmap->devPrivate.ptr;
pbo = 0;
@ -737,7 +737,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
temp_xscale = 1.0 / w;
temp_yscale = 1.0 / h;
glamor_set_normalize_vcoords(temp_xscale,
glamor_set_normalize_vcoords((glamor_pixmap_private *)NULL, temp_xscale,
temp_yscale,
0, 0,
w, h,
@ -750,7 +750,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
glamor_set_normalize_tcoords(source_xscale,
glamor_set_normalize_tcoords(source_priv, source_xscale,
source_yscale,
x, y,
x + w, y + h,
@ -763,7 +763,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glActiveTexture(GL_TEXTURE0);
dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->fbo->tex);
dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
dispatch->glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
@ -988,16 +988,16 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
data = malloc(stride * pixmap->drawable.height);
} else {
dispatch = glamor_get_dispatch(glamor_priv);
if (pixmap_priv->fbo->pbo == 0)
if (pixmap_priv->base.fbo->pbo == 0)
dispatch->glGenBuffers(1,
&pixmap_priv->fbo->pbo);
&pixmap_priv->base.fbo->pbo);
glamor_put_dispatch(glamor_priv);
pbo = pixmap_priv->fbo->pbo;
pbo = pixmap_priv->base.fbo->pbo;
}
if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) {
stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth);
pixmap_priv->drm_stride = pixmap->devKind;
pixmap_priv->base.drm_stride = pixmap->devKind;
pixmap->devKind = stride;
}
@ -1014,9 +1014,9 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
}
if (pbo != 0)
pixmap_priv->fbo->pbo_valid = 1;
pixmap_priv->base.fbo->pbo_valid = 1;
pixmap_priv->gl_fbo = GLAMOR_FBO_DOWNLOADED;
pixmap_priv->base.gl_fbo = GLAMOR_FBO_DOWNLOADED;
pixmap->devPrivate.ptr = dst;
@ -1036,14 +1036,14 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
GCPtr gc = NULL;
int ret = FALSE;
drawable = &pixmap_priv->container->drawable;
drawable = &pixmap_priv->base.pixmap->drawable;
if (pixmap_priv->container->drawable.width == pixmap_priv->fbo->width
&& pixmap_priv->container->drawable.height == pixmap_priv->fbo->height)
if (pixmap_priv->base.pixmap->drawable.width == pixmap_priv->base.fbo->width
&& pixmap_priv->base.pixmap->drawable.height == pixmap_priv->base.fbo->height)
return TRUE;
old_fbo = pixmap_priv->fbo;
glamor_priv = pixmap_priv->glamor_priv;
old_fbo = pixmap_priv->base.fbo;
glamor_priv = pixmap_priv->base.glamor_priv;
if (!old_fbo)
return FALSE;
@ -1058,7 +1058,7 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
scratch_priv = glamor_get_pixmap_private(scratch);
if (!scratch_priv || !scratch_priv->fbo)
if (!scratch_priv || !scratch_priv->base.fbo)
goto fail;
ValidateGC(&scratch->drawable, gc);
@ -1069,7 +1069,7 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
0, 0);
old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
glamor_pixmap_attach_fbo(pixmap_priv->container, new_fbo);
glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo);
glamor_pixmap_attach_fbo(scratch, old_fbo);
DEBUGF("old %dx%d type %d\n",
@ -1139,11 +1139,11 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
return NULL;
sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
pbo = sub_pixmap_priv ? (sub_pixmap_priv->fbo ? sub_pixmap_priv->fbo->pbo : 0): 0;
pbo = sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base.fbo->pbo : 0): 0;
if (pixmap_priv->is_picture) {
sub_pixmap_priv->pict_format = pixmap_priv->pict_format;
sub_pixmap_priv->is_picture = pixmap_priv->is_picture;
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
}
if (pbo)
@ -1157,7 +1157,7 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_acces
if (pbo) {
assert(sub_pixmap->devPrivate.ptr == NULL);
sub_pixmap->devPrivate.ptr = data;
sub_pixmap_priv->fbo->pbo_valid = 1;
sub_pixmap_priv->base.fbo->pbo_valid = 1;
}
#if 0
struct pixman_box16 box;
@ -1189,10 +1189,10 @@ glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int
if (access != GLAMOR_ACCESS_RO) {
sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
if (sub_pixmap_priv
&& sub_pixmap_priv->fbo
&& sub_pixmap_priv->fbo->pbo_valid) {
&& sub_pixmap_priv->base.fbo
&& sub_pixmap_priv->base.fbo->pbo_valid) {
bits = NULL;
pbo = sub_pixmap_priv->fbo->pbo;
pbo = sub_pixmap_priv->base.fbo->pbo;
} else {
bits = sub_pixmap->devPrivate.ptr;
pbo = 0;

View File

@ -309,18 +309,131 @@ typedef struct glamor_pixmap_fbo {
* @gl_tex: The pixmap is in a gl texture originally.
* @is_picture: The drawable is attached to a picture.
* @pict_format: the corresponding picture's format.
* @container: The corresponding pixmap's pointer.
* @pixmap: The corresponding pixmap's pointer.
*
* For GLAMOR_TEXTURE_LARGE, nbox should larger than 1.
* And the box and fbo will both have nbox elements.
* and box[i] store the relatively coords in this pixmap
* of the fbo[i]. The reason why use boxes not region to
* represent this structure is we may need to use overlapped
* boxes for one pixmap for some special reason.
*
* pixmap
* ******************
* * fbo0 * fbo1 *
* * * *
* ******************
* * fbo2 * fbo3 *
* * * *
* ******************
*
* Let's assume the texture has size of 1024x1024
* box[0] = {0,0,1024,1024}
* box[1] = {1024,0,2048,2048}
* ...
*
* For GLAMOR_TEXTURE_ATLAS nbox should be 1. And box
* and fbo both has one elements, and the box store
* the relatively coords in the fbo of this pixmap:
*
* fbo
* ******************
* * pixmap *
* * ********* *
* * * * *
* * ********* *
* * *
* ******************
*
* Assume the pixmap is at the (100,100) relatively to
* the fbo's origin.
* box[0]={100, 100, 1124, 1124};
*
* Considering large pixmap is not a normal case, to keep
* it simple, I designe it as the following way.
* When deal with a large pixmap, it split the working
* rectangle into serval boxes, and each box fit into a
* corresponding fbo. And then the rendering function will
* loop from the left-top box to the right-bottom box,
* each time, we will set current box and current fbo
* to the box and fbo elements. Thus the inner routines
* can handle it as normal, only the coords calculation need
* to aware of it's large pixmap.
*
* Currently, we haven't implemented the atlas pixmap.
*
**/
typedef struct glamor_pixmap_private {
typedef struct glamor_pixmap_clipped_regions{
int block_idx;
RegionPtr region;
} glamor_pixmap_clipped_regions;
#define SET_PIXMAP_FBO_CURRENT(priv, idx) \
do { \
if (priv->type == GLAMOR_TEXTURE_LARGE) { \
(priv)->large.base.fbo = priv->large.fbo_array[idx]; \
(priv)->large.box = priv->large.box_array[idx]; \
} \
} while(0)
typedef struct glamor_pixmap_private_base {
glamor_pixmap_type_t type;
unsigned char gl_fbo:2;
unsigned char is_picture:1;
unsigned char gl_tex:1;
glamor_pixmap_type_t type;
glamor_pixmap_fbo *fbo;
PictFormatShort pict_format;
PixmapPtr container;
PixmapPtr pixmap;
int drm_stride;
glamor_screen_private *glamor_priv;
PicturePtr picture;
}glamor_pixmap_private_base_t;
/*
* @base.fbo: current fbo.
* @box: current fbo's coords in the whole pixmap.
* @block_w: block width of this large pixmap.
* @block_h: block height of this large pixmap.
* @block_wcnt: block count in one block row.
* @block_hcnt: block count in one block column.
* @nbox: total block count.
* @box_array: contains each block's corresponding box.
* @fbo_array: contains each block's fbo pointer.
*
**/
typedef struct glamor_pixmap_private_large {
union {
glamor_pixmap_type_t type;
glamor_pixmap_private_base_t base;
};
BoxRec box;
int block_w;
int block_h;
int block_wcnt;
int block_hcnt;
int nbox;
BoxPtr box_array;
glamor_pixmap_fbo **fbo_array;
}glamor_pixmap_private_large_t;
/*
* @box: the relative coords in the corresponding fbo.
*/
typedef struct glamor_pixmap_private_atlas {
union {
glamor_pixmap_type_t type;
glamor_pixmap_private_base_t base;
};
BoxRec box;
}glamor_pixmap_private_atlas_t;
typedef struct glamor_pixmap_private {
union {
glamor_pixmap_type_t type;
glamor_pixmap_private_base_t base;
glamor_pixmap_private_large_t large;
glamor_pixmap_private_atlas_t atlas;
};
}glamor_pixmap_private;
/*
@ -404,6 +517,7 @@ glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_pri
glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv,
int w, int h, GLenum format, int flag);
void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv);
void glamor_purge_fbo(glamor_pixmap_fbo *fbo);
void glamor_init_pixmap_fbo(ScreenPtr screen);
@ -413,6 +527,11 @@ void glamor_fbo_expire(glamor_screen_private *glamor_priv);
void glamor_init_pixmap_fbo(ScreenPtr screen);
void glamor_fini_pixmap_fbo(ScreenPtr screen);
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 *);
Bool glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv);
/* glamor_copyarea.c */
@ -543,6 +662,19 @@ void glamor_init_putimage_shaders(ScreenPtr screen);
void glamor_fini_putimage_shaders(ScreenPtr screen);
/* glamor_render.c */
Bool
glamor_composite_clipped_region(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
RegionPtr region,
int x_source,
int y_source,
int x_mask,
int y_mask,
int x_dest,
int y_dest);
void glamor_composite(CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
@ -552,6 +684,7 @@ void glamor_composite(CARD8 op,
INT16 xMask,
INT16 yMask,
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
void glamor_trapezoids(CARD8 op,
PicturePtr src, PicturePtr dst,
PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
@ -654,7 +787,6 @@ Bool
glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h,
int stride, void *bits, int pbo);
PixmapPtr
glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y,
int w, int h, glamor_access_t access);
@ -662,6 +794,44 @@ void
glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
int w, int h, glamor_access_t access);
glamor_pixmap_clipped_regions *
glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, int *clipped_nbox, int repeat_type);
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 *
glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform,
RegionPtr region, int *n_region, int dx, int dy, int repeat_type);
Bool
glamor_composite_largepixmap_region(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
glamor_pixmap_private * source_pixmap_priv,
glamor_pixmap_private * mask_pixmap_priv,
glamor_pixmap_private * dest_pixmap_priv,
RegionPtr region, Bool force_clip,
INT16 x_source,
INT16 y_source,
INT16 x_mask,
INT16 y_mask,
INT16 x_dest, INT16 y_dest,
CARD16 width, CARD16 height);
Bool
glamor_get_transform_block_size(struct pixman_transform *transform,
int block_w, int block_h,
int *transformed_block_w,
int *transformed_block_h);
void
glamor_get_transform_extent_from_box(struct pixman_box32 *temp_box,
struct pixman_transform *transform);
/**
* Upload a picture to gl texture. Similar to the
@ -757,5 +927,6 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
#ifndef GLAMOR_GLES2
#define GLAMOR_GRADIENT_SHADER
#endif
#define GLAMOR_TEXTURED_LARGE_PIXMAP 1
#endif /* GLAMOR_PRIV_H */

View File

@ -295,9 +295,9 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
if (pixmap_priv->is_picture) {
temp_pixmap_priv->pict_format = pixmap_priv->pict_format;
temp_pixmap_priv->is_picture = pixmap_priv->is_picture;
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
temp_pixmap_priv->base.picture = pixmap_priv->base.picture;
temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
}
glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,

View File

@ -545,7 +545,7 @@ glamor_set_composite_texture(ScreenPtr screen, int unit,
dispatch = glamor_get_dispatch(glamor_priv);
dispatch->glActiveTexture(GL_TEXTURE0 + unit);
dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
repeat_type = picture->repeatType;
switch (picture->repeatType) {
case RepeatNone:
@ -1047,7 +1047,7 @@ glamor_composite_with_shader(CARD8 op,
glamor_fallback("source == dest\n");
goto fail;
}
if (!source_pixmap_priv || source_pixmap_priv->gl_fbo == 0) {
if (!source_pixmap_priv || source_pixmap_priv->base.gl_fbo == 0) {
/* 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
* refer the tex zero directly latter in the composition.
@ -1068,7 +1068,7 @@ glamor_composite_with_shader(CARD8 op,
glamor_fallback("mask == dest\n");
goto fail;
}
if (!mask_pixmap_priv || mask_pixmap_priv->gl_fbo == 0) {
if (!mask_pixmap_priv || mask_pixmap_priv->base.gl_fbo == 0) {
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
mask_status = GLAMOR_UPLOAD_PENDING;
#else
@ -1259,7 +1259,7 @@ glamor_composite_with_shader(CARD8 op,
width = rects->width;
height = rects->height;
glamor_set_normalize_vcoords(dst_xscale,
glamor_set_normalize_vcoords(dest_pixmap_priv, dst_xscale,
dst_yscale,
x_dest, y_dest,
x_dest + width, y_dest + height,
@ -1269,14 +1269,14 @@ glamor_composite_with_shader(CARD8 op,
if (key.source != SHADER_SOURCE_SOLID) {
if (source->transform)
glamor_set_transformed_normalize_tcoords
(src_matrix, src_xscale,
(source_pixmap_priv, src_matrix, src_xscale,
src_yscale, x_source, y_source,
x_source + width, y_source + height,
glamor_priv->yInverted,
source_texcoords);
else
glamor_set_normalize_tcoords
(src_xscale, src_yscale,
(source_pixmap_priv, src_xscale, src_yscale,
x_source, y_source,
x_source + width, y_source + height,
glamor_priv->yInverted,
@ -1287,7 +1287,7 @@ glamor_composite_with_shader(CARD8 op,
&& key.mask != SHADER_MASK_SOLID) {
if (mask->transform)
glamor_set_transformed_normalize_tcoords
(mask_matrix,
(mask_pixmap_priv, mask_matrix,
mask_xscale,
mask_yscale, x_mask, y_mask,
x_mask + width, y_mask + height,
@ -1295,7 +1295,7 @@ glamor_composite_with_shader(CARD8 op,
mask_texcoords);
else
glamor_set_normalize_tcoords
(mask_xscale,
(mask_pixmap_priv, mask_xscale,
mask_yscale, x_mask, y_mask,
x_mask + width, y_mask + height,
glamor_priv->yInverted,

View File

@ -166,13 +166,12 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
&src_yscale);
dispatch->glUseProgram(glamor_priv->tile_prog);
wh[0] = (float)src_pixmap_priv->fbo->width / tile->drawable.width;
wh[1] = (float)src_pixmap_priv->fbo->height / tile->drawable.height;
glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
dispatch->glUniform2fv(glamor_priv->tile_wh, 1, wh);
dispatch->glActiveTexture(GL_TEXTURE0);
dispatch->glBindTexture(GL_TEXTURE_2D,
src_pixmap_priv->fbo->tex);
src_pixmap_priv->base.fbo->tex);
dispatch->glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
@ -186,7 +185,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
#ifndef GLAMOR_GLES2
dispatch->glEnable(GL_TEXTURE_2D);
#endif
glamor_set_normalize_tcoords(src_xscale, src_yscale,
glamor_set_normalize_tcoords(src_pixmap_priv, src_xscale,
src_yscale,
tile_x1, tile_y1,
tile_x2, tile_y2,
glamor_priv->yInverted,
@ -197,7 +197,8 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
source_texcoords);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale,
dst_yscale,
x1, y1, x2, y2,
glamor_priv->yInverted, vertices);

View File

@ -41,25 +41,49 @@
#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
do { \
*(_pxscale_) = 1.0 / (_pixmap_priv_)->container->drawable.width; \
*(_pyscale_) = 1.0 / (_pixmap_priv_)->container->drawable.height; \
*(_pxscale_) = 1.0 / (_pixmap_priv_)->base.pixmap->drawable.width; \
*(_pyscale_) = 1.0 / (_pixmap_priv_)->base.pixmap->drawable.height; \
} while(0)
#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
do { \
*(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width; \
*(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height; \
*(_pxscale_) = 1.0 / (_pixmap_priv_)->base.fbo->width; \
*(_pyscale_) = 1.0 / (_pixmap_priv_)->base.fbo->height; \
} while(0)
#define GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(priv) \
(priv->fbo->width != priv->container->drawable.width \
|| priv->fbo->height != priv->container->drawable.height)
(priv->base.fbo->width != priv->base.pixmap->drawable.width \
|| priv->base.fbo->height != priv->base.pixmap->drawable.height) \
#define glamor_pixmap_fbo_fix_wh_ratio(wh, priv) do { \
wh[0] = (float)priv->fbo->width \
/ priv->container->drawable.width; \
wh[1] = (float)priv->fbo->height \
/ priv->container->drawable.height; \
#define PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, w, h) \
do { \
if (priv->type == GLAMOR_TEXTURE_LARGE) { \
w = priv->large.box.x2 - priv->large.box.x1; \
h = priv->large.box.y2 - priv->large.box.y1; \
} else { \
w = priv->base.pixmap->drawable.width; \
h = priv->base.pixmap->drawable.height; \
} \
} while(0)
#define glamor_pixmap_fbo_fix_wh_ratio(wh, priv) \
do { \
int actual_w, actual_h; \
PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, actual_w, actual_h); \
wh[0] = (float)priv->base.fbo->width / actual_w; \
wh[1] = (float)priv->base.fbo->height / actual_h; \
} while(0)
#define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_) \
do { \
if (_priv_ && (_priv_)->type \
== GLAMOR_TEXTURE_LARGE) { \
*(_xoff_) = - (_priv_)->large.box.x1; \
*(_yoff_) = - (_priv_)->large.box.y1; \
} else { \
*(_xoff_) = 0; \
*(_yoff_) = 0; \
} \
} while(0)
#define xFixedToFloat(_val_) ((float)xFixedToInt(_val_) \
@ -82,65 +106,111 @@
} \
} while(0)
#define glamor_set_transformed_point(matrix, xscale, yscale, texcoord, \
x, y, yInverted) \
#define glamor_transform_point(matrix, tx, ty, x, y) \
do { \
float result[4]; \
int i; \
float tx, ty; \
\
float result[4]; \
for (i = 0; i < 3; i++) { \
result[i] = (matrix)[i * 3] * (x) + (matrix)[i * 3 + 1] * (y) \
+ (matrix)[i * 3 + 2]; \
} \
tx = result[0] / result[2]; \
ty = result[1] / result[2]; \
} while(0)
#define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_, \
texcoord, yInverted) \
do { \
(texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \
if (yInverted) \
(texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);\
else \
(texcoord)[1] = t_from_x_coord_y(yscale, _ty_); \
DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \
(texcoord)[1]); \
} while(0)
#define glamor_set_transformed_point(priv, matrix, xscale, \
yscale, texcoord, \
x, y, \
yInverted) \
do { \
float tx, ty; \
int fbo_x_off, fbo_y_off; \
pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \
glamor_transform_point(matrix, tx, ty, x, y); \
DEBUGF("tx %f ty %f fbooff %d %d \n", \
tx, ty, fbo_x_off, fbo_y_off); \
\
tx += fbo_x_off; \
ty += fbo_y_off; \
(texcoord)[0] = t_from_x_coord_x(xscale, tx); \
if (yInverted) \
(texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \
else \
(texcoord)[1] = t_from_x_coord_y(yscale, ty); \
DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \
} while(0)
#define glamor_set_transformed_normalize_tcoords( matrix, \
#define glamor_set_transformed_normalize_tcoords( priv, \
matrix, \
xscale, \
yscale, \
tx1, ty1, tx2, ty2, \
yInverted, texcoords) \
do { \
glamor_set_transformed_point(matrix, xscale, yscale, \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
texcoords, tx1, ty1, \
yInverted); \
glamor_set_transformed_point(matrix, xscale, yscale, \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
texcoords + 2, tx2, ty1, \
yInverted); \
glamor_set_transformed_point(matrix, xscale, yscale, \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
texcoords + 4, tx2, ty2, \
yInverted); \
glamor_set_transformed_point(matrix, xscale, yscale, \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
texcoords + 6, tx1, ty2, \
yInverted); \
} while (0)
#define glamor_set_normalize_tcoords(xscale, yscale, x1, y1, x2, y2, \
#define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \
ty1, tx2, ty2, \
yInverted, vertices) \
do { \
(vertices)[0] = t_from_x_coord_x(xscale, x1); \
(vertices)[2] = t_from_x_coord_x(xscale, x2); \
(vertices)[0] = t_from_x_coord_x(xscale, tx1); \
(vertices)[2] = t_from_x_coord_x(xscale, tx2); \
(vertices)[4] = (vertices)[2]; \
(vertices)[6] = (vertices)[0]; \
if (yInverted) { \
(vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \
(vertices)[5] = t_from_x_coord_y_inverted(yscale, y2); \
(vertices)[1] = t_from_x_coord_y_inverted(yscale, ty1); \
(vertices)[5] = t_from_x_coord_y_inverted(yscale, ty2); \
} \
else { \
(vertices)[1] = t_from_x_coord_y(yscale, y1); \
(vertices)[5] = t_from_x_coord_y(yscale, y2); \
(vertices)[1] = t_from_x_coord_y(yscale, ty1); \
(vertices)[5] = t_from_x_coord_y(yscale, ty2); \
} \
(vertices)[3] = (vertices)[1]; \
(vertices)[7] = (vertices)[5]; \
DEBUGF("texture %f %f %f %f\n", tx1, ty1, tx2, ty2); \
DEBUGF("texture %f %f %f %f\n", (vertices)[0], (vertices)[1], \
(vertices)[2], (vertices)[3]); \
DEBUGF("texture %f %f %f %f\n", (vertices)[4], (vertices)[5], \
(vertices)[6], (vertices)[7]); \
} while(0)
#define glamor_set_normalize_tcoords(priv, xscale, yscale, \
x1, y1, x2, y2, \
yInverted, vertices) \
do { \
float tx1, tx2, ty1, ty2; \
int fbo_x_off, fbo_y_off; \
pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \
tx1 = x1 + fbo_x_off; \
tx2 = x2 + fbo_x_off; \
ty1 = y1 + fbo_y_off; \
ty2 = y2 + fbo_y_off; \
_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
tx2, ty2, yInverted, vertices); \
} while(0)
#define glamor_set_tcoords(width, height, x1, y1, x2, y2, \
@ -163,20 +233,23 @@
} while(0)
#define glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2, \
#define glamor_set_normalize_vcoords(priv, xscale, yscale, \
x1, y1, x2, y2, \
yInverted, vertices) \
do { \
(vertices)[0] = v_from_x_coord_x(xscale, x1); \
(vertices)[2] = v_from_x_coord_x(xscale, x2); \
int fbo_x_off, fbo_y_off; \
pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \
(vertices)[0] = v_from_x_coord_x(xscale, x1 + fbo_x_off); \
(vertices)[2] = v_from_x_coord_x(xscale, x2 + fbo_x_off); \
(vertices)[4] = (vertices)[2]; \
(vertices)[6] = (vertices)[0]; \
if (yInverted) { \
(vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \
(vertices)[5] = v_from_x_coord_y_inverted(yscale, y2); \
(vertices)[1] = v_from_x_coord_y_inverted(yscale, y1 + fbo_y_off);\
(vertices)[5] = v_from_x_coord_y_inverted(yscale, y2 + fbo_y_off);\
} \
else { \
(vertices)[1] = v_from_x_coord_y(yscale, y1); \
(vertices)[5] = v_from_x_coord_y(yscale, y2); \
(vertices)[1] = v_from_x_coord_y(yscale, y1 + fbo_y_off); \
(vertices)[5] = v_from_x_coord_y(yscale, y2 + fbo_y_off); \
} \
(vertices)[3] = (vertices)[1]; \
(vertices)[7] = (vertices)[5]; \
@ -244,10 +317,11 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define glamor_check_fbo_size(_glamor_,_w_, _h_) ((_w_) > 0 && (_h_) > 0 \
&& (_w_) < _glamor_->max_fbo_size \
&& (_h_) < _glamor_->max_fbo_size)
&& (_w_) <= _glamor_->max_fbo_size \
&& (_h_) <= _glamor_->max_fbo_size)
/* For 1bpp pixmap, we don't store it as texture. */
#define glamor_check_pixmap_fbo_depth(_depth_) ( \
@ -258,9 +332,9 @@ glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
|| _depth_ == 30 \
|| _depth_ == 32)
#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->is_picture == 1)
#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv && pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv) (pixmap_priv && (pixmap_priv->gl_fbo == GLAMOR_FBO_DOWNLOADED))
#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->base.is_picture == 1)
#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv && pixmap_priv->base.gl_fbo == GLAMOR_FBO_NORMAL)
#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv) (pixmap_priv && (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED))
/**
* Borrow from uxa.
@ -315,7 +389,7 @@ format_for_pixmap(PixmapPtr pixmap)
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
pict_format = pixmap_priv->pict_format;
pict_format = pixmap_priv->base.picture->format;
else
pict_format = format_for_depth(pixmap->drawable.depth);
@ -659,7 +733,7 @@ glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
pict_format = pixmap_priv->pict_format;
pict_format = pixmap_priv->base.picture->format;
else
pict_format = format_for_depth(pixmap->drawable.depth);
@ -783,6 +857,24 @@ inline static Bool glamor_ddx_fallback_check_gc(GCPtr gc)
}
return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable));
}
inline static Bool glamor_is_large_pixmap(PixmapPtr pixmap)
{
glamor_pixmap_private *priv;
priv = glamor_get_pixmap_private(pixmap);
return (priv->type == GLAMOR_TEXTURE_LARGE);
}
inline static Bool glamor_is_large_picture(PicturePtr picture)
{
PixmapPtr pixmap;
if (picture->pDrawable) {
pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
return glamor_is_large_pixmap(pixmap);
}
return FALSE;
}
inline static Bool glamor_tex_format_is_readable(GLenum format)
{