1 # Module generating C source and headers for various PixelTypes
2 # - submodule for blit and friends
3 # 2011 - Tomas Gavenciak <gavento@ucw.cz>
5 from gfxprim
.generators
.utils
import *
7 ## all generated direct blits, for generating GP_Blit() and others
10 # TODO: adapt for both bit-endianness (in-byte prefix and suffix)
11 # WARN: assuming little-endian in sub-byte pixels order (probably)
12 def gen_blit_same_t(size
, size_suffix
, header
, code
):
13 "Generate a function blitting the same type of pixel."
14 "Only depends on bpp (bit size), size_suffix must be"
15 "of form 8BPP, 2BPP_LE and the like."
18 "\n/*** Blit preserving type, variant for {{ size_suffix }} ***\n"
19 " * Assumes the contexts to be of the right types and sizes\n"
20 " * Ignores transformations and clipping */\n\n"
21 "void GP_Blit_{{ size_suffix }}(const GP_Context *c1, GP_Coord x1, GP_Coord y1, GP_Size w, GP_Size h,\n"
22 " GP_Context *c2, GP_Coord x2, GP_Coord y2);\n",
23 size
=size
, size_suffix
=size_suffix
)
26 "\n/*** Blit preservimg type, variant for {{ size_suffix }} ***/\n"
27 "void GP_Blit_{{ size_suffix }}(const GP_Context *c1, GP_Coord x1, GP_Coord y1, GP_Size w, GP_Size h,\n"
28 " GP_Context *c2, GP_Coord x2, GP_Coord y2)\n"
30 " if (unlikely(w == 0 || h == 0)) return;\n\n"
31 " /* Special case - copy whole line-block with one memcpy() */\n"
32 " if ((x1 == 0) && (x2 == 0) && (w == c1->w) && (c1->w == c2->w) &&\n"
33 " (c1->bytes_per_row == c2->bytes_per_row)) {\n"
34 " memcpy(c2->pixels + c2->bytes_per_row * y2,\n"
35 " c1->pixels + c1->bytes_per_row * y1,\n"
36 " c1->bytes_per_row * h);\n"
40 " /* General case - memcpy() each horizontal line */\n"
41 " for (GP_Size i = 0; i < h; i++)\n"
42 " memcpy(GP_PIXEL_ADDR_{{ size_suffix }}(c2, x2, y2 + i), \n"
43 " GP_PIXEL_ADDR_{{ size_suffix }}(c1, x2, y2 + i),\n"
44 " {{ size/8 }} * w);\n"
45 "{% else %}" # subtle - rectangles may not be byte aligned in the same way
46 " /* Alignment (index) of first bits in the first byte */\n"
47 " int al1 = GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x1);\n"
48 " int al2 = GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x2);\n"
49 " /* Special case of the same alignment and width >=2 bytes */\n"
50 " if ((al1 == al2) && (w * {{ size }} >= 16)) {\n"
51 " /* Number of bits in the last partial byte */\n"
52 " int end_al = GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x1 + w);\n"
53 " GP_ASSERT(({{ size }} * w - al1 - end_al) % 8 == 0);\n"
54 " int copy_size = ({{ size }} * w - al1 - end_al) / 8;\n"
55 " /* First and last byte incident to the line */\n"
56 " uint8_t *p1 = GP_PIXEL_ADDR_{{ size_suffix }}(c1, x1, y1);\n"
57 " uint8_t *p2 = GP_PIXEL_ADDR_{{ size_suffix }}(c2, x2, y2);\n"
58 " uint8_t *end_p1 = GP_PIXEL_ADDR_{{ size_suffix }}(c1, x1 + w - 1, y1);\n"
59 " uint8_t *end_p2 = GP_PIXEL_ADDR_{{ size_suffix }}(c2, x2 + w - 1, y2);\n"
60 " for (GP_Size i = 0; i < h; i++) {\n"
62 " GP_SET_BITS(al1, 8-al1, *p2, GP_GET_BITS(al1, 8-al1, *p1));\n"
63 " memcpy(p2+(al1!=0), p1+(al1!=0), copy_size);\n"
65 " GP_SET_BITS(0, end_al, *end_p2, GP_GET_BITS(0, end_al, *end_p1));\n"
66 " p1 += c1->bytes_per_row;\n"
67 " end_p1 += c1->bytes_per_row;\n"
68 " p2 += c2->bytes_per_row;\n"
69 " end_p2 += c2->bytes_per_row;\n"
71 " } else /* Different bit-alignment, can't use memcpy() */\n"
72 " GP_Blit_Naive(c1, x1, y1, w, h, c2, x2, y2);\n"
74 "}\n", size
=size
, size_suffix
=size_suffix
)