GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_display_driver_4bpp_block_move.c Lines: 136 136 100.0 %
Date: 2024-12-05 08:52:37 Branches: 70 70 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** GUIX Component                                                        */
16
/**                                                                       */
17
/**   Display Management (Display)                                        */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define GX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_display.h"
28
#include "gx_system.h"
29
#include "gx_utility.h"
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _gx_display_driver_4bpp_block_move                  PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    4-bpp display driver block moving function.                         */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    context                               Draw context                  */
48
/*    block                                 The rectangle to be moved     */
49
/*    xshift                                Amount to move on X-axis      */
50
/*    yshift                                Amount to move on Y-axis      */
51
/*                                                                        */
52
/*  OUTPUT                                                                */
53
/*                                                                        */
54
/*    None                                                                */
55
/*                                                                        */
56
/*  CALLS                                                                 */
57
/*                                                                        */
58
/*    memmove                               Move a block of data          */
59
/*                                                                        */
60
/*  CALLED BY                                                             */
61
/*                                                                        */
62
/*    GUIX Internal Code                                                  */
63
/*                                                                        */
64
/*  RELEASE HISTORY                                                       */
65
/*                                                                        */
66
/*    DATE              NAME                      DESCRIPTION             */
67
/*                                                                        */
68
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
69
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
70
/*                                            resulting in version 6.1    */
71
/*                                                                        */
72
/**************************************************************************/
73
16
VOID _gx_display_driver_4bpp_block_move(GX_DRAW_CONTEXT *context,
74
                                        GX_RECTANGLE *block, INT xshift, INT yshift)
