1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** GUIX Component */
17 /** */
18 /** Display Management (Display) */
19 /** */
20 /**************************************************************************/
21
22 #define GX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "gx_api.h"
28 #include "gx_display.h"
29 #include "gx_utility.h"
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _gx_display_driver_4bpp_canvas_copy PORTABLE C */
36 /* 6.1 */
37 /* AUTHOR */
38 /* */
39 /* Kenneth Maxwell, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* Generic 4bpp canvas copy function. */
44 /* */
45 /* INPUT */
46 /* */
47 /* canvas The canvas to copy from */
48 /* composite The canvas to copy to */
49 /* */
50 /* OUTPUT */
51 /* */
52 /* None */
53 /* */
54 /* CALLS */
55 /* */
56 /* _gx_utility_rectangle_shift Move the rectangle */
57 /* _gx_utility_rectangle_overlap_detect Detect two rectangles being */
58 /* overlap to each other */
59 /* memcpy Move canvas data */
60 /* */
61 /* CALLED BY */
62 /* */
63 /* GUIX Internal Code */
64 /* */
65 /* RELEASE HISTORY */
66 /* */
67 /* DATE NAME DESCRIPTION */
68 /* */
69 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
70 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
71 /* resulting in version 6.1 */
72 /* */
73 /**************************************************************************/
_gx_display_driver_4bpp_canvas_copy(GX_CANVAS * canvas,GX_CANVAS * composite)74 VOID _gx_display_driver_4bpp_canvas_copy(GX_CANVAS *canvas, GX_CANVAS *composite)
75 {
76 GX_RECTANGLE dirty;
77 GX_RECTANGLE overlap;
78 GX_UBYTE *read;
79 GX_UBYTE *write;
80 GX_UBYTE color;
81 INT row;
82 INT column;
83 UINT read_pos;
84 UINT write_pos;
85 GX_UBYTE read_mask;
86 GX_UBYTE write_mask;
87 INT readstride;
88 INT writestride;
89 INT offset;
90
91 dirty.gx_rectangle_left = dirty.gx_rectangle_top = 0;
92 dirty.gx_rectangle_right = (GX_VALUE)(canvas -> gx_canvas_x_resolution - 1);
93 dirty.gx_rectangle_bottom = (GX_VALUE)(canvas -> gx_canvas_y_resolution - 1);
94 readstride = (canvas->gx_canvas_x_resolution + 1) >> 1;
95 writestride = (composite->gx_canvas_x_resolution + 1) >> 1;
96
97 _gx_utility_rectangle_shift(&dirty, canvas -> gx_canvas_display_offset_x, canvas -> gx_canvas_display_offset_y);
98
99 if (_gx_utility_rectangle_overlap_detect(&dirty, &composite -> gx_canvas_dirty_area, &overlap))
100 {
101 offset = overlap.gx_rectangle_left - dirty.gx_rectangle_left;
102 read_pos = (UINT)((overlap.gx_rectangle_top - dirty.gx_rectangle_top) * readstride + (offset >> 1));
103 write_pos = (UINT)(overlap.gx_rectangle_top * writestride + (overlap.gx_rectangle_left >> 1));
104
105 for (row = overlap.gx_rectangle_top; row <= overlap.gx_rectangle_bottom; row++)
106 {
107 read = (GX_UBYTE *)canvas->gx_canvas_memory;
108 write = (GX_UBYTE *)composite->gx_canvas_memory;
109
110 read += read_pos;
111 write += write_pos;
112 /* If position is odd, it means the low bits. */
113 if (offset & 0x01)
114 {
115 read_mask = 0x0f;
116 }
117 else
118 {
119 read_mask = 0xf0;
120 }
121
122 if (overlap.gx_rectangle_left & 0x01)
123 {
124 write_mask = 0x0f;
125 }
126 else
127 {
128 write_mask = 0xf0;
129 }
130
131 for (column = overlap.gx_rectangle_left; column <= overlap.gx_rectangle_right; column++)
132 {
133 color = (*read) & read_mask;
134 *write = (GX_UBYTE)((*write) & (~write_mask));
135
136 if (color)
137 {
138 /* Read and write have same mask bits. */
139 if (read_mask & write_mask)
140 {
141 *write |= color;
142 }
143 else
144 {
145 /* Read and write are malposed. */
146 /* If position is odd, it means the low bits. */
147 if (write_mask & 0x01)
148 {
149 *write |= (GX_UBYTE)(color >> 4);
150 }
151 else
152 {
153 *write |= (GX_UBYTE)(color << 4);
154 }
155 }
156 }
157
158 read_mask >>= 4;
159 write_mask >>= 4;
160 if (!read_mask)
161 {
162 read++;
163 read_mask = 0xf0;
164 }
165 if (!write_mask)
166 {
167 write++;
168 write_mask = 0xf0;
169 }
170 }
171 write_pos = (UINT)((INT)write_pos + writestride);
172 read_pos = (UINT)((INT)read_pos + readstride);
173 }
174 }
175 }
176
177