a2cda2438e6e75b5e0d3fdcee87712f6a77ed723
[openembedded.git] /
1 From 8ea1a333de202018a862a7b04b94479d3109274b Mon Sep 17 00:00:00 2001
2 From: Siarhei Siamashka <siarhei.siamashka@nokia.com>
3 Date: Tue, 16 Mar 2010 16:55:28 +0100
4 Subject: [PATCH 1/5] Generic C implementation of pixman_blt with overlapping support
5
6 Uses memcpy/memmove functions to copy pixels, can handle the
7 case when both source and destination areas are in the same
8 image (this is useful for scrolling).
9
10 It is assumed that copying direction is only important when
11 using the same image for both source and destination (and
12 src_stride == dst_stride). Copying direction is undefined
13 for the images with different source and destination stride
14 which happen to be in the overlapped areas (but this is an
15 unrealistic case anyway).
16 ---
17  pixman/pixman-general.c |   21 ++++++++++++++++++---
18  pixman/pixman-private.h |   43 +++++++++++++++++++++++++++++++++++++++++++
19  2 files changed, 61 insertions(+), 3 deletions(-)
20
21 diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
22 index bddf79a..f525744 100644
23 --- a/pixman/pixman-general.c
24 +++ b/pixman/pixman-general.c
25 @@ -285,9 +285,24 @@ general_blt (pixman_implementation_t *imp,
26               int                      width,
27               int                      height)
28  {
29 -    /* We can't blit unless we have sse2 or mmx */
30 -
31 -    return FALSE;
32 +    uint8_t *dst_bytes = (uint8_t *)dst_bits;
33 +    uint8_t *src_bytes = (uint8_t *)src_bits;
34 +    int bpp;
35 +
36 +    if (src_bpp != dst_bpp || src_bpp & 7)
37 +       return FALSE;
38 +
39 +    bpp = src_bpp >> 3;
40 +    width *= bpp;
41 +    src_stride *= 4;
42 +    dst_stride *= 4;
43 +    pixman_blt_helper (src_bytes + src_y * src_stride + src_x * bpp,
44 +                       dst_bytes + dst_y * dst_stride + dst_x * bpp,
45 +                       src_stride,
46 +                       dst_stride,
47 +                       width,
48 +                       height);
49 +    return TRUE;
50  }
51  
52  static pixman_bool_t
53 diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
54 index d5767af..eeb677d 100644
55 --- a/pixman/pixman-private.h
56 +++ b/pixman/pixman-private.h
57 @@ -10,6 +10,7 @@
58  
59  #include "pixman.h"
60  #include <time.h>
61 +#include <string.h>
62  #include <assert.h>
63  #include <stdio.h>
64  #include <string.h>
65 @@ -867,4 +868,46 @@ void pixman_timer_register (pixman_timer_t *timer);
66  
67  #endif /* PIXMAN_TIMERS */
68  
69 +/* a helper function, can blit 8-bit images with src/dst overlapping support */
70 +static inline void
71 +pixman_blt_helper (uint8_t *src_bytes,
72 +                   uint8_t *dst_bytes,
73 +                   int      src_stride,
74 +                   int      dst_stride,
75 +                   int      width,
76 +                   int      height)
77 +{
78 +    /*
79 +     * The second part of this check is not strictly needed, but it prevents
80 +     * unnecessary upside-down processing of areas which belong to different
81 +     * images. Upside-down processing can be slower with fixed-distance-ahead
82 +     * prefetch and perceived as having more tearing.
83 +     */
84 +    if (src_bytes < dst_bytes + width &&
85 +       src_bytes + src_stride * height > dst_bytes)
86 +    {
87 +       src_bytes += src_stride * height - src_stride;
88 +       dst_bytes += dst_stride * height - dst_stride;
89 +       dst_stride = -dst_stride;
90 +       src_stride = -src_stride;
91 +       /* Horizontal scrolling to the left needs memmove */
92 +       if (src_bytes + width > dst_bytes)
93 +       {
94 +           while (--height >= 0)
95 +           {
96 +               memmove (dst_bytes, src_bytes, width);
97 +               dst_bytes += dst_stride;
98 +               src_bytes += src_stride;
99 +           }
100 +           return;
101 +       }
102 +    }
103 +    while (--height >= 0)
104 +    {
105 +       memcpy (dst_bytes, src_bytes, width);
106 +       dst_bytes += dst_stride;
107 +       src_bytes += src_stride;
108 +    }
109 +}
110 +
111  #endif /* PIXMAN_PRIVATE_H */
112 -- 
113 1.6.6.1
114