GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_system_dirty_list_trim.c Lines: 57 57 100.0 %
Date: 2026-03-06 19:21:09 Branches: 42 42 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   System Management (System)                                          */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "gx_api.h"
28
#include "gx_system.h"
29
#include "gx_utility.h"
30
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_system_dirty_overlap_check                      PORTABLE C      */
37
/*                                                           6.1          */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Kenneth Maxwell, Microsoft Corporation                              */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function checks if it has overlapping dirty area with others.  */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    dirty                                 Pointer to dirty area         */
49
/*                                                                        */
50
/*  OUTPUT                                                                */
51
/*                                                                        */
52
/*    None                                                                */
53
/*                                                                        */
54
/*  CALLS                                                                 */
55
/*                                                                        */
56
/*    _gx_utility_rectangle_overlap_detect  Detect overlap of rectangles  */
57
/*                                                                        */
58
/*  CALLED BY                                                             */
59
/*                                                                        */
60
/*    _gx_system_dirty_list_trim            Calculate and trim dirty list */
61
/*                                                                        */
62
/**************************************************************************/
63
195998
static VOID _gx_system_dirty_overlap_check(GX_DIRTY_AREA *dirty)
64
{
65
GX_WIDGET      *dirty_widget;
66
GX_WIDGET      *sibling;
67
GX_WIDGET      *parent;
68
69
195998
    dirty_widget = dirty -> gx_dirty_area_widget;
70
195998
    parent = dirty_widget -> gx_widget_parent;
71
72
313109
    while (parent)
73
    {
74
        /* check to see if this is a viewport owner */
75
197544
        if (dirty -> gx_dirty_area_widget -> gx_widget_type >= GX_TYPE_WINDOW)
76
        {
77
122320
            if (parent -> gx_widget_type == GX_TYPE_ROOT_WINDOW)
78
            {
79
                /* this widget is a view owner, no need to go further */
80
80433
                return;
81
            }
82
        }
83
84
        /* not a view owner, so check to see if it has overlapping siblings */
85
117111
        sibling = dirty_widget -> gx_widget_next;
86
87
756349
        while(sibling)
88
        {
89
641851
            if (_gx_utility_rectangle_overlap_detect(&sibling -> gx_widget_size, &dirty -> gx_dirty_area_rectangle, NULL))
90
            {
91
                /* mark the parent as dirty, so that both children are drawn */
92
2613
                dirty_widget = parent;
93
2613
                dirty -> gx_dirty_area_widget = dirty_widget;
94
2613
                break;
95
            }
96
639238
            sibling = sibling->gx_widget_next;
97
        }
98
117111
        dirty_widget = parent;
99
117111
        parent = dirty_widget -> gx_widget_parent;
100
    }
101
}
102
103
/**************************************************************************/
104
/*                                                                        */
105
/*  FUNCTION                                               RELEASE        */
106
/*                                                                        */
107
/*    _gx_system_dirty_list_trim                          PORTABLE C      */
108
/*                                                           6.1          */
109
/*  AUTHOR                                                                */
110
/*                                                                        */
111
/*    Kenneth Maxwell, Microsoft Corporation                              */
112
/*                                                                        */
113
/*  DESCRIPTION                                                           */
114
/*                                                                        */
115
/*    This function trims the dirty list to reduce redundancy and         */
116
/*    eliminate invalid entries prior to refreshing the canvas. This      */
117
/*    function returns the sum of the remaining dirty areas               */
118
/*                                                                        */
119
/*  INPUT                                                                 */
120
/*                                                                        */
121
/*    dirty_area                            Pointer to return value       */
122
/*    root                                  Point to the root window      */
123
/*                                                                        */
124
/*  OUTPUT                                                                */
125
/*                                                                        */
126
/*    [GX_TRUE | GX_FALSE]                  GX_TRUE if dirty, otherwise   */
127
/*                                            GX_FALSE                    */
128
/*                                                                        */
129
/*  CALLS                                                                 */
130
/*                                                                        */
131
/*    _gx_utility_rectangle_combine         Combine two rectangles        */
132
/*    _gx_utility_rectangle_define          Define a rectangle            */
133
/*    _gx_utility_rectangle_overlap_detect  Detect overlap of rectangles  */
134
/*    _gx_system_dirty_overlap_check        Detect overlapping children   */
135
/*                                                                        */
136
/*  CALLED BY                                                             */
137
/*                                                                        */
138
/*    _gx_system_canvas_refresh             Refresh the canvas            */
139
/*                                                                        */
140
/**************************************************************************/
141
156822
UINT  _gx_system_dirty_list_trim(GX_RECTANGLE *dirty_area, GX_WINDOW_ROOT *root)
142
{
143
144
UINT           index_1;
145
UINT           index_2;
146
GX_DIRTY_AREA *dirty;
147
GX_DIRTY_AREA *dirty2;
148
GX_CANVAS     *canvas;
149
GX_WIDGET     *parent;
150
151
    /* pick up pointer to canvas */
152
156822
    canvas = root -> gx_window_root_canvas;
153
154
    /* Initialize a dirty area rectangle.  */
155
156822
    _gx_utility_rectangle_define(dirty_area, canvas -> gx_canvas_x_resolution,
156
156822
                                 canvas -> gx_canvas_y_resolution, -1, -1);
157
158
    /* Setup pointer to start of dirty area list.  */
159
156822
    dirty =  canvas -> gx_canvas_dirty_list;
160
161
    /* This loop looks for invalid entries (invisible) and
162
       entries that have overlappers in the z order, in
163
       which case we need to back up the drawing layer
164
     */
165
166
353763
    for (index_1 = 0; index_1 < canvas -> gx_canvas_dirty_count; index_1++)
167
    {
168
        /* Is there a widget for this dirty area entry?  */
169
196941
        if (dirty -> gx_dirty_area_widget == GX_NULL)
170
        {
171
29
            dirty++;
172
29
            continue;
173
        }
174
175
196912
        if (!(dirty -> gx_dirty_area_widget -> gx_widget_status & GX_STATUS_VISIBLE))
176
        {
177
914
            dirty -> gx_dirty_area_widget = GX_NULL;
178
914
            dirty++;
179
914
            continue;
180
        }
181
182
        /* check to see if we need to modify the drawing level because of overlapping
183
           siblings
184
        */
185
195998
         _gx_system_dirty_overlap_check(dirty);
186
195998
        dirty++;
187
    }
188
189
    /* This loop tests to see if a dirty entry also has a parent
190
       that is marked as dirty. If the dirty rectangles overlap,
191
       just combine the rectangles and get rid of the child entry
192
     */
193
194
156822
    dirty =  canvas -> gx_canvas_dirty_list;
195
196
353763
    for (index_1 = 0; index_1 < canvas -> gx_canvas_dirty_count; index_1++)
197
    {
198
        /* Is there a widget for this dirty area entry?  */
199
196941
        if (dirty -> gx_dirty_area_widget == GX_NULL)
200
        {
201
3983
            dirty++;
202
3983
            continue;
203
        }
204
205
        /* Yes, there is a widget. Loop through the dirty area array.  */
206
633222
        for (index_2 = 0; index_2 < canvas -> gx_canvas_dirty_count; index_2++)
207
        {
208
            /* Pickup the next dirty area entry.  */
209
440264
            dirty2 = &canvas -> gx_canvas_dirty_list[index_2];
210
211
            /* Is is valid?  */
212

440264
            if ((dirty2 -> gx_dirty_area_widget) && (dirty != dirty2))
213
            {
214
228825
                parent = dirty2 -> gx_dirty_area_widget -> gx_widget_parent;
215
216

456858
                while (parent && (parent != dirty -> gx_dirty_area_widget))
217
                {
218
228033
                    parent = parent -> gx_widget_parent;
219
                }
220
221
                /* check to see if one is parent of the other */
222
228825
                if (parent == dirty -> gx_dirty_area_widget)
223
                {
224
                    /* dirty1 is parent of dirty2, do the dirty
225
                        rectangles overlap?  */
226
80380
                    if (_gx_utility_rectangle_overlap_detect(&dirty -> gx_dirty_area_rectangle, &dirty2 -> gx_dirty_area_rectangle, NULL))
227
                    {
228
                        /* Yes, combine the two entries into one and NULL out the child entry.  */
229
56171
                        _gx_utility_rectangle_combine(&dirty -> gx_dirty_area_rectangle, &dirty2 -> gx_dirty_area_rectangle);
230
231
                        /* NULL out the child entry.  */
232
56171
                        dirty2 -> gx_dirty_area_widget = GX_NULL;
233
56171
                        continue;
234
                    }
235
                }
236
237
                /* check to see if two entries for same widget */
238
172654
                if (dirty2 -> gx_dirty_area_widget == dirty -> gx_dirty_area_widget)
239
                {
240
                    /* same widget marked twice */
241
                    /* do the dirty rectangles overlap?  */
242
29966
                    if (_gx_utility_rectangle_overlap_detect(&dirty -> gx_dirty_area_rectangle, &dirty2 -> gx_dirty_area_rectangle, NULL))
243
                    {
244
                        /* Yes, combine the two entries into one and NULL out the child entry.  */
245
1188
                        _gx_utility_rectangle_combine(&dirty -> gx_dirty_area_rectangle, &dirty2 -> gx_dirty_area_rectangle);
246
247
                        /* NULL out the second entry.  */
248
1188
                        dirty2 -> gx_dirty_area_widget =  GX_NULL;
249
                    }
250
                }
251
            }
252
        }
253
254
        /* Add to our overall sum of dirty area.  */
255
192958
        _gx_utility_rectangle_combine(dirty_area, &(dirty -> gx_dirty_area_rectangle));
256
257
        /* Move to next dirty area entry.  */
258
192958
        dirty++;
259
    }
260
261
    /* Do we have anything to draw?  */
262
156822
    if ((dirty_area -> gx_rectangle_left <= dirty_area -> gx_rectangle_right) &&
263
122237
        (dirty_area -> gx_rectangle_top <= dirty_area -> gx_rectangle_bottom))
264
    {
265
266
        /* Yes, we have something to draw.  */
267
122161
        return(GX_TRUE);
268
    }
269
    else
270
    {
271
272
        /* No, nothing left after trimming duplicates.  */
273
34661
        return(GX_FALSE);
274
    }
275
}
276