pixman-noop.c revision 1176bdada62cabc6ec4b0308a930e83b679d5d36
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
33static void
34noop_composite (pixman_implementation_t *imp,
35		pixman_composite_info_t *info)
36{
37    return;
38}
39
40static void
41dest_write_back_direct (pixman_iter_t *iter)
42{
43    iter->buffer += iter->image->bits.rowstride;
44}
45
46static uint32_t *
47noop_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
56static uint32_t *
57get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
58{
59    return NULL;
60}
61
62static pixman_bool_t
63noop_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
134static pixman_bool_t
135noop_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
160static 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
166pixman_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