75
{
76
GX_UBYTE *putrow;
77
GX_UBYTE *getrow;
78
GX_UBYTE *pGet;
79
GX_UBYTE *pPut;
80
INT       width;
81
INT       column;
82
INT       y;
83
INT       height;
84
INT       stride;
85
GX_UBYTE  putmask;
86
GX_UBYTE  getmask;
87
INT       move_width;
88
89
16
    putrow = (GX_UBYTE *)context -> gx_draw_context_memory;
90
91
16
    stride = (context -> gx_draw_context_pitch + 1) >> 1;
92
93
16
    if (xshift)
94
    {
95
9
        if (xshift > 0)
96
        {
97
            /* Copy from right to left.  */
98
5
            width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
99
5
            width -= xshift;
100
101
5
            putrow += block -> gx_rectangle_top * stride;
102
5
            getrow = putrow;
103
104
5
            putrow += block -> gx_rectangle_right >> 1;
105
5
            getrow += (block -> gx_rectangle_left + width - 1) >> 1;
106
107
546
            for (y = block -> gx_rectangle_top; y <= block -> gx_rectangle_bottom; y++)
108
            {
109
541
                pPut = putrow;
110
541
                pGet = getrow;
111
112
541
                if (block -> gx_rectangle_right & 0x01)
113
                {
114
456
                    putmask = 0x0f;
115
                }
116
                else
117
                {
118
85
                    putmask = 0xf0;
119
                }
120
121
541
                if ((block -> gx_rectangle_left + width - 1) & 0x01)
122
                {
123
114
                    getmask = 0x0f;
124
                }
125
                else
126
                {
127
427
                    getmask = 0xf0;
128
                }
129
130
77645
                for (column = 0; column < width; column++)
131
                {
132
                    /* Set bits to 0. */
133
77104
                    *pPut &= (GX_UBYTE)(~putmask);
134
135
77104
                    if ((*pGet) & getmask)
136
                    {
137
75695
                        if (getmask == putmask)
138
                        {
139
11609
                            *pPut |= ((*pGet) & getmask);
140
                        }
141
                        else
142
                        {
143
64086
                            if (getmask == 0xf0)
144
                            {
145
32208
                                *pPut |= (GX_UBYTE)((((*pGet) & getmask) >> 4) & 0x0f);
146
                            }
147
                            else
148
                            {
149
31878
                                *pPut |= (GX_UBYTE)((GX_UBYTE)(((*pGet) & getmask) << 4) & 0xf0);
150
                            }
151
                        }
152
                    }
153
154
77104
                    if (getmask == 0xf0)
155
                    {
156
38723
                        getmask = 0x0f;
157
38723
                        pGet--;
158
                    }
159
                    else
160
                    {
161
38381
                        getmask = 0xf0;
162
                    }
163
164
77104
                    if (putmask == 0xf0)
165
                    {
166
38381
                        putmask = 0x0f;
167
38381
                        pPut--;
168
                    }
169
                    else
170
                    {
171
38723
                        putmask = 0xf0;
172
                    }
173
                }
174
175
541
                putrow += stride;
176
541
                getrow += stride;
177
            }
178
        }
179
        else
180
        {
181
            /* Copy from right to left.  */
182
4
            width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
183
4
            width += xshift;
184
185
4
            putrow += block -> gx_rectangle_top * stride;
186
4
            getrow = putrow;
187
188
4
            putrow += block -> gx_rectangle_left >> 1;
189
4
            getrow += (block -> gx_rectangle_left - xshift) >> 1;
190
191
431
            for (y = block -> gx_rectangle_top; y <= block -> gx_rectangle_bottom; y++)
192
            {
193
427
                pPut = putrow;
194
427
                pGet = getrow;
195
196
427
                if (block -> gx_rectangle_left & 0x01)
197
                {
198
85
                    putmask = 0x0f;
199
                }
200
                else
201
                {
202
342
                    putmask = 0xf0;
203
                }
204
205
427
                if ((block -> gx_rectangle_left - xshift) & 0x01)
206
                {
207
313
                    getmask = 0x0f;
208
                }
209
                else
210
                {
211
114
                    getmask = 0xf0;
212
                }
213
214
47321
                for (column = 0; column < width; column++)
215
                {
216
                    /* Set bits to 0. */
217
46894
                    *pPut &= (GX_UBYTE)(~putmask);
218
219
46894
                    if ((*pGet) & getmask)
220
                    {
221
45329
                        if (getmask == putmask)
222
                        {
223
11609
                            *pPut |= ((*pGet) & getmask);
224
                        }
225
                        else
226
                        {
227
33720
                            if (getmask == 0xf0)
228
                            {
229
16749
                                *pPut |= (GX_UBYTE)((((*pGet) & getmask) >> 4) & 0x0f);
230
                            }
231
                            else
232
                            {
233
16971
                                *pPut |= (GX_UBYTE)((GX_UBYTE)(((*pGet) & getmask) << 4) & 0xf0);
234
                            }
235
                        }
236
                    }
237
238
46894
                    getmask >>= 4;
239
46894
                    if (getmask == 0)
240
                    {
241
23561
                        getmask = 0xf0;
242
23561
                        pGet++;
243
                    }
244
245
46894
                    putmask >>= 4;
246
46894
                    if (putmask == 0)
247
                    {
248
23333
                        putmask = 0xf0;
249
23333
                        pPut++;
250
                    }
251
                }
252
253
427
                putrow += stride;
254
427
                getrow += stride;
255
            }
256
        }
257
    }
258
    else
259
    {
260
7
        width = block -> gx_rectangle_right - block -> gx_rectangle_left + 1;
261
262
7
        if (yshift > 0)
263
        {
264
            /* Copy from top to bottom.  */
265
4
            putrow += (block -> gx_rectangle_bottom * stride);
266
4
            putrow += (block -> gx_rectangle_left >> 1);
267
268
4
            getrow = putrow;
269
4
            getrow -= yshift * stride;
270
271
4
            height = block -> gx_rectangle_bottom - block -> gx_rectangle_top + 1;
272
4
            height -= yshift;
273
274
411
            for (y = 0; y < height; y++)
275
            {
276
407
                pPut = putrow;
277
407
                pGet = getrow;
278
279
407
                if (block -> gx_rectangle_left & 0x01)
280
                {
281
68
                    putmask = 0x0f;
282
                }
283
                else
284
                {
285
339
                    putmask = 0xf0;
286
                }
287
288
407
                column = 0;
289
950
                while (column < width)
290
                {
291

543
                    if ((putmask == 0xf0) && (width - column >= 2))
292
                    {
293
407
                        move_width = (width - column) >> 1;
294
407
                        memmove(pPut, pGet, (size_t)move_width);
295
407
                        pPut += move_width;
296
407
                        pGet += move_width;
297
407
                        column += (move_width << 1);
298
                    }
299
                    else
300
                    {
301
136
                        *pPut &= (GX_UBYTE)(~putmask);
302
136
                        if ((*pGet) & putmask)
303
                        {
304
12
                            *pPut |= (GX_UBYTE)((*pGet) & putmask);
305
                        }
306
307
308
136
                        putmask >>= 4;
309
310
136
                        if (putmask == 0)
311
                        {
312
68
                            putmask = 0xf0;
313
68
                            pPut++;
314
68
                            pGet++;
315
                        }
316
317
136
                        column++;
318
                    }
319
                }
320
321
407
                putrow -= stride;
322
407
                getrow -= stride;
323
            }
324
        }
325
        else
326
        {
327
            /* Copy from bottom to top.  */
328
3
            putrow += (block -> gx_rectangle_top * stride);
329
3
            putrow += (block -> gx_rectangle_left >> 1);
330
331
3
            getrow = putrow;
332
3
            getrow -= yshift * stride;
333
334
3
            height = block -> gx_rectangle_bottom - block -> gx_rectangle_top + 1;
335
3
            height += yshift;
336
337
221
            for (y = 0; y < height; y++)
338
            {
339
218
                pPut = putrow;
340
218
                pGet = getrow;
341
342
218
                if (block -> gx_rectangle_left & 0x01)
343
                {
344
68
                    putmask = 0x0f;
345
                }
346
                else
347
                {
348
150
                    putmask = 0xf0;
349
                }
350
351
218
                column = 0;
352
353
572
                while (column < width)
354
                {
355

354
                    if ((putmask == 0xf0) && (width - column >= 2))
356
                    {
357
218
                        move_width = (width - column) >> 1;
358
218
                        memmove(pPut, pGet, (size_t)move_width);
359
218
                        pPut += move_width;
360
218
                        pGet += move_width;
361
218
                        column += (move_width << 1);
362
                    }
363
                    else
364
                    {
365
136
                        *pPut &= (GX_UBYTE)(~putmask);
366
136
                        if ((*pGet) & putmask)
367
                        {
368
12
                            *pPut |= (GX_UBYTE)((*pGet) & putmask);
369
                        }
370
371
136
                        putmask >>= 4;
372
373
136
                        if (putmask == 0)
374
                        {
375
68
                            putmask = 0xf0;
376
68
                            pPut++;
377
68
                            pGet++;
378
                        }
379
380
136
                        column++;
381
                    }
382
                }
383
384
218
                putrow += stride;
385
218
                getrow += stride;
386
            }
387
        }
388
    }
389
16
}
390