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
noop_composite(pixman_implementation_t * imp,pixman_composite_info_t * info)34 noop_composite (pixman_implementation_t *imp,
35 pixman_composite_info_t *info)
36 {
37 return;
38 }
39
40 static void
dest_write_back_direct(pixman_iter_t * iter)41 dest_write_back_direct (pixman_iter_t *iter)
42 {
43 iter->buffer += iter->image->bits.rowstride;
44 }
45
46 static uint32_t *
noop_get_scanline(pixman_iter_t * iter,const uint32_t * mask)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 *
get_scanline_null(pixman_iter_t * iter,const uint32_t * mask)57 get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
58 {
59 return NULL;
60 }
61
62 static pixman_bool_t
noop_src_iter_init(pixman_implementation_t * imp,pixman_iter_t * iter)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
noop_dest_iter_init(pixman_implementation_t * imp,pixman_iter_t * iter)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 *
_pixman_implementation_create_noop(pixman_implementation_t * fallback)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