1 /* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ 2 /* 3 * Copyright 2011 Red Hat, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 #include <string.h> 28 #include <stdlib.h> 29 #include "pixman-private.h" 30 #include "pixman-combine32.h" 31 #include "pixman-inlines.h" 32 33 static void 34 noop_composite (pixman_implementation_t *imp, 35 pixman_composite_info_t *info) 36 { 37 return; 38 } 39 40 static void 41 dest_write_back_direct (pixman_iter_t *iter) 42 { 43 iter->buffer += iter->image->bits.rowstride; 44 } 45 46 static uint32_t * 47 noop_get_scanline (pixman_iter_t *iter, const uint32_t *mask) 48 { 49 uint32_t *result = iter->buffer; 50 51 iter->buffer += iter->image->bits.rowstride; 52 53 return result; 54 } 55 56 static uint32_t * 57 get_scanline_null (pixman_iter_t *iter, const uint32_t *mask) 58 { 59 return NULL; 60 } 61 62 static pixman_bool_t 63 noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) 64 { 65 pixman_image_t *image = iter->image; 66 67 #define FLAGS \ 68 (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM) 69 70 if (!image) 71 { 72 iter->get_scanline = get_scanline_null; 73 } 74 else if ((iter->iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) == 75 (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) 76 { 77 iter->get_scanline = _pixman_iter_get_scanline_noop; 78 } 79 else if (image->common.extended_format_code == PIXMAN_solid && 80 (iter->image->type == SOLID || 81 (iter->image_flags & FAST_PATH_NO_ALPHA_MAP))) 82 { 83 if (iter->iter_flags & ITER_NARROW) 84 { 85 uint32_t *buffer = iter->buffer; 86 uint32_t *end = buffer + iter->width; 87 uint32_t color; 88 89 if (image->type == SOLID) 90 color = image->solid.color_32; 91 else 92 color = image->bits.fetch_pixel_32 (&image->bits, 0, 0); 93 94 while (buffer < end) 95 *(buffer++) = color; 96 } 97 else 98 { 99 argb_t *buffer = (argb_t *)iter->buffer; 100 argb_t *end = buffer + iter->width; 101 argb_t color; 102 103 if (image->type == SOLID) 104 color = image->solid.color_float; 105 else 106 color = image->bits.fetch_pixel_float (&image->bits, 0, 0); 107 108 while (buffer < end) 109 *(buffer++) = color; 110 } 111 112 iter->get_scanline = _pixman_iter_get_scanline_noop; 113 } 114 else if (image->common.extended_format_code == PIXMAN_a8r8g8b8 && 115 (iter->iter_flags & ITER_NARROW) && 116 (iter->image_flags & FLAGS) == FLAGS && 117 iter->x >= 0 && iter->y >= 0 && 118 iter->x + iter->width <= image->bits.width && 119 iter->y + iter->height <= image->bits.height) 120 { 121 iter->buffer = 122 image->bits.bits + iter->y * image->bits.rowstride + iter->x; 123 124 iter->get_scanline = noop_get_scanline; 125 } 126 else 127 { 128 return FALSE; 129 } 130 131 return TRUE; 132 } 133 134 static pixman_bool_t 135 noop_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter) 136 { 137 pixman_image_t *image = iter->image; 138 uint32_t image_flags = iter->image_flags; 139 uint32_t iter_flags = iter->iter_flags; 140 141 if ((image_flags & FAST_PATH_STD_DEST_FLAGS) == FAST_PATH_STD_DEST_FLAGS && 142 (iter_flags & ITER_NARROW) == ITER_NARROW && 143 ((image->common.extended_format_code == PIXMAN_a8r8g8b8) || 144 (image->common.extended_format_code == PIXMAN_x8r8g8b8 && 145 (iter_flags & (ITER_LOCALIZED_ALPHA))))) 146 { 147 iter->buffer = image->bits.bits + iter->y * image->bits.rowstride + iter->x; 148 149 iter->get_scanline = _pixman_iter_get_scanline_noop; 150 iter->write_back = dest_write_back_direct; 151 152 return TRUE; 153 } 154 else 155 { 156 return FALSE; 157 } 158 } 159 160 static const pixman_fast_path_t noop_fast_paths[] = 161 { 162 { PIXMAN_OP_DST, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, noop_composite }, 163 { PIXMAN_OP_NONE }, 164 }; 165 166 pixman_implementation_t * 167 _pixman_implementation_create_noop (pixman_implementation_t *fallback) 168 { 169 pixman_implementation_t *imp = 170 _pixman_implementation_create (fallback, noop_fast_paths); 171 172 imp->src_iter_init = noop_src_iter_init; 173 imp->dest_iter_init = noop_dest_iter_init; 174 175 return imp; 176 } 177