diff options
author | Zhigang Gong <zhigang.gong@linux.intel.com> | 2012-06-11 01:52:14 +0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2013-12-18 11:23:51 -0800 |
commit | e96ea02010874a3a46f212f42134083bd29fefe3 (patch) | |
tree | 05c747c93c84789796ceced419e9195efaef3e82 /glamor/glamor_render.c | |
parent | ace35e408cd7a79c5215bbd0f14b624d8d949e34 (diff) |
largepixmap: Implement infrastructure for large pixmap.
Added infrastructure for largepixmap, this commit implemented:
1. Create/Destroy large pixmap.
2. Upload/Download large pixmap.
3. Implement basic repeat normal support.
3. tile/fill/copyarea large pixmap get supported.
The most complicated part glamor_composite still not implemented.
Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
Diffstat (limited to 'glamor/glamor_render.c')
-rw-r--r-- | glamor/glamor_render.c | 562 |
1 files changed, 341 insertions, 221 deletions
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 6a584ba6e..48a5bb3ee 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -37,7 +37,12 @@ #ifdef RENDER #include "mipict.h" #include "fbpict.h" - +#if 0 +//#define DEBUGF(str, ...) do {} while(0) +#define DEBUGF(str, ...) ErrorF(str, ##__VA_ARGS__) +//#define DEBUGRegionPrint(x) do {} while (0) +#define DEBUGRegionPrint RegionPrint +#endif struct shader_key { enum shader_source source; enum shader_mask mask; @@ -606,18 +611,20 @@ glamor_set_composite_texture(ScreenPtr screen, int unit, #endif /* XXX may be we can eaxctly check whether we need to touch * the out-of-box area then determine whether we need to fix. - * */ - if (repeat_type != RepeatNone) - repeat_type += RepeatFix; - else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { - if (picture->transform - || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))) + **/ + /*if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE)*/ { + if (repeat_type != RepeatNone) repeat_type += RepeatFix; - } - - if (repeat_type >= RepeatFix) { - glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv); - dispatch->glUniform2fv(wh_location, 1, wh); + else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 + || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { + if (picture->transform + || (GLAMOR_PIXMAP_FBO_NOT_EAXCT_SIZE(pixmap_priv))) + repeat_type += RepeatFix; + } + if (repeat_type >= RepeatFix) { + glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv); + dispatch->glUniform2fv(wh_location, 1, wh); + } } dispatch->glUniform1i(repeat_location, repeat_type); glamor_put_dispatch(glamor_priv); @@ -687,53 +694,44 @@ glamor_composite_with_copy(CARD8 op, INT16 x_source, INT16 y_source, INT16 x_dest, - INT16 y_dest, CARD16 width, CARD16 height) + INT16 y_dest, + RegionPtr region) { - RegionRec region; int ret = FALSE; - if (!source->pDrawable) return FALSE; if (!compatible_formats(op, dest, source)) return FALSE; - if (source->repeat || source->transform) + if (source->repeat || source->transform) { return FALSE; + } x_dest += dest->pDrawable->x; y_dest += dest->pDrawable->y; x_source += source->pDrawable->x; y_source += source->pDrawable->y; - if (!miComputeCompositeRegion(®ion, - source, NULL, dest, - x_source, y_source, - 0, 0, x_dest, y_dest, width, height)) - return TRUE; - if (PICT_FORMAT_A(source->format) == 0) { /* Fallback if we sample outside the source so that we * swizzle the correct clear color for out-of-bounds texels. */ - if (region.extents.x1 + x_source - x_dest < 0) + if (region->extents.x1 + x_source - x_dest < 0) goto cleanup_region; - if (region.extents.x2 + x_source - x_dest > source->pDrawable->width) + if (region->extents.x2 + x_source - x_dest > source->pDrawable->width) goto cleanup_region; - if (region.extents.y1 + y_source - y_dest < 0) + if (region->extents.y1 + y_source - y_dest < 0) goto cleanup_region; - if (region.extents.y2 + y_source - y_dest > source->pDrawable->height) + if (region->extents.y2 + y_source - y_dest > source->pDrawable->height) goto cleanup_region; } - ret = glamor_copy_n_to_n_nf(source->pDrawable, dest->pDrawable, NULL, - REGION_RECTS(®ion), - REGION_NUM_RECTS(®ion), + RegionRects(region), RegionNumRects(region), x_source - x_dest, y_source - y_dest, FALSE, FALSE, 0, NULL); cleanup_region: - REGION_UNINIT(dest->pDrawable->pScreen, ®ion); return ret; } @@ -929,12 +927,44 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src, return FALSE; } +static void +glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv, + int repeat_type, + float *matrix, + float xscale, float yscale, + int x1, int y1, int x2, int y2, + int yInverted, float *texcoords) +{ + if (!matrix && repeat_type == RepeatNone) + glamor_set_normalize_tcoords(priv, xscale, yscale, + x1, y1, + x2, y2, + yInverted, + texcoords); + else if (matrix && repeat_type == RepeatNone) + glamor_set_transformed_normalize_tcoords(priv, matrix, xscale, + yscale, x1, y1, + x2, y2, + yInverted, + texcoords); + else if (!matrix && repeat_type != RepeatNone) + glamor_set_repeat_normalize_tcoords(priv, repeat_type, + xscale, yscale, + x1, y1, + x2, y2, + yInverted, + texcoords); + else if (matrix && repeat_type != RepeatNone) + assert(0); +} + static Bool glamor_composite_with_shader(CARD8 op, PicturePtr source, PicturePtr mask, PicturePtr dest, - int nrect, glamor_composite_rect_t * rects) + int nrect, + glamor_composite_rect_t * rects) { ScreenPtr screen = dest->pDrawable->pScreen; glamor_screen_private *glamor_priv = @@ -959,6 +989,7 @@ glamor_composite_with_shader(CARD8 op, enum glamor_pixmap_status mask_status = GLAMOR_NONE; PictFormatShort saved_source_format = 0; float src_matrix[9], mask_matrix[9]; + float *psrc_matrix = NULL, *pmask_matrix = NULL; GLfloat source_solid_color[4], mask_solid_color[4]; int vert_stride = 4; int nrect_max; @@ -970,20 +1001,23 @@ glamor_composite_with_shader(CARD8 op, goto fail; } memset(&key, 0, sizeof(key)); - if (!source->pDrawable) { - if (source->pSourcePict->type == SourcePictTypeSolidFill) { - key.source = SHADER_SOURCE_SOLID; - glamor_get_rgba_from_pixel(source-> - pSourcePict->solidFill. - color, - &source_solid_color[0], - &source_solid_color[1], - &source_solid_color[2], - &source_solid_color[3], - PICT_a8r8g8b8); - } else { - glamor_fallback("gradient source\n"); - goto fail; + if (!source) { + key.source = SHADER_SOURCE_SOLID; + source_solid_color[0] = 0.0; + source_solid_color[1] = 0.0; + source_solid_color[2] = 0.0; + source_solid_color[3] = 0.0; + } else if (!source->pDrawable) { + if (source->pSourcePict->type == SourcePictTypeSolidFill) { + key.source = SHADER_SOURCE_SOLID; + glamor_get_rgba_from_pixel(source-> + pSourcePict->solidFill. + color, + &source_solid_color[0], + &source_solid_color[1], + &source_solid_color[2], + &source_solid_color[3], + PICT_a8r8g8b8); } } else { key.source = SHADER_SOURCE_TEXTURE_ALPHA; @@ -999,9 +1033,6 @@ glamor_composite_with_shader(CARD8 op, &mask_solid_color[1], &mask_solid_color[2], &mask_solid_color[3], PICT_a8r8g8b8); - } else { - glamor_fallback("gradient mask\n"); - goto fail; } } else { key.mask = SHADER_MASK_TEXTURE_ALPHA; @@ -1029,7 +1060,7 @@ glamor_composite_with_shader(CARD8 op, key.in = SHADER_IN_SOURCE_ONLY; } - if (source->alphaMap) { + if (source && source->alphaMap) { glamor_fallback("source alphaMap\n"); goto fail; } @@ -1044,13 +1075,14 @@ glamor_composite_with_shader(CARD8 op, source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); if (source_pixmap == dest_pixmap) { + /* XXX source and the dest share the same texture. + * Does it need special handle? */ glamor_fallback("source == dest\n"); - goto fail; } - if (!source_pixmap_priv || source_pixmap_priv->base.gl_fbo == 0) { - /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex + if (source_pixmap_priv->base.gl_fbo == 0) { + /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex * equal to zero when the pixmap is screen pixmap. Then we may - * refer the tex zero directly latter in the composition. + * refer the tex zero directly latter in the composition. * It seems that it works fine, but it may have potential problem*/ #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD source_status = GLAMOR_UPLOAD_PENDING; @@ -1068,7 +1100,7 @@ glamor_composite_with_shader(CARD8 op, glamor_fallback("mask == dest\n"); goto fail; } - if (!mask_pixmap_priv || mask_pixmap_priv->base.gl_fbo == 0) { + if (mask_pixmap_priv->base.gl_fbo == 0) { #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD mask_status = GLAMOR_UPLOAD_PENDING; #else @@ -1095,20 +1127,20 @@ glamor_composite_with_shader(CARD8 op, } if (source->format != saved_source_format) { - glamor_picture_format_fixup(source, - source_pixmap_priv); + //glamor_picture_format_fixup(source, + // source_pixmap_priv); } - /* XXX + /* XXX * By default, glamor_upload_picture_to_texture will wire alpha to 1 - * if one picture doesn't have alpha. So we don't do that again in + * if one picture doesn't have alpha. So we don't do that again in * rendering function. But here is a special case, as source and - * mask share the same texture but may have different formats. For + * mask share the same texture but may have different formats. For * example, source doesn't have alpha, but mask has alpha. Then the * texture will have the alpha value for the mask. And will not wire * to 1 for the source. In this case, we have to use different shader * to wire the source's alpha to 1. * - * But this may cause a potential problem if the source's repeat mode + * But this may cause a potential problem if the source's repeat mode * is REPEAT_NONE, and if the source is smaller than the dest, then * for the region not covered by the source may be painted incorrectly. * because we wire the alpha to 1. @@ -1156,13 +1188,15 @@ glamor_composite_with_shader(CARD8 op, * transformed source and mask, if the transform is not int translate. */ if (key.source != SHADER_SOURCE_SOLID && source->transform - && !pixman_transform_is_int_translate(source->transform)) { + && !pixman_transform_is_int_translate(source->transform) + && source_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) { if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv)) goto fail; } if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID && mask->transform - && !pixman_transform_is_int_translate(mask->transform)) { + && !pixman_transform_is_int_translate(mask->transform) + && mask_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) { if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv)) goto fail; } @@ -1217,7 +1251,10 @@ glamor_composite_with_shader(CARD8 op, &source_y_off); pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale); - glamor_picture_get_matrixf(source, src_matrix); + if (source->transform) { + psrc_matrix = src_matrix; + glamor_picture_get_matrixf(source, psrc_matrix); + } vert_stride += 4; } @@ -1226,7 +1263,10 @@ glamor_composite_with_shader(CARD8 op, &mask_x_off, &mask_y_off); pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale); - glamor_picture_get_matrixf(mask, mask_matrix); + if (mask->transform) { + pmask_matrix = mask_matrix; + glamor_picture_get_matrixf(mask, pmask_matrix); + } vert_stride += 4; } @@ -1252,13 +1292,16 @@ glamor_composite_with_shader(CARD8 op, x_dest = rects->x_dst + dest_x_off; y_dest = rects->y_dst + dest_y_off; - x_source = rects->x_src + source_x_off;; + x_source = rects->x_src + source_x_off; y_source = rects->y_src + source_y_off; x_mask = rects->x_mask + mask_x_off; y_mask = rects->y_mask + mask_y_off; width = rects->width; height = rects->height; + DEBUGF("dest(%d,%d) source(%d %d) mask (%d %d), width %d height %d \n", + x_dest, y_dest, x_source, y_source,x_mask,y_mask,width,height); + glamor_set_normalize_vcoords(dest_pixmap_priv, dst_xscale, dst_yscale, x_dest, y_dest, @@ -1266,41 +1309,21 @@ glamor_composite_with_shader(CARD8 op, glamor_priv->yInverted, vertices); - if (key.source != SHADER_SOURCE_SOLID) { - if (source->transform) - glamor_set_transformed_normalize_tcoords - (source_pixmap_priv, src_matrix, src_xscale, - src_yscale, x_source, y_source, - x_source + width, y_source + height, - glamor_priv->yInverted, - source_texcoords); - else - glamor_set_normalize_tcoords - (source_pixmap_priv, src_xscale, src_yscale, - x_source, y_source, - x_source + width, y_source + height, - glamor_priv->yInverted, - source_texcoords); - } + if (key.source != SHADER_SOURCE_SOLID) + glamor_set_normalize_tcoords_generic( + source_pixmap_priv, source->repeatType, psrc_matrix, + src_xscale, src_yscale, x_source, y_source, + x_source + width, y_source + height, + glamor_priv->yInverted, source_texcoords); if (key.mask != SHADER_MASK_NONE - && key.mask != SHADER_MASK_SOLID) { - if (mask->transform) - glamor_set_transformed_normalize_tcoords - (mask_pixmap_priv, mask_matrix, - mask_xscale, - mask_yscale, x_mask, y_mask, - x_mask + width, y_mask + height, - glamor_priv->yInverted, - mask_texcoords); - else - glamor_set_normalize_tcoords - (mask_pixmap_priv, mask_xscale, - mask_yscale, x_mask, y_mask, - x_mask + width, y_mask + height, - glamor_priv->yInverted, - mask_texcoords); - } + && key.mask != SHADER_MASK_SOLID) + glamor_set_normalize_tcoords_generic( + mask_pixmap_priv, mask->repeatType, pmask_matrix, + mask_xscale, mask_yscale, x_mask, y_mask, + x_mask + width, y_mask + height, + glamor_priv->yInverted, mask_texcoords); + glamor_emit_composite_rect(screen, source_texcoords, mask_texcoords, @@ -1323,6 +1346,7 @@ glamor_composite_with_shader(CARD8 op, dispatch->glActiveTexture(GL_TEXTURE1); dispatch->glDisable(GL_TEXTURE_2D); #endif + DEBUGF("finish rendering.\n"); dispatch->glUseProgram(0); if (saved_source_format) source->format = saved_source_format; @@ -1398,17 +1422,18 @@ glamor_convert_gradient_picture(ScreenPtr screen, return dst; } -static Bool -_glamor_composite(CARD8 op, - PicturePtr source, - PicturePtr mask, - PicturePtr dest, - INT16 x_source, - INT16 y_source, - INT16 x_mask, - INT16 y_mask, - INT16 x_dest, INT16 y_dest, - CARD16 width, CARD16 height, Bool fallback) +Bool +glamor_composite_clipped_region(CARD8 op, + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + RegionPtr region, + int x_source, + int y_source, + int x_mask, + int y_mask, + int x_dest, + int y_dest) { ScreenPtr screen = dest->pDrawable->pScreen; glamor_pixmap_private *dest_pixmap_priv; @@ -1419,80 +1444,63 @@ _glamor_composite(CARD8 op, PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; PicturePtr temp_src = source, temp_mask = mask; int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; + + BoxPtr extent; glamor_composite_rect_t rect[10]; glamor_composite_rect_t *prect = rect; int prect_size = ARRAY_SIZE(rect); - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - Bool ret = TRUE; - RegionRec region; + int ok = FALSE; + int i; + int width; + int height; BoxPtr box; - int nbox, i, ok = FALSE; - PixmapPtr sub_dest_pixmap = NULL; - PixmapPtr sub_source_pixmap = NULL; - PixmapPtr sub_mask_pixmap = NULL; - int dest_x_off, dest_y_off, saved_dest_x = 0, saved_dest_y = 0; - int source_x_off, source_y_off, saved_source_x = 0, saved_source_y = 0; - int mask_x_off, mask_y_off, saved_mask_x = 0, saved_mask_y = 0; - DrawablePtr saved_dest_drawable = NULL; - DrawablePtr saved_source_drawable = NULL; - DrawablePtr saved_mask_drawable = NULL; + int nbox; + extent = RegionExtents(region); + box = RegionRects(region); + nbox = RegionNumRects(region); + width = extent->x2 - extent->x1; + height = extent->y2 - extent->y1; x_temp_src = x_source; y_temp_src = y_source; x_temp_mask = x_mask; y_temp_mask = y_mask; - - DEBUGF("Composite Src: (%d, %d)\n" - " Mask: (%d, %d)\n" - " to dst: (%d, %d), size: %d X %d \n", - x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); + DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n", + x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); + DEBUGF("dest pixmap %p ", dest_pixmap); dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); /* Currently. Always fallback to cpu if destination is in CPU memory. */ - if (source->pDrawable) { + if (source && source->pDrawable) { source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); - if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY) - goto fail; } if (mask && mask->pDrawable) { mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); - if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY) - goto fail; - } - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { - goto fail; } - if (op >= ARRAY_SIZE(composite_op_info)) - goto fail; - - if ((!source->pDrawable + /* XXX is it possible source mask have non-zero drawable.x/y? */ + if (source + && ((!source->pDrawable && (source->pSourcePict->type != SourcePictTypeSolidFill)) || (source->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv) - && - ((width * height * 4 < - (source_pixmap->drawable.width * - source_pixmap->drawable.height)) - || - !(glamor_check_fbo_size - (glamor_priv, source_pixmap->drawable.width, - source_pixmap->drawable.height))))) { + && (source_pixmap->drawable.width != width + || source_pixmap->drawable.height != height)))) { temp_src = glamor_convert_gradient_picture(screen, source, - x_source, y_source, + extent->x1 + x_source - x_dest, + extent->y1 + y_source - y_dest, width, height); if (!temp_src) { temp_src = source; - goto fail; + goto out; } - x_temp_src = y_temp_src = 0; + x_temp_src = - extent->x1 + x_dest; + y_temp_src = - extent->y1 + y_dest; } if (mask @@ -1500,26 +1508,22 @@ _glamor_composite(CARD8 op, ((!mask->pDrawable && (mask->pSourcePict->type != SourcePictTypeSolidFill)) || (mask->pDrawable - && (!GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv)) - && - ((width * height * 4 < - (mask_pixmap->drawable.width * - mask_pixmap->drawable.height)) - || - !(glamor_check_fbo_size - (glamor_priv, mask_pixmap->drawable.width, - mask_pixmap->drawable.height)))))) { + && !GLAMOR_PIXMAP_PRIV_HAS_FBO(mask_pixmap_priv) + && (mask_pixmap->drawable.width != width + || mask_pixmap->drawable.height != height)))) { /* XXX if mask->pDrawable is the same as source->pDrawable, we have an opportunity * to do reduce one convertion. */ temp_mask = glamor_convert_gradient_picture(screen, mask, - x_mask, y_mask, + extent->x1 + x_mask - x_dest, + extent->y1 + y_mask - y_dest, width, height); if (!temp_mask) { temp_mask = mask; - goto fail; + goto out; } - x_temp_mask = y_temp_mask = 0; + x_temp_mask = - extent->x1 + x_dest; + y_temp_mask = - extent->y1 + y_dest; } /* Do two-pass PictOpOver componentAlpha, until we enable * dual source color blending. @@ -1527,43 +1531,38 @@ _glamor_composite(CARD8 op, if (mask && mask->componentAlpha) { if (op == PictOpOver) { - glamor_composite(PictOpOutReverse, - temp_src, temp_mask, dest, - x_temp_src, y_temp_src, - x_temp_mask, y_temp_mask, - x_dest, y_dest, width, height); - glamor_composite(PictOpAdd, - temp_src, temp_mask, dest, - x_temp_src, y_temp_src, - x_temp_mask, y_temp_mask, - x_dest, y_dest, width, height); - goto done; - - } else if (op == PictOpAtop - || op == PictOpAtopReverse - || op == PictOpXor - || op >= PictOpSaturate) { - glamor_fallback - ("glamor_composite(): component alpha op %x\n", op); - goto fail; + glamor_composite_clipped_region(PictOpOutReverse, + temp_src, temp_mask, dest, + region, + x_temp_src, y_temp_src, + x_temp_mask, y_temp_mask, + x_dest, y_dest); + + glamor_composite_clipped_region(PictOpAdd, + temp_src, temp_mask, dest, + region, + x_temp_src, y_temp_src, + x_temp_mask, y_temp_mask, + x_dest, y_dest); + ok = TRUE; + goto out; } } - if (!mask) { + if (!mask && temp_src) { if (glamor_composite_with_copy(op, temp_src, dest, x_temp_src, y_temp_src, - x_dest, y_dest, width, - height)) - goto done; + x_dest, y_dest, region)) { + ok = TRUE; + goto out; + } } - /*XXXXX, maybe we can make a copy of dest pixmap.*/ - if (source_pixmap == dest_pixmap) - goto full_fallback; + /*XXXXX, self copy?*/ x_dest += dest->pDrawable->x; y_dest += dest->pDrawable->y; - if (temp_src->pDrawable) { + if (temp_src && temp_src->pDrawable) { x_temp_src += temp_src->pDrawable->x; y_temp_src += temp_src->pDrawable->y; } @@ -1571,16 +1570,6 @@ _glamor_composite(CARD8 op, x_temp_mask += temp_mask->pDrawable->x; y_temp_mask += temp_mask->pDrawable->y; } - if (!miComputeCompositeRegion(®ion, - temp_src, temp_mask, dest, - x_temp_src, y_temp_src, - x_temp_mask, y_temp_mask, - x_dest, y_dest, width, - height)) - goto done; - - box = REGION_RECTS(®ion); - nbox = REGION_NUM_RECTS(®ion); if (nbox > ARRAY_SIZE(rect)) { prect = calloc(nbox, sizeof(*prect)); @@ -1612,15 +1601,153 @@ _glamor_composite(CARD8 op, box += box_cnt; } + if (prect != rect) + free(prect); +out: + if (temp_src != source) + FreePicture(temp_src, 0); + if (temp_mask != mask) + FreePicture(temp_mask, 0); + + return ok; +} + +static Bool +_glamor_composite(CARD8 op, + PicturePtr source, + PicturePtr mask, + PicturePtr dest, + INT16 x_source, + INT16 y_source, + INT16 x_mask, + INT16 y_mask, + INT16 x_dest, INT16 y_dest, + CARD16 width, CARD16 height, Bool fallback) +{ + ScreenPtr screen = dest->pDrawable->pScreen; + glamor_pixmap_private *dest_pixmap_priv; + glamor_pixmap_private *source_pixmap_priv = + NULL, *mask_pixmap_priv = NULL; + PixmapPtr dest_pixmap = + glamor_get_drawable_pixmap(dest->pDrawable); + PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; + glamor_screen_private *glamor_priv = + glamor_get_screen_private(screen); + Bool ret = TRUE; + RegionRec region; + BoxPtr box, extent; + int nbox, ok = FALSE; + PixmapPtr sub_dest_pixmap = NULL; + PixmapPtr sub_source_pixmap = NULL; + PixmapPtr sub_mask_pixmap = NULL; + int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y; + int source_x_off, source_y_off, saved_source_x, saved_source_y; + int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y; + DrawablePtr saved_dest_drawable; + DrawablePtr saved_source_drawable; + DrawablePtr saved_mask_drawable; + int force_clip = 0; + + dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); + + if (source->pDrawable) { + source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); + source_pixmap_priv = glamor_get_pixmap_private(source_pixmap); + if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY) + goto fail; + } + + if (mask && mask->pDrawable) { + mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); + mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); + if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY) + goto fail; + } + + DEBUGF("source pixmap %p (%d %d) mask(%d %d) dest(%d %d) width %d height %d \n", + source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { + goto fail; + } + + if (op >= ARRAY_SIZE(composite_op_info)) + goto fail; + + if (mask && mask->componentAlpha) { + if (op == PictOpAtop + || op == PictOpAtopReverse + || op == PictOpXor + || op >= PictOpSaturate) { + glamor_fallback + ("glamor_composite(): component alpha op %x\n", op); + goto fail; + } + } + + if (!miComputeCompositeRegion(®ion, + source, mask, dest, + x_source + (source_pixmap ? source->pDrawable->x : 0), + y_source + (source_pixmap ? source->pDrawable->y : 0), + x_mask + (mask_pixmap ? mask->pDrawable->x : 0), + y_mask + (mask_pixmap ? mask->pDrawable->y : 0), + x_dest + dest->pDrawable->x, + y_dest + dest->pDrawable->y, + width, + height)) { + ret = TRUE; + goto done; + } + + box = REGION_RECTS(®ion); + nbox = REGION_NUM_RECTS(®ion); + DEBUGF("first clipped when compositing.\n"); + DEBUGRegionPrint(®ion); + extent = RegionExtents(®ion); + if (nbox == 0) { + ret = TRUE; + goto done; + } + /* If destination is not a large pixmap, but the region is larger + * than texture size limitation, and source or mask is memory pixmap, + * then there may be need to load a large memory pixmap to a + * texture, and this is not permitted. Then we force to clip the + * destination and make sure latter will not upload a large memory + * pixmap. */ + if (!glamor_check_fbo_size(glamor_priv, + extent->x2 - extent->x1, extent->y2 - extent->y1) + && (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) + && ((source_pixmap_priv + && source_pixmap_priv->type == GLAMOR_MEMORY) + || (mask_pixmap_priv + && mask_pixmap_priv->type == GLAMOR_MEMORY) + || (!source_pixmap_priv + && (source->pSourcePict->type != SourcePictTypeSolidFill)) + || (!mask_pixmap_priv && mask + && mask->pSourcePict->type != SourcePictTypeSolidFill))) + force_clip = 1; + + if (force_clip || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE + || (source_pixmap_priv + && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) + || (mask_pixmap_priv + && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)) + goto fail; + else + ok = glamor_composite_clipped_region(op, source, + mask, dest, ®ion, + x_source, y_source, + x_mask, y_mask, + x_dest, y_dest); + REGION_UNINIT(dest->pDrawable->pScreen, ®ion); if (ok) goto done; - fail: if (!fallback && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable) - && (!source_pixmap + && (!source_pixmap || glamor_ddx_fallback_check_pixmap(&source_pixmap->drawable)) && (!mask_pixmap || glamor_ddx_fallback_check_pixmap(&mask_pixmap->drawable))) { @@ -1662,13 +1789,11 @@ fail: x_ ##p = 0; \ y_ ##p = 0; \ } } while(0) - GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW); - if (source->pDrawable) + if (source->pDrawable && !source->transform) GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO); - if (mask && mask->pDrawable) + if (mask && mask->pDrawable && !mask->transform) GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO); - full_fallback: if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) { if (source_pixmap == dest_pixmap || glamor_prepare_access_picture @@ -1711,12 +1836,6 @@ full_fallback: PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO); PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW); done: - if (temp_src != source) - FreePicture(temp_src, 0); - if (temp_mask != mask) - FreePicture(temp_mask, 0); - if (prect != rect) - free(prect); return ret; } @@ -1754,9 +1873,6 @@ glamor_composite_nf(CARD8 op, FALSE); } - - - /** * Creates an appropriate picture to upload our alpha mask into (which * we calculated in system memory) @@ -1797,7 +1913,7 @@ glamor_create_mask_picture(ScreenPtr screen, * glamor_trapezoids is a copy of miTrapezoids that does all the trapezoid * accumulation in system memory. */ -static Bool +static Bool _glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, @@ -1885,7 +2001,7 @@ glamor_trapezoids(CARD8 op, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid * traps) { - _glamor_trapezoids(op, src, dst, mask_format, x_src, + _glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, ntrap, traps, TRUE); } @@ -1895,7 +2011,7 @@ glamor_trapezoids_nf(CARD8 op, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid * traps) { - return _glamor_trapezoids(op, src, dst, mask_format, x_src, + return _glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, ntrap, traps, FALSE); } @@ -1912,8 +2028,12 @@ glamor_composite_glyph_rects(CARD8 op, ValidatePicture(src); ValidatePicture(dst); - if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects)) - return; + if (!(glamor_is_large_picture(src) + || (mask && glamor_is_large_picture(mask)) + || glamor_is_large_picture(dst))) { + if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects)) + return; + } n = nrect; r = rects; |