pixman-general.c revision 1b18d63a
1/* 2 * Copyright © 2009 Red Hat, Inc. 3 * Copyright © 2000 SuSE, Inc. 4 * Copyright © 2007 Red Hat, Inc. 5 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. 6 * 2005 Lars Knoll & Zack Rusin, Trolltech 7 * 2008 Aaron Plattner, NVIDIA Corporation 8 * 9 * Permission to use, copy, modify, distribute, and sell this software and its 10 * documentation for any purpose is hereby granted without fee, provided that 11 * the above copyright notice appear in all copies and that both that 12 * copyright notice and this permission notice appear in supporting 13 * documentation, and that the name of Red Hat not be used in advertising or 14 * publicity pertaining to distribution of the software without specific, 15 * written prior permission. Red Hat makes no representations about the 16 * suitability of this software for any purpose. It is provided "as is" 17 * without express or implied warranty. 18 * 19 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 20 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 23 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 24 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 25 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 26 * SOFTWARE. 27 */ 28#ifdef HAVE_CONFIG_H 29#include <config.h> 30#endif 31#include <stdlib.h> 32#include <string.h> 33#include <math.h> 34#include <limits.h> 35#include <stdio.h> 36#include <stdlib.h> 37#include <string.h> 38#include "pixman-private.h" 39#include "pixman-combine32.h" 40#include "pixman-private.h" 41 42#define SCANLINE_BUFFER_LENGTH 8192 43 44static void 45general_composite_rect (pixman_implementation_t *imp, 46 pixman_op_t op, 47 pixman_image_t * src, 48 pixman_image_t * mask, 49 pixman_image_t * dest, 50 int32_t src_x, 51 int32_t src_y, 52 int32_t mask_x, 53 int32_t mask_y, 54 int32_t dest_x, 55 int32_t dest_y, 56 int32_t width, 57 int32_t height) 58{ 59 uint8_t stack_scanline_buffer[SCANLINE_BUFFER_LENGTH * 3]; 60 uint8_t *scanline_buffer = stack_scanline_buffer; 61 uint8_t *src_buffer, *mask_buffer, *dest_buffer; 62 fetch_scanline_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL; 63 pixman_combine_32_func_t compose; 64 store_scanline_t store; 65 source_image_class_t src_class, mask_class; 66 pixman_bool_t component_alpha; 67 uint32_t *bits; 68 int32_t stride; 69 int narrow, Bpp; 70 int i; 71 72 narrow = 73 (src->common.flags & FAST_PATH_NARROW_FORMAT) && 74 (!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) && 75 (dest->common.flags & FAST_PATH_NARROW_FORMAT); 76 Bpp = narrow ? 4 : 8; 77 78 if (width * Bpp > SCANLINE_BUFFER_LENGTH) 79 { 80 scanline_buffer = pixman_malloc_abc (width, 3, Bpp); 81 82 if (!scanline_buffer) 83 return; 84 } 85 86 src_buffer = scanline_buffer; 87 mask_buffer = src_buffer + width * Bpp; 88 dest_buffer = mask_buffer + width * Bpp; 89 90 src_class = _pixman_image_classify (src, 91 src_x, src_y, 92 width, height); 93 94 mask_class = SOURCE_IMAGE_CLASS_UNKNOWN; 95 96 if (mask) 97 { 98 mask_class = _pixman_image_classify (mask, 99 src_x, src_y, 100 width, height); 101 } 102 103 if (op == PIXMAN_OP_CLEAR) 104 fetch_src = NULL; 105 else if (narrow) 106 fetch_src = _pixman_image_get_scanline_32; 107 else 108 fetch_src = _pixman_image_get_scanline_64; 109 110 if (!mask || op == PIXMAN_OP_CLEAR) 111 fetch_mask = NULL; 112 else if (narrow) 113 fetch_mask = _pixman_image_get_scanline_32; 114 else 115 fetch_mask = _pixman_image_get_scanline_64; 116 117 if (op == PIXMAN_OP_CLEAR || op == PIXMAN_OP_SRC) 118 fetch_dest = NULL; 119 else if (narrow) 120 fetch_dest = _pixman_image_get_scanline_32; 121 else 122 fetch_dest = _pixman_image_get_scanline_64; 123 124 if (narrow) 125 store = _pixman_image_store_scanline_32; 126 else 127 store = _pixman_image_store_scanline_64; 128 129 /* Skip the store step and composite directly into the 130 * destination if the output format of the compose func matches 131 * the destination format. 132 * 133 * If the destination format is a8r8g8b8 then we can always do 134 * this. If it is x8r8g8b8, then we can only do it if the 135 * operator doesn't make use of destination alpha. 136 */ 137 if ((dest->bits.format == PIXMAN_a8r8g8b8) || 138 (dest->bits.format == PIXMAN_x8r8g8b8 && 139 (op == PIXMAN_OP_OVER || 140 op == PIXMAN_OP_ADD || 141 op == PIXMAN_OP_SRC || 142 op == PIXMAN_OP_CLEAR || 143 op == PIXMAN_OP_IN_REVERSE || 144 op == PIXMAN_OP_OUT_REVERSE || 145 op == PIXMAN_OP_DST))) 146 { 147 if (narrow && 148 !dest->common.alpha_map && 149 !dest->bits.write_func) 150 { 151 store = NULL; 152 } 153 } 154 155 if (!store) 156 { 157 bits = dest->bits.bits; 158 stride = dest->bits.rowstride; 159 } 160 else 161 { 162 bits = NULL; 163 stride = 0; 164 } 165 166 component_alpha = 167 fetch_src && 168 fetch_mask && 169 mask && 170 mask->common.type == BITS && 171 mask->common.component_alpha && 172 PIXMAN_FORMAT_RGB (mask->bits.format); 173 174 if (narrow) 175 { 176 if (component_alpha) 177 compose = _pixman_implementation_combine_32_ca; 178 else 179 compose = _pixman_implementation_combine_32; 180 } 181 else 182 { 183 if (component_alpha) 184 compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca; 185 else 186 compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64; 187 } 188 189 if (!compose) 190 return; 191 192 if (!fetch_mask) 193 mask_buffer = NULL; 194 195 for (i = 0; i < height; ++i) 196 { 197 /* fill first half of scanline with source */ 198 if (fetch_src) 199 { 200 if (fetch_mask) 201 { 202 /* fetch mask before source so that fetching of 203 source can be optimized */ 204 fetch_mask (mask, mask_x, mask_y + i, 205 width, (void *)mask_buffer, 0); 206 207 if (mask_class == SOURCE_IMAGE_CLASS_HORIZONTAL) 208 fetch_mask = NULL; 209 } 210 211 if (src_class == SOURCE_IMAGE_CLASS_HORIZONTAL) 212 { 213 fetch_src (src, src_x, src_y + i, 214 width, (void *)src_buffer, 0); 215 fetch_src = NULL; 216 } 217 else 218 { 219 fetch_src (src, src_x, src_y + i, 220 width, (void *)src_buffer, (void *)mask_buffer); 221 } 222 } 223 else if (fetch_mask) 224 { 225 fetch_mask (mask, mask_x, mask_y + i, 226 width, (void *)mask_buffer, 0); 227 } 228 229 if (store) 230 { 231 /* fill dest into second half of scanline */ 232 if (fetch_dest) 233 { 234 fetch_dest (dest, dest_x, dest_y + i, 235 width, (void *)dest_buffer, 0); 236 } 237 238 /* blend */ 239 compose (imp->toplevel, op, 240 (void *)dest_buffer, 241 (void *)src_buffer, 242 (void *)mask_buffer, 243 width); 244 245 /* write back */ 246 store (&(dest->bits), dest_x, dest_y + i, width, 247 (void *)dest_buffer); 248 } 249 else 250 { 251 /* blend */ 252 compose (imp->toplevel, op, 253 bits + (dest_y + i) * stride + dest_x, 254 (void *)src_buffer, (void *)mask_buffer, width); 255 } 256 } 257 258 if (scanline_buffer != stack_scanline_buffer) 259 free (scanline_buffer); 260} 261 262static const pixman_fast_path_t general_fast_path[] = 263{ 264 { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect }, 265 { PIXMAN_OP_NONE } 266}; 267 268static pixman_bool_t 269general_blt (pixman_implementation_t *imp, 270 uint32_t * src_bits, 271 uint32_t * dst_bits, 272 int src_stride, 273 int dst_stride, 274 int src_bpp, 275 int dst_bpp, 276 int src_x, 277 int src_y, 278 int dst_x, 279 int dst_y, 280 int width, 281 int height) 282{ 283 /* We can't blit unless we have sse2 or mmx */ 284 285 return FALSE; 286} 287 288static pixman_bool_t 289general_fill (pixman_implementation_t *imp, 290 uint32_t * bits, 291 int stride, 292 int bpp, 293 int x, 294 int y, 295 int width, 296 int height, 297 uint32_t xor) 298{ 299 return FALSE; 300} 301 302pixman_implementation_t * 303_pixman_implementation_create_general (void) 304{ 305 pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path); 306 307 _pixman_setup_combiner_functions_32 (imp); 308 _pixman_setup_combiner_functions_64 (imp); 309 310 imp->blt = general_blt; 311 imp->fill = general_fill; 312 313 return imp; 314} 315 316