Commit ace35e40 authored by Zhigang Gong's avatar Zhigang Gong Committed by Eric Anholt

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: default avatarZhigang Gong <zhigang.gong@linux.intel.com>
parent 4c174f4c
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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
......@@ -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;
}
......@@ -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);
......
......@@ -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),
......
......@@ -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;
}
......@@ -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;
......
......@@ -309,19 +309,132 @@ 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;
} glamor_pixmap_private;
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;
/*
* Pixmap dynamic status, used by dynamic upload feature.
......@@ -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);