xserver-multidpi/glamor/glamor_picture.c
Eric Anholt 2cc7a0815e glamor: Drop the GLES2 REVERT_UPLOADING_2_10_10_10 paths.
These just smash your 2_10_10_10 data into 8888, despite what the
comments said.  That's not valid rendering, so just ditch this path
and fall back to software.  One might also note in the code being
removed here that the REVERT_UPLOADING_10_10_10_2 path wasn't even
connected.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
2016-03-10 11:12:43 -05:00

708 lines
24 KiB
C

/*
* Copyright © 2009 Intel Corporation
* Copyright © 1998 Keith Packard
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Authors:
* Zhigang Gong <zhigang.gong@gmail.com>
*
*/
#include <stdlib.h>
#include "glamor_priv.h"
#include "mipict.h"
/*
* Map picture's format to the correct gl texture format and type.
* no_alpha is used to indicate whehter we need to wire alpha to 1.
*
* Although opengl support A1/GL_BITMAP, we still don't use it
* here, it seems that mesa has bugs when uploading a A1 bitmap.
*
* Return 0 if find a matched texture type. Otherwise return -1.
**/
static Bool
glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
PictFormatShort format,
GLenum *tex_format,
GLenum *tex_type,
int *no_alpha,
int *revert,
int *swap_rb)
{
glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
Bool is_little_endian = IMAGE_BYTE_ORDER == LSBFirst;
*no_alpha = 0;
*revert = REVERT_NONE;
*swap_rb = SWAP_NONE_UPLOADING;
switch (format) {
case PICT_a1:
*tex_format = glamor_priv->one_channel_format;
*tex_type = GL_UNSIGNED_BYTE;
*revert = REVERT_UPLOADING_A1;
break;
case PICT_b8g8r8x8:
*no_alpha = 1;
case PICT_b8g8r8a8:
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_INT_8_8_8_8;
} else {
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_BYTE;
*swap_rb = SWAP_UPLOADING;
*revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
}
break;
case PICT_x8r8g8b8:
*no_alpha = 1;
case PICT_a8r8g8b8:
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
} else {
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_BYTE;
*swap_rb = SWAP_UPLOADING;
*revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
break;
}
break;
case PICT_x8b8g8r8:
*no_alpha = 1;
case PICT_a8b8g8r8:
*tex_format = GL_RGBA;
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
*tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
} else {
*tex_type = GL_UNSIGNED_BYTE;
*revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
}
break;
case PICT_x2r10g10b10:
*no_alpha = 1;
case PICT_a2r10g10b10:
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
} else {
return FALSE;
}
break;
case PICT_x2b10g10r10:
*no_alpha = 1;
case PICT_a2b10g10r10:
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
} else {
return FALSE;
}
break;
case PICT_r5g6b5:
*tex_format = GL_RGB;
*tex_type = GL_UNSIGNED_SHORT_5_6_5;
if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP)
*revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
break;
case PICT_b5g6r5:
*tex_format = GL_RGB;
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
*tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
} else {
*tex_type = GL_UNSIGNED_SHORT_5_6_5;
if (is_little_endian)
*swap_rb = SWAP_UPLOADING;
*revert = is_little_endian ? REVERT_NONE : REVERT_NORMAL;
}
break;
case PICT_x1b5g5r5:
*no_alpha = 1;
case PICT_a1b5g5r5:
*tex_format = GL_RGBA;
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
} else {
*tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
if (is_little_endian)
*revert = REVERT_UPLOADING_1_5_5_5;
else
*revert = REVERT_NONE;
}
break;
case PICT_x1r5g5b5:
*no_alpha = 1;
case PICT_a1r5g5b5:
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
} else {
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
if (is_little_endian)
*revert = REVERT_UPLOADING_1_5_5_5;
else
*revert = REVERT_NONE;
*swap_rb = SWAP_UPLOADING;
}
break;
case PICT_a8:
*tex_format = glamor_priv->one_channel_format;
*tex_type = GL_UNSIGNED_BYTE;
break;
case PICT_x4r4g4b4:
*no_alpha = 1;
case PICT_a4r4g4b4:
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
*tex_format = GL_BGRA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
} else {
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
*revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
*swap_rb = SWAP_UPLOADING;
}
break;
case PICT_x4b4g4r4:
*no_alpha = 1;
case PICT_a4b4g4r4:
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
} else {
*tex_format = GL_RGBA;
*tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
*revert = is_little_endian ? REVERT_NORMAL : REVERT_NONE;
}
break;
default:
return FALSE;
}
return TRUE;
}
static void *
_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
int stride)
{
PictFormatShort dst_format = PICT_a8, src_format = PICT_a1;
pixman_image_t *dst_image;
pixman_image_t *src_image;
int src_stride = PixmapBytePad(w, 1);
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) : \
(((dst_bits) > (src_bits)) ? \
(((d) << ((dst_bits) - (src_bits))) \
+ (( 1 << ((dst_bits) - (src_bits))) >> 1)) \
: ((d) >> ((src_bits) - (dst_bits)))))
#define GLAMOR_DO_CONVERT(src, dst, no_alpha, swap, \
a_shift_src, a_bits_src, \
b_shift_src, b_bits_src, \
g_shift_src, g_bits_src, \
r_shift_src, r_bits_src, \
a_shift, a_bits, \
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);\
b_mask_src = (((1 << (b_bits_src)) - 1) << b_shift_src);\
g_mask_src = (((1 << (g_bits_src)) - 1) << g_shift_src);\
r_mask_src = (((1 << (r_bits_src)) - 1) << r_shift_src);\
if (no_alpha) \
a = (a_mask_src) >> (a_shift_src); \
else \
a = ((src) & (a_mask_src)) >> (a_shift_src); \
b = ((src) & (b_mask_src)) >> (b_shift_src); \
g = ((src) & (g_mask_src)) >> (g_shift_src); \
r = ((src) & (r_mask_src)) >> (r_shift_src); \
a = ADJUST_BITS(a, a_bits_src, a_bits); \
b = ADJUST_BITS(b, b_bits_src, b_bits); \
g = ADJUST_BITS(g, g_bits_src, g_bits); \
r = ADJUST_BITS(r, r_bits_src, r_bits); \
if (swap == 0) \
(*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_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
int stride, int no_alpha, int swap_rb)
{
int x, y;
unsigned short *words, *saved_words, *source_words;
int swap = 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];
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;
}
/*
* This function is to convert an unsupported color format to/from a
* supported GL format.
* Here are the current scenarios:
*
* @no_alpha:
* If it is set, then we need to wire the alpha value to 1.
* @revert:
REVERT_UPLOADING_A1 : convert an A1 buffer to an Alpha8 buffer
REVERT_UPLOADING_1_5_5_5 : convert X1R5G5B5 to B5G5R5X1
@swap_rb: if we have the swap_rb set, then we need to swap the R and B's position.
*
*/
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)
{
if (revert == REVERT_UPLOADING_A1) {
return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride);
}
else if (revert == REVERT_UPLOADING_1_5_5_5) {
return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride,
no_alpha, swap_rb);
}
else
ErrorF("convert a non-supported mode %x.\n", revert);
return NULL;
}
/**
* Upload pixmap to a specified texture.
* This texture may not be the one attached to it.
**/
static Bool
__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)
{
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
int non_sub = 0;
unsigned int iformat = 0;
glamor_make_current(glamor_priv);
if (*tex == 0) {
glGenTextures(1, tex);
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
iformat = gl_iformat_for_pixmap(pixmap);
else
iformat = format;
non_sub = 1;
assert(x == 0 && y == 0);
}
glBindTexture(GL_TEXTURE_2D, *tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
assert(pbo || bits != 0);
if (bits == NULL) {
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
glamor_priv->suppress_gl_out_of_memory_logging = true;
if (non_sub)
glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
else
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits);
glamor_priv->suppress_gl_out_of_memory_logging = false;
if (glGetError() == GL_OUT_OF_MEMORY) {
if (non_sub) {
glDeleteTextures(1, tex);
*tex = 0;
}
return FALSE;
}
if (bits == NULL)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
return TRUE;
}
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)
{
ScreenPtr screen = pixmap->drawable.pScreen;
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
float dst_xscale, dst_yscale;
GLuint tex = 0;
int need_free_bits = 0;
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 = xallocarray(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) {
free(converted_bits);
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
#ifdef WALKAROUND_LARGE_TEXTURE_MAP
&& glamor_pixmap_priv_is_small(pixmap_priv)
#endif
) {
int fbo_x_off, fbo_y_off;
assert(pixmap_priv->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->fbo->width);
assert(y + fbo_y_off + h <= pixmap_priv->fbo->height);
if (!__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
format, type,
x + fbo_x_off, y + fbo_y_off,
w, h,
bits, pbo)) {
if (need_free_bits)
free(bits);
return FALSE;
}
} else {
static const float texcoords_inv[8] = { 0, 0,
1, 0,
1, 1,
0, 1
};
GLfloat *v;
char *vbo_offset;
v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat), &vbo_offset);
pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale);
glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
dst_yscale,
x, y,
x + w, y + h,
v);
/* Slow path, we need to flip y or wire alpha to 1. */
glamor_make_current(glamor_priv);
if (!__glamor_upload_pixmap_to_texture(pixmap, &tex,
format, type, 0, 0, w, h, bits,
pbo)) {
if (need_free_bits)
free(bits);
return FALSE;
}
memcpy(&v[8], texcoords_inv, 8 * sizeof(GLfloat));
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
GL_FALSE, 2 * sizeof(float), vbo_offset);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
GL_FALSE, 2 * sizeof(float), vbo_offset + 8 * sizeof(GLfloat));
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glamor_put_vbo_space(screen);
glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
glamor_set_alu(screen, GXcopy);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glDeleteTextures(1, &tex);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
if (need_free_bits)
free(bits);
return TRUE;
}
/*
* Prepare to upload a pixmap to texture memory.
* no_alpha equals 1 means the format needs to wire alpha to 1.
*/
static int
glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
int revert, int swap_rb)
{
int flag = 0;
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
GLenum iformat;
if (!(no_alpha || (revert == REVERT_NORMAL)
|| (swap_rb != SWAP_NONE_UPLOADING))) {
/* We don't need a fbo, a simple texture uploading should work. */
flag = GLAMOR_CREATE_FBO_NO_FBO;
}
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
iformat = gl_iformat_for_pixmap(pixmap);
else
iformat = format;
if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
return -1;
return 0;
}
/*
* upload sub region to a large region.
* */
static void
glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits,
int src_stride, int bpp, int x, int y, int w, int h)
{
int j;
int byte_per_pixel;
byte_per_pixel = bpp / 8;
src_bits += y * src_stride + (x * byte_per_pixel);
for (j = y; j < y + h; j++) {
memcpy(dst_bits, src_bits, w * byte_per_pixel);
src_bits += src_stride;
dst_bits += dst_stride;
}
}
/**
* Uploads a picture based on a GLAMOR_MEMORY pixmap to a texture in a
* temporary FBO.
*/
Bool
glamor_upload_picture_to_texture(PicturePtr picture)
{
PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
void *bits = pixmap->devPrivate.ptr;
int stride = pixmap->devKind;
ScreenPtr screen = pixmap->drawable.pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
GLenum format, type;
int no_alpha, revert, swap_rb;
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
Bool force_clip;
assert(glamor_pixmap_is_memory(pixmap));
assert(!pixmap_priv->fbo);
if (!glamor_get_tex_format_type_from_pictformat(screen,
picture->format,
&format,
&type,
&no_alpha,
&revert, &swap_rb)) {
glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
return FALSE;
}
if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
return FALSE;
force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP;
if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) {
RegionRec region;
BoxRec box;
int n_region;
glamor_pixmap_clipped_regions *clipped_regions;
void *sub_bits;
int i, j;
sub_bits = xallocarray(pixmap->drawable.height, stride);
if (sub_bits == NULL)
return FALSE;
box.x1 = 0;
box.y1 = 0;
box.x2 = pixmap->drawable.width;
box.y2 = pixmap->drawable.height;
RegionInitBoxes(&region, &box, 1);
if (!force_clip)
clipped_regions =
glamor_compute_clipped_regions(pixmap, &region, &n_region,
0, 0, 0);
else
clipped_regions =
glamor_compute_clipped_regions_ext(pixmap, &region,
&n_region,
pixmap_priv->block_w,
pixmap_priv->block_h,
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;
glamor_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 == 0 && temp_stride == stride) {
temp_bits = (char *) bits + boxes[j].y1 * stride;
}
else {
temp_bits = sub_bits;
glamor_put_bits(temp_bits, temp_stride, bits, stride,
pixmap->drawable.bitsPerPixel,
boxes[j].x1, boxes[j].y1,
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, boxes[j].y1,
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,
0) == 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,
0, 0,
pixmap->drawable.width,
pixmap->drawable.height,
stride, bits,
0);
}