Home | History | Annotate | Download | only in pixman
      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