aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/glamor/glamor_pixmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/glamor/glamor_pixmap.c')
-rw-r--r--xorg-server/glamor/glamor_pixmap.c2245
1 files changed, 1115 insertions, 1130 deletions
diff --git a/xorg-server/glamor/glamor_pixmap.c b/xorg-server/glamor/glamor_pixmap.c
index 84694ec3c..f7de59c39 100644
--- a/xorg-server/glamor/glamor_pixmap.c
+++ b/xorg-server/glamor/glamor_pixmap.c
@@ -37,21 +37,20 @@
*/
void
glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
- int *x, int *y)
+ int *x, int *y)
{
#ifdef COMPOSITE
- if (drawable->type == DRAWABLE_WINDOW) {
- *x = -pixmap->screen_x;
- *y = -pixmap->screen_y;
- return;
- }
+ if (drawable->type == DRAWABLE_WINDOW) {
+ *x = -pixmap->screen_x;
+ *y = -pixmap->screen_y;
+ return;
+ }
#endif
- *x = 0;
- *y = 0;
+ *x = 0;
+ *y = 0;
}
-
void
glamor_pixmap_init(ScreenPtr screen)
{
@@ -64,173 +63,168 @@ glamor_pixmap_fini(ScreenPtr screen)
}
void
-glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo * fbo, int x0, int y0, int width, int height)
+glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *fbo, int x0, int y0,
+ int width, int height)
{
- glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
- dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
+ glamor_gl_dispatch *dispatch = glamor_get_dispatch(fbo->glamor_priv);
+
+ dispatch->glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
#ifndef GLAMOR_GLES2
- dispatch->glMatrixMode(GL_PROJECTION);
- dispatch->glLoadIdentity();
- dispatch->glMatrixMode(GL_MODELVIEW);
- dispatch->glLoadIdentity();
+ dispatch->glMatrixMode(GL_PROJECTION);
+ dispatch->glLoadIdentity();
+ dispatch->glMatrixMode(GL_MODELVIEW);
+ dispatch->glLoadIdentity();
#endif
- dispatch->glViewport(x0, y0,
- width, height);
+ dispatch->glViewport(x0, y0, width, height);
- glamor_put_dispatch(fbo->glamor_priv);
+ glamor_put_dispatch(fbo->glamor_priv);
}
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;
+ int w, h;
- PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h);
- glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0,
- w, h);
+ PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h);
+ glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0, w, h);
}
int
-glamor_set_destination_pixmap_priv(glamor_pixmap_private * pixmap_priv)
+glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv)
{
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
- return -1;
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ return -1;
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
- return 0;
+ glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ return 0;
}
int
glamor_set_destination_pixmap(PixmapPtr pixmap)
{
- int err;
- glamor_pixmap_private *pixmap_priv =
- glamor_get_pixmap_private(pixmap);
+ int err;
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
- err = glamor_set_destination_pixmap_priv(pixmap_priv);
- return err;
+ err = glamor_set_destination_pixmap_priv(pixmap_priv);
+ return err;
}
Bool
glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
{
- if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
- return GL_TRUE;
- }
+ if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
+ return GL_TRUE;
+ }
- glamor_fallback("unsupported planemask %lx\n", planemask);
- return GL_FALSE;
+ glamor_fallback("unsupported planemask %lx\n", planemask);
+ return GL_FALSE;
}
Bool
glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
{
#ifndef GLAMOR_GLES2
- if (alu == GXcopy) {
- dispatch->glDisable(GL_COLOR_LOGIC_OP);
- return TRUE;
- }
- dispatch->glEnable(GL_COLOR_LOGIC_OP);
- switch (alu) {
- case GXclear:
- dispatch->glLogicOp(GL_CLEAR);
- break;
- case GXand:
- dispatch->glLogicOp(GL_AND);
- break;
- case GXandReverse:
- dispatch->glLogicOp(GL_AND_REVERSE);
- break;
- case GXandInverted:
- dispatch->glLogicOp(GL_AND_INVERTED);
- break;
- case GXnoop:
- dispatch->glLogicOp(GL_NOOP);
- break;
- case GXxor:
- dispatch->glLogicOp(GL_XOR);
- break;
- case GXor:
- dispatch->glLogicOp(GL_OR);
- break;
- case GXnor:
- dispatch->glLogicOp(GL_NOR);
- break;
- case GXequiv:
- dispatch->glLogicOp(GL_EQUIV);
- break;
- case GXinvert:
- dispatch->glLogicOp(GL_INVERT);
- break;
- case GXorReverse:
- dispatch->glLogicOp(GL_OR_REVERSE);
- break;
- case GXcopyInverted:
- dispatch->glLogicOp(GL_COPY_INVERTED);
- break;
- case GXorInverted:
- dispatch->glLogicOp(GL_OR_INVERTED);
- break;
- case GXnand:
- dispatch->glLogicOp(GL_NAND);
- break;
- case GXset:
- dispatch->glLogicOp(GL_SET);
- break;
- default:
- glamor_fallback("unsupported alu %x\n", alu);
- return FALSE;
- }
+ if (alu == GXcopy) {
+ dispatch->glDisable(GL_COLOR_LOGIC_OP);
+ return TRUE;
+ }
+ dispatch->glEnable(GL_COLOR_LOGIC_OP);
+ switch (alu) {
+ case GXclear:
+ dispatch->glLogicOp(GL_CLEAR);
+ break;
+ case GXand:
+ dispatch->glLogicOp(GL_AND);
+ break;
+ case GXandReverse:
+ dispatch->glLogicOp(GL_AND_REVERSE);
+ break;
+ case GXandInverted:
+ dispatch->glLogicOp(GL_AND_INVERTED);
+ break;
+ case GXnoop:
+ dispatch->glLogicOp(GL_NOOP);
+ break;
+ case GXxor:
+ dispatch->glLogicOp(GL_XOR);
+ break;
+ case GXor:
+ dispatch->glLogicOp(GL_OR);
+ break;
+ case GXnor:
+ dispatch->glLogicOp(GL_NOR);
+ break;
+ case GXequiv:
+ dispatch->glLogicOp(GL_EQUIV);
+ break;
+ case GXinvert:
+ dispatch->glLogicOp(GL_INVERT);
+ break;
+ case GXorReverse:
+ dispatch->glLogicOp(GL_OR_REVERSE);
+ break;
+ case GXcopyInverted:
+ dispatch->glLogicOp(GL_COPY_INVERTED);
+ break;
+ case GXorInverted:
+ dispatch->glLogicOp(GL_OR_INVERTED);
+ break;
+ case GXnand:
+ dispatch->glLogicOp(GL_NAND);
+ break;
+ case GXset:
+ dispatch->glLogicOp(GL_SET);
+ break;
+ default:
+ glamor_fallback("unsupported alu %x\n", alu);
+ return FALSE;
+ }
#else
- if (alu != GXcopy)
- return FALSE;
+ if (alu != GXcopy)
+ return FALSE;
#endif
- return TRUE;
+ return TRUE;
}
static void *
-_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride, int revert)
+_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
+ int stride, int revert)
{
- PictFormatShort dst_format, src_format;
- pixman_image_t *dst_image;
- pixman_image_t *src_image;
- int src_stride;
-
- if (revert == REVERT_UPLOADING_A1) {
- src_format = PICT_a1;
- dst_format = PICT_a8;
- src_stride = PixmapBytePad(w, 1);
- } else {
- dst_format = PICT_a1;
- src_format = PICT_a8;
- src_stride = (((w * 8 + 7) / 8) + 3) & ~3;
- }
-
- dst_image = pixman_image_create_bits(dst_format,
- w, h,
- dst_bits,
- stride);
- if (dst_image == NULL) {
- return NULL;
- }
-
- src_image = pixman_image_create_bits(src_format,
- w, h,
- src_bits,
- src_stride);
-
- if (src_image == NULL) {
- pixman_image_unref(dst_image);
- return NULL;
- }
-
- pixman_image_composite(PictOpSrc, src_image, NULL, dst_image,
- 0, 0, 0, 0, 0, 0,
- w,h);
-
- pixman_image_unref(src_image);
- pixman_image_unref(dst_image);
- return dst_bits;
+ PictFormatShort dst_format, src_format;
+ pixman_image_t *dst_image;
+ pixman_image_t *src_image;
+ int src_stride;
+
+ if (revert == REVERT_UPLOADING_A1) {
+ src_format = PICT_a1;
+ dst_format = PICT_a8;
+ src_stride = PixmapBytePad(w, 1);
+ }
+ else {
+ dst_format = PICT_a1;
+ src_format = PICT_a8;
+ src_stride = (((w * 8 + 7) / 8) + 3) & ~3;
+ }
+
+ dst_image = pixman_image_create_bits(dst_format, w, h, dst_bits, stride);
+ if (dst_image == NULL) {
+ return NULL;
+ }
+
+ src_image = pixman_image_create_bits(src_format,
+ w, h, src_bits, src_stride);
+
+ if (src_image == NULL) {
+ pixman_image_unref(dst_image);
+ return NULL;
+ }
+
+ pixman_image_composite(PictOpSrc, src_image, NULL, dst_image,
+ 0, 0, 0, 0, 0, 0, w, h);
+
+ pixman_image_unref(src_image);
+ pixman_image_unref(dst_image);
+ return dst_bits;
}
#define ADJUST_BITS(d, src_bits, dst_bits) (((dst_bits) == (src_bits)) ? (d) : \
@@ -248,7 +242,7 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st
b_shift, b_bits, \
g_shift, g_bits, \
r_shift, r_bits) \
- { \
+ do { \
typeof(src) a,b,g,r; \
typeof(src) a_mask_src, b_mask_src, g_mask_src, r_mask_src;\
a_mask_src = (((1 << (a_bits_src)) - 1) << a_shift_src);\
@@ -270,79 +264,80 @@ _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int st
(*dst) = ((a) << (a_shift)) | ((b) << (b_shift)) | ((g) << (g_shift)) | ((r) << (r_shift)); \
else \
(*dst) = ((a) << (a_shift)) | ((r) << (b_shift)) | ((g) << (g_shift)) | ((b) << (r_shift)); \
- }
+ } while (0)
static void *
-_glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+_glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h,
+ int stride, int no_alpha, int revert,
+ int swap_rb)
{
- int x,y;
- unsigned int *words, *saved_words, *source_words;
- int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || swap_rb == SWAP_NONE_UPLOADING);
-
- source_words = src_bits;
- words = dst_bits;
- saved_words = words;
-
- for (y = 0; y < h; y++)
- {
- DEBUGF("Line %d : ", y);
- for (x = 0; x < w; x++)
- {
- unsigned int pixel = source_words[x];
-
- if (revert == REVERT_DOWNLOADING_2_10_10_10)
- GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
- 24, 8, 16, 8, 8, 8, 0, 8,
- 30, 2, 20, 10, 10, 10, 0, 10)
- else
- GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
- 30, 2, 20, 10, 10, 10, 0, 10,
- 24, 8, 16, 8, 8, 8, 0, 8);
- DEBUGF("%x:%x ", pixel, words[x]);
- }
- DEBUGF("\n");
- words += stride / sizeof(*words);
- source_words += stride / sizeof(*words);
- }
- DEBUGF("\n");
- return saved_words;
+ int x, y;
+ unsigned int *words, *saved_words, *source_words;
+ int swap = !(swap_rb == SWAP_NONE_DOWNLOADING ||
+ swap_rb == SWAP_NONE_UPLOADING);
+
+ source_words = src_bits;
+ words = dst_bits;
+ saved_words = words;
+
+ for (y = 0; y < h; y++) {
+ DEBUGF("Line %d : ", y);
+ for (x = 0; x < w; x++) {
+ unsigned int pixel = source_words[x];
+
+ if (revert == REVERT_DOWNLOADING_2_10_10_10)
+ GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+ 24, 8, 16, 8, 8, 8, 0, 8,
+ 30, 2, 20, 10, 10, 10, 0, 10);
+ else
+ GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+ 30, 2, 20, 10, 10, 10, 0, 10,
+ 24, 8, 16, 8, 8, 8, 0, 8);
+ DEBUGF("%x:%x ", pixel, words[x]);
+ }
+ DEBUGF("\n");
+ words += stride / sizeof(*words);
+ source_words += stride / sizeof(*words);
+ }
+ DEBUGF("\n");
+ return saved_words;
}
static void *
-_glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+_glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
+ int stride, int no_alpha, int revert, int swap_rb)
{
- int x,y;
- unsigned short *words, *saved_words, *source_words;
- int swap = !(swap_rb == SWAP_NONE_DOWNLOADING || swap_rb == SWAP_NONE_UPLOADING);
-
- words = dst_bits;
- source_words = src_bits;
- saved_words = words;
-
- for (y = 0; y < h; y++)
- {
- DEBUGF("Line %d : ", y);
- for (x = 0; x < w; x++)
- {
- unsigned short pixel = source_words[x];
-
- if (revert == REVERT_DOWNLOADING_1_5_5_5)
- GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
- 0, 1, 1, 5, 6, 5, 11, 5,
- 15, 1, 10, 5, 5, 5, 0, 5)
- else
- GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
- 15, 1, 10, 5, 5, 5, 0, 5,
- 0, 1, 1, 5, 6, 5, 11, 5);
- DEBUGF("%04x:%04x ", pixel, words[x]);
- }
- DEBUGF("\n");
- words += stride / sizeof(*words);
- source_words += stride / sizeof(*words);
- }
- DEBUGF("\n");
- return saved_words;
+ int x, y;
+ unsigned short *words, *saved_words, *source_words;
+ int swap = !(swap_rb == SWAP_NONE_DOWNLOADING ||
+ swap_rb == SWAP_NONE_UPLOADING);
+
+ words = dst_bits;
+ source_words = src_bits;
+ saved_words = words;
+
+ for (y = 0; y < h; y++) {
+ DEBUGF("Line %d : ", y);
+ for (x = 0; x < w; x++) {
+ unsigned short pixel = source_words[x];
+
+ if (revert == REVERT_DOWNLOADING_1_5_5_5)
+ GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+ 0, 1, 1, 5, 6, 5, 11, 5,
+ 15, 1, 10, 5, 5, 5, 0, 5);
+ else
+ GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+ 15, 1, 10, 5, 5, 5, 0, 5,
+ 0, 1, 1, 5, 6, 5, 11, 5);
+ DEBUGF("%04x:%04x ", pixel, words[x]);
+ }
+ DEBUGF("\n");
+ words += stride / sizeof(*words);
+ source_words += stride / sizeof(*words);
+ }
+ DEBUGF("\n");
+ return saved_words;
}
/*
@@ -364,18 +359,28 @@ _glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h, int
*/
static void *
-glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, int stride, int no_alpha, int revert, int swap_rb)
+glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h,
+ int stride, int no_alpha, int revert, int swap_rb)
{
- if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) {
- return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride, revert);
- } else if (revert == REVERT_DOWNLOADING_2_10_10_10 || revert == REVERT_UPLOADING_2_10_10_10) {
- return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h, stride, no_alpha, revert, swap_rb);
- } else if (revert == REVERT_DOWNLOADING_1_5_5_5 || revert == REVERT_UPLOADING_1_5_5_5) {
- return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride, no_alpha, revert, swap_rb);
- } else
- ErrorF("convert a non-supported mode %x.\n", revert);
-
- return NULL;
+ if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) {
+ return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride,
+ revert);
+ }
+ else if (revert == REVERT_DOWNLOADING_2_10_10_10 ||
+ revert == REVERT_UPLOADING_2_10_10_10) {
+ return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h,
+ stride, no_alpha, revert,
+ swap_rb);
+ }
+ else if (revert == REVERT_DOWNLOADING_1_5_5_5 ||
+ revert == REVERT_UPLOADING_1_5_5_5) {
+ return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride,
+ no_alpha, revert, swap_rb);
+ }
+ else
+ ErrorF("convert a non-supported mode %x.\n", revert);
+
+ return NULL;
}
/**
@@ -385,198 +390,182 @@ glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h, int s
int in_restore = 0;
static void
__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
- GLenum format,
- GLenum type,
- int x, int y, int w, int h,
- void *bits, int pbo)
+ GLenum format,
+ GLenum type,
+ int x, int y, int w, int h,
+ void *bits, int pbo)
{
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(pixmap->drawable.pScreen);
- glamor_gl_dispatch *dispatch;
- int non_sub = 0;
- unsigned int iformat = 0;
-
- dispatch = glamor_get_dispatch(glamor_priv);
- if (*tex == 0) {
- dispatch->glGenTextures(1, tex);
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
- gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
- else
- iformat = format;
- non_sub = 1;
- assert(x == 0 && y == 0);
- }
-
- dispatch->glBindTexture(GL_TEXTURE_2D, *tex);
- dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- GL_NEAREST);
- dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- GL_NEAREST);
- dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-
- if (bits == NULL)
- dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
- pbo);
- if (non_sub)
- dispatch->glTexImage2D(GL_TEXTURE_2D,
- 0, iformat, w, h, 0,
- format, type,
- bits);
- else
- dispatch->glTexSubImage2D(GL_TEXTURE_2D,
- 0, x, y, w, h,
- format, type,
- bits);
-
- if (bits == NULL)
- dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- glamor_put_dispatch(glamor_priv);
+ glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(pixmap->drawable.pScreen);
+ glamor_gl_dispatch *dispatch;
+ int non_sub = 0;
+ unsigned int iformat = 0;
+
+ dispatch = glamor_get_dispatch(glamor_priv);
+ if (*tex == 0) {
+ dispatch->glGenTextures(1, tex);
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+ gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
+ else
+ iformat = format;
+ non_sub = 1;
+ assert(x == 0 && y == 0);
+ }
+
+ dispatch->glBindTexture(GL_TEXTURE_2D, *tex);
+ dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+ if (bits == NULL)
+ dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
+ if (non_sub)
+ dispatch->glTexImage2D(GL_TEXTURE_2D,
+ 0, iformat, w, h, 0, format, type, bits);
+ else
+ dispatch->glTexSubImage2D(GL_TEXTURE_2D,
+ 0, x, y, w, h, format, type, bits);
+
+ if (bits == NULL)
+ dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ glamor_put_dispatch(glamor_priv);
}
static Bool
-_glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, 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_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
+ 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_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
- glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
- glamor_gl_dispatch *dispatch;
- static float vertices[8];
- static float texcoords[8] = { 0, 1,
- 1, 1,
- 1, 0,
- 0, 0
- };
- static float texcoords_inv[8] = { 0, 0,
- 1, 0,
- 1, 1,
- 0, 1
- };
- float *ptexcoords;
- float dst_xscale, dst_yscale;
- GLuint tex = 0;
- int need_flip;
- int need_free_bits = 0;
-
- need_flip = !glamor_priv->yInverted;
-
- if (bits == NULL)
- goto ready_to_upload;
-
- if (revert > REVERT_NORMAL) {
- /* XXX if we are restoring the pixmap, then we may not need to allocate
- * new buffer */
- void *converted_bits;
-
- if (pixmap->drawable.depth == 1)
- stride = (((w * 8 + 7) / 8) + 3) & ~3;
-
- converted_bits = malloc(h * stride);
-
- if (converted_bits == NULL)
- return FALSE;
- bits = glamor_color_convert_to_bits(bits, converted_bits, w, h,
- stride,
- no_alpha, revert, swap_rb);
- if (bits == NULL) {
- ErrorF("Failed to convert pixmap no_alpha %d,"
- "revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb);
- return FALSE;
- }
- no_alpha = 0;
- revert = REVERT_NONE;
- swap_rb = SWAP_NONE_UPLOADING;
- need_free_bits = TRUE;
- }
-
-ready_to_upload:
-
- /* Try fast path firstly, upload the pixmap to the texture attached
- * to the fbo directly. */
- if (no_alpha == 0
- && revert == REVERT_NONE
- && swap_rb == SWAP_NONE_UPLOADING
- && !need_flip
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+ glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(pixmap->drawable.pScreen);
+ glamor_gl_dispatch *dispatch;
+ static float vertices[8];
+
+ static float texcoords[8] = { 0, 1,
+ 1, 1,
+ 1, 0,
+ 0, 0
+ };
+ static float texcoords_inv[8] = { 0, 0,
+ 1, 0,
+ 1, 1,
+ 0, 1
+ };
+ float *ptexcoords;
+ float dst_xscale, dst_yscale;
+ GLuint tex = 0;
+ int need_flip;
+ int need_free_bits = 0;
+
+ need_flip = !glamor_priv->yInverted;
+
+ if (bits == NULL)
+ goto ready_to_upload;
+
+ if (revert > REVERT_NORMAL) {
+ /* XXX if we are restoring the pixmap, then we may not need to allocate
+ * new buffer */
+ void *converted_bits;
+
+ if (pixmap->drawable.depth == 1)
+ stride = (((w * 8 + 7) / 8) + 3) & ~3;
+
+ converted_bits = malloc(h * stride);
+
+ if (converted_bits == NULL)
+ return FALSE;
+ bits = glamor_color_convert_to_bits(bits, converted_bits, w, h,
+ stride, no_alpha, revert, swap_rb);
+ if (bits == NULL) {
+ ErrorF("Failed to convert pixmap no_alpha %d,"
+ "revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb);
+ return FALSE;
+ }
+ no_alpha = 0;
+ revert = REVERT_NONE;
+ swap_rb = SWAP_NONE_UPLOADING;
+ need_free_bits = TRUE;
+ }
+
+ ready_to_upload:
+
+ /* Try fast path firstly, upload the pixmap to the texture attached
+ * to the fbo directly. */
+ if (no_alpha == 0
+ && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING && !need_flip
#ifdef WALKAROUND_LARGE_TEXTURE_MAP
- && pixmap_priv->type != GLAMOR_TEXTURE_LARGE
+ && pixmap_priv->type != GLAMOR_TEXTURE_LARGE
#endif
- ) {
- int fbo_x_off, fbo_y_off;
- 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,
- format, type,
- x + fbo_x_off, y + fbo_y_off, w, h,
- bits, pbo);
- return TRUE;
- }
-
- if (need_flip)
- ptexcoords = texcoords;
- else
- ptexcoords = texcoords_inv;
-
- pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
- glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
- dst_yscale,
- x, y,
- x + w, y + h,
- glamor_priv->yInverted,
- vertices);
- /* Slow path, we need to flip y or wire alpha to 1. */
- dispatch = glamor_get_dispatch(glamor_priv);
- dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
- GL_FALSE, 2 * sizeof(float),
- vertices);
- dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
- dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
- GL_FALSE, 2 * sizeof(float),
- ptexcoords);
- dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
- __glamor_upload_pixmap_to_texture(pixmap, &tex,
- format, type,
- 0, 0, w, h,
- bits, pbo);
- dispatch->glActiveTexture(GL_TEXTURE0);
- dispatch->glBindTexture(GL_TEXTURE_2D, tex);
-
- dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- GL_NEAREST);
- dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- GL_NEAREST);
+ ) {
+ int fbo_x_off, fbo_y_off;
+
+ 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,
+ format, type,
+ x + fbo_x_off, y + fbo_y_off, w, h,
+ bits, pbo);
+ return TRUE;
+ }
+
+ if (need_flip)
+ ptexcoords = texcoords;
+ else
+ ptexcoords = texcoords_inv;
+
+ pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
+ glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
+ dst_yscale,
+ x, y,
+ x + w, y + h,
+ glamor_priv->yInverted, vertices);
+ /* Slow path, we need to flip y or wire alpha to 1. */
+ dispatch = glamor_get_dispatch(glamor_priv);
+ dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+ GL_FALSE, 2 * sizeof(float), vertices);
+ dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+ GL_FALSE, 2 * sizeof(float), ptexcoords);
+ dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+ glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ __glamor_upload_pixmap_to_texture(pixmap, &tex,
+ format, type, 0, 0, w, h, bits, pbo);
+ dispatch->glActiveTexture(GL_TEXTURE0);
+ dispatch->glBindTexture(GL_TEXTURE_2D, tex);
+
+ dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#ifndef GLAMOR_GLES2
- dispatch->glEnable(GL_TEXTURE_2D);
+ dispatch->glEnable(GL_TEXTURE_2D);
#endif
- dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
- dispatch->glUniform1i(glamor_priv->
- finish_access_revert[no_alpha],
- revert);
- dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
- swap_rb);
+ dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+ dispatch->glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
+ dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
+ swap_rb);
- dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
#ifndef GLAMOR_GLES2
- dispatch->glDisable(GL_TEXTURE_2D);
+ dispatch->glDisable(GL_TEXTURE_2D);
#endif
- dispatch->glUseProgram(0);
- dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- dispatch->glDeleteTextures(1, &tex);
- dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ dispatch->glUseProgram(0);
+ dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+ dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ dispatch->glDeleteTextures(1, &tex);
+ dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
- glamor_put_dispatch(glamor_priv);
+ glamor_put_dispatch(glamor_priv);
- if (need_free_bits)
- free(bits);
- return TRUE;
+ if (need_free_bits)
+ free(bits);
+ return TRUE;
}
/*
@@ -587,54 +576,53 @@ ready_to_upload:
* 2. no_alpha != 0, we need to wire the alpha.
* */
static int
-glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int revert, int swap_rb)
+glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
+ int revert, int swap_rb)
{
- int flag = 0;
- glamor_pixmap_private *pixmap_priv;
- glamor_screen_private *glamor_priv;
- glamor_pixmap_fbo *fbo;
- GLenum iformat;
-
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-
- if (pixmap_priv->base.gl_fbo)
- return 0;
-
- 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->base.fbo && pixmap_priv->base.fbo->fb)
- return 0;
-
- if (!(no_alpha
- || (revert == REVERT_NORMAL)
- || (swap_rb != SWAP_NONE_UPLOADING)
- || !glamor_priv->yInverted)) {
- /* We don't need a fbo, a simple texture uploading should work. */
-
- flag = GLAMOR_CREATE_FBO_NO_FBO;
- }
-
- if ((flag == GLAMOR_CREATE_FBO_NO_FBO
- && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
- || (flag == 0
- && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
- return 0;
-
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
- gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
- else
- iformat = format;
-
- if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
- return -1;
-
- return 0;
+ int flag = 0;
+ glamor_pixmap_private *pixmap_priv;
+ glamor_screen_private *glamor_priv;
+ glamor_pixmap_fbo *fbo;
+ GLenum iformat;
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+
+ if (pixmap_priv->base.gl_fbo)
+ return 0;
+
+ 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->base.fbo && pixmap_priv->base.fbo->fb)
+ return 0;
+
+ if (!(no_alpha || (revert == REVERT_NORMAL)
+ || (swap_rb != SWAP_NONE_UPLOADING)
+ || !glamor_priv->yInverted)) {
+ /* We don't need a fbo, a simple texture uploading should work. */
+
+ flag = GLAMOR_CREATE_FBO_NO_FBO;
+ }
+
+ if ((flag == GLAMOR_CREATE_FBO_NO_FBO
+ && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
+ || (flag == 0 && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
+ return 0;
+
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+ gl_iformat_for_depth(pixmap->drawable.depth, &iformat);
+ else
+ iformat = format;
+
+ if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
+ return -1;
+
+ return 0;
}
/*
@@ -642,185 +630,188 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, int
* */
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 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;
- }
+ 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 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;
- }
-}
+ 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
-glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h,
- int stride, void *bits, int pbo)
+glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
+ int h, int stride, void *bits, int pbo)
{
- GLenum format, type;
- int no_alpha, revert, swap_rb;
- glamor_pixmap_private *pixmap_priv;
- Bool force_clip;
-
- 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 TRUE;
- }
- if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
- return FALSE;
-
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
- && !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
-
- if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
- 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(&region, &box, 1);
- if (!force_clip)
- clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
- else
- clipped_regions = glamor_compute_clipped_regions_ext(pixmap_priv, &region, &n_region,
- pixmap_priv->base.glamor_priv->max_fbo_size,
- pixmap_priv->base.glamor_priv->max_fbo_size, 0, 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(&region);
- free(sub_bits);
- assert(0);
- return FALSE;
- }
- }
- RegionDestroy(clipped_regions[i].region);
- }
- free(sub_bits);
- free(clipped_regions);
- RegionUninit(&region);
- 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);
+ GLenum format, type;
+ int no_alpha, revert, swap_rb;
+ glamor_pixmap_private *pixmap_priv;
+ Bool force_clip;
+
+ 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 TRUE;
+ }
+ if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
+ return FALSE;
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
+ && !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
+
+ if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
+ 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(&region, &box, 1);
+ if (!force_clip)
+ clipped_regions =
+ glamor_compute_clipped_regions(pixmap_priv, &region, &n_region,
+ 0, 0, 0);
+ else
+ clipped_regions =
+ glamor_compute_clipped_regions_ext(pixmap_priv, &region,
+ &n_region,
+ pixmap_priv->base.
+ glamor_priv->max_fbo_size,
+ pixmap_priv->base.
+ glamor_priv->max_fbo_size, 0,
+ 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(&region);
+ free(sub_bits);
+ assert(0);
+ return FALSE;
+ }
+ }
+ RegionDestroy(clipped_regions[i].region);
+ }
+ free(sub_bits);
+ free(clipped_regions);
+ RegionUninit(&region);
+ 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);
}
enum glamor_pixmap_status
glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
{
- glamor_pixmap_private *pixmap_priv;
- void *data;
- int pbo;
- int ret;
-
- pixmap_priv = glamor_get_pixmap_private(pixmap);
-
- if ((pixmap_priv->base.fbo)
- && (pixmap_priv->base.fbo->pbo_valid)) {
- data = NULL;
- pbo = pixmap_priv->base.fbo->pbo;
- } else {
- data = pixmap->devPrivate.ptr;
- pbo = 0;
- }
-
- if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0,
- pixmap->drawable.width,
- pixmap->drawable.height,
- pixmap->devKind,
- data, pbo))
- ret = GLAMOR_UPLOAD_DONE;
- else
- ret = GLAMOR_UPLOAD_FAILED;
-
- return ret;
+ glamor_pixmap_private *pixmap_priv;
+ void *data;
+ int pbo;
+ int ret;
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+ if ((pixmap_priv->base.fbo)
+ && (pixmap_priv->base.fbo->pbo_valid)) {
+ data = NULL;
+ pbo = pixmap_priv->base.fbo->pbo;
+ }
+ else {
+ data = pixmap->devPrivate.ptr;
+ pbo = 0;
+ }
+
+ if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ pixmap->devKind, data, pbo))
+ ret = GLAMOR_UPLOAD_DONE;
+ else
+ ret = GLAMOR_UPLOAD_FAILED;
+
+ return ret;
}
void
glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
{
- if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE)
- LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n");
+ if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE)
+ LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n");
}
/*
@@ -832,83 +823,68 @@ glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
* */
glamor_pixmap_fbo *
-glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLenum format,
- GLenum type, int no_alpha, int revert, int swap_rb)
-
+glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
+ GLenum format, GLenum type, int no_alpha,
+ int revert, int swap_rb)
{
- glamor_pixmap_private *source_priv;
- glamor_screen_private *glamor_priv;
- ScreenPtr screen;
- glamor_pixmap_fbo *temp_fbo;
- glamor_gl_dispatch *dispatch;
- float temp_xscale, temp_yscale, source_xscale, source_yscale;
- static float vertices[8];
- static float texcoords[8];
-
- screen = source->drawable.pScreen;
-
- glamor_priv = glamor_get_screen_private(screen);
- source_priv = glamor_get_pixmap_private(source);
- temp_fbo = glamor_create_fbo(glamor_priv,
- w, h,
- format,
- 0);
- if (temp_fbo == NULL)
- return NULL;
-
- dispatch = glamor_get_dispatch(glamor_priv);
- temp_xscale = 1.0 / w;
- temp_yscale = 1.0 / h;
-
- glamor_set_normalize_vcoords((struct glamor_pixmap_private*)NULL,temp_xscale,
- temp_yscale,
- 0, 0,
- w, h,
- glamor_priv->yInverted,
- vertices);
-
- dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
- GL_FALSE, 2 * sizeof(float),
- vertices);
- dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
- pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
- glamor_set_normalize_tcoords(source_priv, source_xscale,
- source_yscale,
- x, y,
- x + w, y + h,
- glamor_priv->yInverted,
- texcoords);
-
- dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
- GL_FALSE, 2 * sizeof(float),
- texcoords);
- dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
- dispatch->glActiveTexture(GL_TEXTURE0);
- dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
- dispatch->glTexParameteri(GL_TEXTURE_2D,
- GL_TEXTURE_MIN_FILTER,
- GL_NEAREST);
- dispatch->glTexParameteri(GL_TEXTURE_2D,
- GL_TEXTURE_MAG_FILTER,
- GL_NEAREST);
-
- glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
- dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
- dispatch->glUniform1i(glamor_priv->
- finish_access_revert[no_alpha],
- revert);
- dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
- swap_rb);
-
- dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- dispatch->glUseProgram(0);
- glamor_put_dispatch(glamor_priv);
- return temp_fbo;
+ glamor_pixmap_private *source_priv;
+ glamor_screen_private *glamor_priv;
+ ScreenPtr screen;
+ glamor_pixmap_fbo *temp_fbo;
+ glamor_gl_dispatch *dispatch;
+ float temp_xscale, temp_yscale, source_xscale, source_yscale;
+ static float vertices[8];
+ static float texcoords[8];
+
+ screen = source->drawable.pScreen;
+
+ glamor_priv = glamor_get_screen_private(screen);
+ source_priv = glamor_get_pixmap_private(source);
+ temp_fbo = glamor_create_fbo(glamor_priv, w, h, format, 0);
+ if (temp_fbo == NULL)
+ return NULL;
+
+ dispatch = glamor_get_dispatch(glamor_priv);
+ temp_xscale = 1.0 / w;
+ temp_yscale = 1.0 / h;
+
+ glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL,
+ temp_xscale, temp_yscale, 0, 0, w, h,
+ glamor_priv->yInverted, vertices);
+
+ dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+ GL_FALSE, 2 * sizeof(float), vertices);
+ dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+ pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
+ glamor_set_normalize_tcoords(source_priv, source_xscale,
+ source_yscale,
+ x, y,
+ x + w, y + h,
+ glamor_priv->yInverted, texcoords);
+
+ dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+ GL_FALSE, 2 * sizeof(float), texcoords);
+ dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+ dispatch->glActiveTexture(GL_TEXTURE0);
+ dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
+ dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
+ dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+ dispatch->glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
+ dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],
+ swap_rb);
+
+ dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+ dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ dispatch->glUseProgram(0);
+ glamor_put_dispatch(glamor_priv);
+ return temp_fbo;
}
/*
@@ -918,263 +894,263 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLe
static void *
_glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
- 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)
+ 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;
- GLenum gl_access = 0, gl_usage = 0;
- void *data, *read;
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(pixmap->drawable.pScreen);
- glamor_gl_dispatch *dispatch;
- glamor_pixmap_fbo *temp_fbo = NULL;
- int need_post_conversion = 0;
- int need_free_data = 0;
- int fbo_x_off, fbo_y_off;
-
- data = bits;
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
- return NULL;
-
- switch (access) {
- case GLAMOR_ACCESS_RO:
- gl_access = GL_READ_ONLY;
- gl_usage = GL_STREAM_READ;
- break;
- case GLAMOR_ACCESS_WO:
- return bits;
- case GLAMOR_ACCESS_RW:
- gl_access = GL_READ_WRITE;
- gl_usage = GL_DYNAMIC_DRAW;
- break;
- default:
- ErrorF("Glamor: Invalid access code. %d\n", access);
- assert(0);
- }
-
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
- need_post_conversion = (revert > REVERT_NORMAL);
- if (need_post_conversion) {
- if (pixmap->drawable.depth == 1) {
- int temp_stride;
- temp_stride = (((w * 8 + 7) / 8) + 3) & ~3;
- data = malloc(temp_stride * h);
- if (data == NULL)
- return NULL;
- need_free_data = 1;
- }
- }
-
- pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
-
- if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
- && !need_post_conversion
- && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
- if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h,
- format, type, no_alpha,
- revert, swap_rb))) {
- free(data);
- return NULL;
- }
- x = 0;
- y = 0;
- fbo_x_off = 0;
- fbo_y_off = 0;
- }
-
- dispatch = glamor_get_dispatch(glamor_priv);
- dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
-
- if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
-
- if (!glamor_priv->yInverted) {
- assert(glamor_priv->gl_flavor ==
- GLAMOR_GL_DESKTOP);
- dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
- }
-
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) {
- assert(pbo > 0);
- dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
- dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
- stride *
- h,
- NULL, gl_usage);
- }
-
- dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data);
-
- if (!glamor_priv->yInverted) {
- assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
- dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0);
- }
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) {
- bits = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
- gl_access);
- dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
- }
- } else {
- unsigned int temp_pbo;
- int yy;
-
- dispatch = glamor_get_dispatch(glamor_priv);
- dispatch->glGenBuffers(1, &temp_pbo);
- dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER,
- temp_pbo);
- dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
- stride *
- h,
- NULL, GL_STREAM_READ);
- dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h,
- format, type, 0);
- read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER,
- GL_READ_ONLY);
- for (yy = 0; yy < pixmap->drawable.height; yy++)
- memcpy((char*)data + yy * stride,
- (char*)read + (h - yy - 1) * stride, stride);
- dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
- dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
- dispatch->glDeleteBuffers(1, &temp_pbo);
- }
-
- dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
- glamor_put_dispatch(glamor_priv);
-
- if (need_post_conversion) {
- /* As OpenGL desktop version never enters here.
- * Don't need to consider if the pbo is valid.*/
- bits = glamor_color_convert_to_bits(data, bits,
- w, h,
- stride,
- no_alpha,
- revert, swap_rb);
- }
-
- if (temp_fbo != NULL)
- glamor_destroy_fbo(temp_fbo);
- if (need_free_data)
- free(data);
-
- return bits;
+ glamor_pixmap_private *pixmap_priv;
+ GLenum gl_access = 0, gl_usage = 0;
+ void *data, *read;
+ glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(pixmap->drawable.pScreen);
+ glamor_gl_dispatch *dispatch;
+ glamor_pixmap_fbo *temp_fbo = NULL;
+ int need_post_conversion = 0;
+ int need_free_data = 0;
+ int fbo_x_off, fbo_y_off;
+
+ data = bits;
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ return NULL;
+
+ switch (access) {
+ case GLAMOR_ACCESS_RO:
+ gl_access = GL_READ_ONLY;
+ gl_usage = GL_STREAM_READ;
+ break;
+ case GLAMOR_ACCESS_WO:
+ return bits;
+ case GLAMOR_ACCESS_RW:
+ gl_access = GL_READ_WRITE;
+ gl_usage = GL_DYNAMIC_DRAW;
+ break;
+ default:
+ ErrorF("Glamor: Invalid access code. %d\n", access);
+ assert(0);
+ }
+
+ glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+
+ need_post_conversion = (revert > REVERT_NORMAL);
+ if (need_post_conversion) {
+ if (pixmap->drawable.depth == 1) {
+ int temp_stride;
+
+ temp_stride = (((w * 8 + 7) / 8) + 3) & ~3;
+ data = malloc(temp_stride * h);
+ if (data == NULL)
+ return NULL;
+ need_free_data = 1;
+ }
+ }
+
+ pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
+
+ if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
+ && !need_post_conversion
+ && (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
+ if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h,
+ format, type, no_alpha,
+ revert, swap_rb))) {
+ free(data);
+ return NULL;
+ }
+ x = 0;
+ y = 0;
+ fbo_x_off = 0;
+ fbo_y_off = 0;
+ }
+
+ dispatch = glamor_get_dispatch(glamor_priv);
+ dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
+
+ if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
+
+ if (!glamor_priv->yInverted) {
+ assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
+ dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
+ }
+
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) {
+ assert(pbo > 0);
+ dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
+ dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
+ stride * h, NULL, gl_usage);
+ }
+
+ dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type,
+ data);
+
+ if (!glamor_priv->yInverted) {
+ assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
+ dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0);
+ }
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) {
+ bits = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access);
+ dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+ }
+ }
+ else {
+ unsigned int temp_pbo;
+ int yy;
+
+ dispatch = glamor_get_dispatch(glamor_priv);
+ dispatch->glGenBuffers(1, &temp_pbo);
+ dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo);
+ dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
+ stride * h, NULL, GL_STREAM_READ);
+ dispatch->glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h,
+ format, type, 0);
+ read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
+ for (yy = 0; yy < pixmap->drawable.height; yy++)
+ memcpy((char *) data + yy * stride,
+ (char *) read + (h - yy - 1) * stride, stride);
+ dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+ dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+ dispatch->glDeleteBuffers(1, &temp_pbo);
+ }
+
+ dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glamor_put_dispatch(glamor_priv);
+
+ if (need_post_conversion) {
+ /* As OpenGL desktop version never enters here.
+ * Don't need to consider if the pbo is valid.*/
+ bits = glamor_color_convert_to_bits(data, bits,
+ w, h,
+ stride, no_alpha, revert, swap_rb);
+ }
+
+ if (temp_fbo != NULL)
+ glamor_destroy_fbo(temp_fbo);
+ if (need_free_data)
+ free(data);
+
+ 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)
+ int stride, void *bits, int pbo,
+ glamor_access_t access)
{
- GLenum format, type;
- int no_alpha, revert, swap_rb;
- glamor_pixmap_private *pixmap_priv;
- Bool force_clip;
-
- if (glamor_get_tex_format_type_from_pixmap(pixmap,
- &format,
- &type,
- &no_alpha,
- &revert,
- &swap_rb, 0)) {
- 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;
-
- force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
- && !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
-
- if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
-
- 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(&region, &box, 1);
-
- if (!force_clip)
- clipped_regions = glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0, 0, 0);
- else
- clipped_regions = glamor_compute_clipped_regions_ext(pixmap_priv, &region, &n_region,
- pixmap_priv->base.glamor_priv->max_fbo_size,
- pixmap_priv->base.glamor_priv->max_fbo_size, 0, 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(&region);
- 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(&region);
- 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);
+ GLenum format, type;
+ int no_alpha, revert, swap_rb;
+ glamor_pixmap_private *pixmap_priv;
+ Bool force_clip;
+
+ if (glamor_get_tex_format_type_from_pixmap(pixmap,
+ &format,
+ &type,
+ &no_alpha,
+ &revert, &swap_rb, 0)) {
+ 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;
+
+ force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
+ && !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
+
+ if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
+
+ 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(&region, &box, 1);
+
+ if (!force_clip)
+ clipped_regions =
+ glamor_compute_clipped_regions(pixmap_priv, &region, &n_region,
+ 0, 0, 0);
+ else
+ clipped_regions =
+ glamor_compute_clipped_regions_ext(pixmap_priv, &region,
+ &n_region,
+ pixmap_priv->base.
+ glamor_priv->max_fbo_size,
+ pixmap_priv->base.
+ glamor_priv->max_fbo_size, 0,
+ 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(&region);
+ 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(&region);
+ 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.
* The input data is the pixmap's fbo.
@@ -1187,67 +1163,64 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
Bool
glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
{
- glamor_pixmap_private *pixmap_priv =
- glamor_get_pixmap_private(pixmap);
- unsigned int stride;
- void *data = NULL, *dst;
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(pixmap->drawable.pScreen);
- glamor_gl_dispatch *dispatch;
- int pbo = 0;
-
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
- return TRUE;
-
- glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
- "Downloading pixmap %p %dx%d depth%d\n",
- pixmap,
- pixmap->drawable.width,
- pixmap->drawable.height,
- pixmap->drawable.depth);
-
- stride = pixmap->devKind;
-
- if (access == GLAMOR_ACCESS_WO
- || glamor_priv->gl_flavor == GLAMOR_GL_ES2
- || (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)
- || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
- data = malloc(stride * pixmap->drawable.height);
- } else {
- dispatch = glamor_get_dispatch(glamor_priv);
- if (pixmap_priv->base.fbo->pbo == 0)
- dispatch->glGenBuffers(1,
- &pixmap_priv->base.fbo->pbo);
- glamor_put_dispatch(glamor_priv);
- pbo = pixmap_priv->base.fbo->pbo;
- }
-
- if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) {
- stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth);
- pixmap_priv->base.drm_stride = pixmap->devKind;
- pixmap->devKind = stride;
- }
-
- dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0,
- pixmap->drawable.width,
- pixmap->drawable.height,
- pixmap->devKind,
- data, pbo, access);
-
- if (!dst) {
- if (data)
- free(data);
- return FALSE;
- }
-
- if (pbo != 0)
- pixmap_priv->base.fbo->pbo_valid = 1;
-
- pixmap_priv->base.gl_fbo = GLAMOR_FBO_DOWNLOADED;
-
- pixmap->devPrivate.ptr = dst;
-
- return TRUE;
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+ unsigned int stride;
+ void *data = NULL, *dst;
+ glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(pixmap->drawable.pScreen);
+ glamor_gl_dispatch *dispatch;
+ int pbo = 0;
+
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ return TRUE;
+
+ glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
+ "Downloading pixmap %p %dx%d depth%d\n",
+ pixmap,
+ pixmap->drawable.width,
+ pixmap->drawable.height, pixmap->drawable.depth);
+
+ stride = pixmap->devKind;
+
+ if (access == GLAMOR_ACCESS_WO
+ || glamor_priv->gl_flavor == GLAMOR_GL_ES2
+ || (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)
+ || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ data = malloc(stride * pixmap->drawable.height);
+ }
+ else {
+ dispatch = glamor_get_dispatch(glamor_priv);
+ if (pixmap_priv->base.fbo->pbo == 0)
+ dispatch->glGenBuffers(1, &pixmap_priv->base.fbo->pbo);
+ glamor_put_dispatch(glamor_priv);
+ pbo = pixmap_priv->base.fbo->pbo;
+ }
+
+ if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) {
+ stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth);
+ pixmap_priv->base.drm_stride = pixmap->devKind;
+ pixmap->devKind = stride;
+ }
+
+ dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ pixmap->devKind, data, pbo, access);
+
+ if (!dst) {
+ if (data)
+ free(data);
+ return FALSE;
+ }
+
+ if (pbo != 0)
+ pixmap_priv->base.fbo->pbo_valid = 1;
+
+ pixmap_priv->base.gl_fbo = GLAMOR_FBO_DOWNLOADED;
+
+ pixmap->devPrivate.ptr = dst;
+
+ return TRUE;
}
/* fixup a fbo to the exact size as the pixmap. */
@@ -1255,60 +1228,58 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
Bool
glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
{
- glamor_pixmap_fbo *old_fbo;
- glamor_pixmap_fbo *new_fbo = NULL;
- PixmapPtr scratch = NULL;
- glamor_pixmap_private *scratch_priv;
- DrawablePtr drawable;
- GCPtr gc = NULL;
- int ret = FALSE;
-
- drawable = &pixmap_priv->base.pixmap->drawable;
-
- if (!GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))
- return TRUE;
-
- old_fbo = pixmap_priv->base.fbo;
-
- if (!old_fbo)
- return FALSE;
-
- gc = GetScratchGC(drawable->depth, screen);
- if (!gc)
- goto fail;
-
- scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
- drawable->depth,
- GLAMOR_CREATE_PIXMAP_FIXUP);
-
- scratch_priv = glamor_get_pixmap_private(scratch);
-
- if (!scratch_priv->base.fbo)
- goto fail;
-
- ValidateGC(&scratch->drawable, gc);
- glamor_copy_area(drawable,
- &scratch->drawable,
- gc, 0, 0,
- drawable->width, drawable->height,
- 0, 0);
- old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
- new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
- glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo);
- glamor_pixmap_attach_fbo(scratch, old_fbo);
-
- DEBUGF("old %dx%d type %d\n",
- drawable->width, drawable->height, pixmap_priv->type);
- DEBUGF("copy tex %d %dx%d to tex %d %dx%d \n",
- old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex, new_fbo->width, new_fbo->height);
- ret = TRUE;
-fail:
- if (gc)
- FreeScratchGC(gc);
- if (scratch)
- glamor_destroy_pixmap(scratch);
-
- return ret;
+ glamor_pixmap_fbo *old_fbo;
+ glamor_pixmap_fbo *new_fbo = NULL;
+ PixmapPtr scratch = NULL;
+ glamor_pixmap_private *scratch_priv;
+ DrawablePtr drawable;
+ GCPtr gc = NULL;
+ int ret = FALSE;
+
+ drawable = &pixmap_priv->base.pixmap->drawable;
+
+ if (!GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))
+ return TRUE;
+
+ old_fbo = pixmap_priv->base.fbo;
+
+ if (!old_fbo)
+ return FALSE;
+
+ gc = GetScratchGC(drawable->depth, screen);
+ if (!gc)
+ goto fail;
+
+ scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
+ drawable->depth, GLAMOR_CREATE_PIXMAP_FIXUP);
+
+ scratch_priv = glamor_get_pixmap_private(scratch);
+
+ if (!scratch_priv->base.fbo)
+ goto fail;
+
+ ValidateGC(&scratch->drawable, gc);
+ glamor_copy_area(drawable,
+ &scratch->drawable,
+ gc, 0, 0, drawable->width, drawable->height, 0, 0);
+ old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
+ new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
+ glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo);
+ glamor_pixmap_attach_fbo(scratch, old_fbo);
+
+ DEBUGF("old %dx%d type %d\n",
+ drawable->width, drawable->height, pixmap_priv->type);
+ DEBUGF("copy tex %d %dx%d to tex %d %dx%d \n",
+ old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex,
+ new_fbo->width, new_fbo->height);
+ ret = TRUE;
+ fail:
+ if (gc)
+ FreeScratchGC(gc);
+ if (scratch)
+ glamor_destroy_pixmap(scratch);
+
+ return ret;
}
/*
@@ -1328,106 +1299,120 @@ fail:
*
* */
PixmapPtr
-glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, glamor_access_t access)
+glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h,
+ glamor_access_t access)
{
- glamor_screen_private *glamor_priv;
- PixmapPtr sub_pixmap;
- glamor_pixmap_private *sub_pixmap_priv, *pixmap_priv;
- void *data;
- int pbo;
- int flag;
- if (x < 0 || y < 0)
- return NULL;
- w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
- h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
- if (access == GLAMOR_ACCESS_WO) {
- sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
- pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
- return sub_pixmap;
- }
-
- glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
- pixmap_priv = glamor_get_pixmap_private(pixmap);
-
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
- return NULL;
- if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 || pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
- flag = GLAMOR_CREATE_PIXMAP_CPU;
- else
- flag = GLAMOR_CREATE_PIXMAP_MAP;
-
- sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
- pixmap->drawable.depth, flag);
-
- if (sub_pixmap == NULL)
- return NULL;
-
- 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;
-
- if (pixmap_priv->base.is_picture) {
- sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
- sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
- }
-
- if (pbo)
- data = NULL;
- else
- data = sub_pixmap->devPrivate.ptr;
-
- data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, sub_pixmap->devKind,
- data, pbo, access);
- if(data == NULL) {
- fbDestroyPixmap(sub_pixmap);
- return NULL;
- }
- if (pbo) {
- assert(sub_pixmap->devPrivate.ptr == NULL);
- sub_pixmap->devPrivate.ptr = data;
- sub_pixmap_priv->base.fbo->pbo_valid = 1;
- }
+ glamor_screen_private *glamor_priv;
+ PixmapPtr sub_pixmap;
+ glamor_pixmap_private *sub_pixmap_priv, *pixmap_priv;
+ void *data;
+ int pbo;
+ int flag;
+
+ if (x < 0 || y < 0)
+ return NULL;
+ w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
+ h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
+ if (access == GLAMOR_ACCESS_WO) {
+ sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
+ pixmap->drawable.depth,
+ GLAMOR_CREATE_PIXMAP_CPU);
+ return sub_pixmap;
+ }
+
+ glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ return NULL;
+ if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 ||
+ pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
+ flag = GLAMOR_CREATE_PIXMAP_CPU;
+ else
+ flag = GLAMOR_CREATE_PIXMAP_MAP;
+
+ sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
+ pixmap->drawable.depth, flag);
+
+ if (sub_pixmap == NULL)
+ return NULL;
+
+ 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;
+
+ if (pixmap_priv->base.is_picture) {
+ sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
+ sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
+ }
+
+ if (pbo)
+ data = NULL;
+ else
+ data = sub_pixmap->devPrivate.ptr;
+
+ data =
+ glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h,
+ sub_pixmap->devKind, data, pbo,
+ access);
+ if (data == NULL) {
+ fbDestroyPixmap(sub_pixmap);
+ return NULL;
+ }
+ if (pbo) {
+ assert(sub_pixmap->devPrivate.ptr == NULL);
+ sub_pixmap->devPrivate.ptr = data;
+ sub_pixmap_priv->base.fbo->pbo_valid = 1;
+ }
#if 0
- struct pixman_box16 box;
- PixmapPtr new_sub_pixmap;
- int dx, dy;
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = w;
- box.y2 = h;
-
- dx = x;
- dy = y;
-
- new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
- pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU);
- 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);
+ struct pixman_box16 box;
+ PixmapPtr new_sub_pixmap;
+ int dx, dy;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = w;
+ box.y2 = h;
+
+ dx = x;
+ dy = y;
+
+ new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
+ pixmap->drawable.depth,
+ GLAMOR_CREATE_PIXMAP_CPU);
+ 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);
#endif
- return sub_pixmap;
+ return sub_pixmap;
}
void
-glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y, int w, int h, glamor_access_t access)
+glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
+ int w, int h, glamor_access_t access)
{
- void *bits;
- int pbo;
- glamor_pixmap_private *sub_pixmap_priv;
- if (access != GLAMOR_ACCESS_RO) {
- sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
- if (sub_pixmap_priv->base.fbo
- && sub_pixmap_priv->base.fbo->pbo_valid) {
- bits = NULL;
- pbo = sub_pixmap_priv->base.fbo->pbo;
- } else {
- bits = sub_pixmap->devPrivate.ptr;
- pbo = 0;
- }
-
- assert(x >= 0 && y >= 0);
- w = (w > sub_pixmap->drawable.width) ? sub_pixmap->drawable.width : w;
- h = (h > sub_pixmap->drawable.height) ? sub_pixmap->drawable.height : h;
- glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h, sub_pixmap->devKind, bits, pbo);
- }
- glamor_destroy_pixmap(sub_pixmap);
+ void *bits;
+ int pbo;
+ glamor_pixmap_private *sub_pixmap_priv;
+
+ if (access != GLAMOR_ACCESS_RO) {
+ sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
+ if (sub_pixmap_priv->base.fbo && sub_pixmap_priv->base.fbo->pbo_valid) {
+ bits = NULL;
+ pbo = sub_pixmap_priv->base.fbo->pbo;
+ }
+ else {
+ bits = sub_pixmap->devPrivate.ptr;
+ pbo = 0;
+ }
+
+ assert(x >= 0 && y >= 0);
+ w = (w > sub_pixmap->drawable.width) ? sub_pixmap->drawable.width : w;
+ h = (h > sub_pixmap->drawable.height) ? sub_pixmap->drawable.height : h;
+ glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h,
+ sub_pixmap->devKind, bits, pbo);
+ }
+ glamor_destroy_pixmap(sub_pixmap);
}