GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_system_dirty_list_trim.c Lines: 57 57 100.0 %
Date: 2024-12-05 08:52:37 Branches: 42 42 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
/**   System Management (System)                                          */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define GX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_system.h"
28
#include "gx_utility.h"
29
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _gx_system_dirty_overlap_check                      PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    This function checks if it has overlapping dirty area with others.  */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    dirty                                 Pointer to dirty area         */
48
/*                                                                        */
49
/*  OUTPUT                                                                */
50
/*                                                                        */
51
/*    None                                                                */
52
/*                                                                        */
53
/*  CALLS                                                                 */
54
/*                                                                        */
55
/*    _gx_utility_rectangle_overlap_detect  Detect overlap of rectangles  */
56
/*                                                                        */
57
/*  CALLED BY                                                             */
58
/*                                                                        */
59
/*    _gx_system_dirty_list_trim            Calculate and trim dirty list */
60
/*                                                                        */
61
/*  RELEASE HISTORY                                                       */
62
/*                                                                        */
63
/*    DATE              NAME                      DESCRIPTION             */
64
/*                                                                        */
65
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
66
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
67
/*                                            resulting in version 6.1    */
68
/*                                                                        */
69
/**************************************************************************/
70
195997
static VOID _gx_system_dirty_overlap_check(GX_DIRTY_AREA *dirty)
71
{
72
GX_WIDGET      *dirty_widget;
73
GX_WIDGET      *sibling;
74
GX_WIDGET      *parent;
75
76
195997
    dirty_widget = dirty -> gx_dirty_area_widget;
77
195997
    parent = dirty_widget -> gx_widget_parent;
78
79
313108
    while (parent)
80
    {
81
        /* check to see if this is a viewport owner */
82
197546
        if (dirty -> gx_dirty_area_widget -> gx_widget_type >= GX_TYPE_WINDOW)
83
        {
84
122322
            if (parent -> gx_widget_type == GX_TYPE_ROOT_WINDOW)
85
            {
86
                /* this widget is a view owner, no need to go further */
87
80435
                return;
88
            }
89
        }
90
91
        /* not a view owner, so check to see if it has overlapping siblings */
92
117111
        sibling = dirty_widget -> gx_widget_next;
93
94
756349
        while(sibling)
95
        {
96
641851
            if (_gx_utility_rectangle_overlap_detect(&sibling -> gx_widget_size, &dirty -> gx_dirty_area_rectangle, NULL))
97
            {
98
                /* mark the parent as dirty, so that both children are drawn */
99
2613
                dirty_widget = parent;
100
2613
                dirty -> gx_dirty_area_widget = dirty_widget;
101
2613
                break;
102
            }
103
639238
            sibling = sibling->gx_widget_next;
104
        }
105
117111
        dirty_widget = parent;
106
117111
        parent = dirty_widget -> gx_widget_parent;
107
    }
108
}
109
110
/**************************************************************************/
111
/*                                                                        */
112
/*  FUNCTION                                               RELEASE        */
113
/*                                                                        */
114
/*    _gx_system_dirty_list_trim                          PORTABLE C      */
115
/*                                                           6.1          */
116
/*  AUTHOR                                                                */
117
/*                                                                        */
118
/*    Kenneth Maxwell, Microsoft Corporation                              */
119
/*                                                                        */
120
/*  DESCRIPTION                                                           */
121
/*                                                                        */
122
/*    This function trims the dirty list to reduce redundancy and         */
123
/*    eliminate invalid entries prior to refreshing the canvas. This      */
124
/*    function returns the sum of the remaining dirty areas               */
125
/*                                                                        */
126
/*  INPUT                                                                 */
127
/*                                                                        */
128
/*    dirty_area                            Pointer to return value       */
129
/*    root                                  Point to the root window      */
130
/*                                                                        */
131
/*  OUTPUT                                                                */
132
/*                                                                        */
133
/*    [GX_TRUE | GX_FALSE]                  GX_TRUE if dirty, otherwise   */
134
/*                                            GX_FALSE                    */
135
/*                                                                        */
136
/*  CALLS                                                                 */
137
/*                                                                        */
138
/*    _gx_utility_rectangle_combine         Combine two rectangles        */
139
/*    _gx_utility_rectangle_define          Define a rectangle            */
140
/*    _gx_utility_rectangle_overlap_detect  Detect overlap of rectangles  */
141
/*    _gx_system_dirty_overlap_check        Detect overlapping children   */
142
/*                                                                        */
143
/*  CALLED BY                                                             */
144
/*                                                                        */
145
/*    _gx_system_canvas_refresh             Refresh the canvas            */
146
/*                                                                        */
147
/*  RELEASE HISTORY                                                       */
148
/*                                                                        */
149
/*    DATE              NAME                      DESCRIPTION             */
150
/*                                                                        */
151
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
152
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
153
/*                                            resulting in version 6.1    */
154
/*                                                                        */
155
/**************************************************************************/
156
156747
UINT  _gx_system_dirty_list_trim(GX_RECTANGLE *dirty_area, GX_WINDOW_ROOT *root)
157
{
158
159
UINT           index_1;
160
UINT           index_2;
161
GX_DIRTY_AREA *dirty;
162
GX_DIRTY_AREA *dirty2;
163
GX_CANVAS     *canvas;
164
GX_WIDGET     *parent;
165
166
    /* pick up pointer to canvas */
167
156747
    canvas = root -> gx_window_root_canvas;
168
169
    /* Initialize a dirty area rectangle.  */
170
156747
    _gx_utility_rectangle_define(dirty_area, canvas -> gx_canvas_x_resolution,
171
156747
                                 canvas -> gx_canvas_y_resolution, -1, -1);
172
173
    /* Setup pointer to start of dirty area list.  */
174
156747
    dirty =  canvas -> gx_canvas_dirty_list;
175
176
    /* This loop looks for invalid entries (invisible) and
177
       entries that have overlappers in the z order, in
178
       which case we need to back up the drawing layer
179
     */
180
181
353687
    for (index_1 = 0; index_1 < canvas -> gx_canvas_dirty_count; index_1++)
182
    {
183
        /* Is there a widget for this dirty area entry?  */
184
196940
        if (dirty -> gx_dirty_area_widget == GX_NULL)
185
        {
186
29
            dirty++;
187
29
            continue;
188
        }
189
190
196911
        if (!(dirty -> gx_dirty_area_widget -> gx_widget_status & GX_STATUS_VISIBLE))
191
        {
192
914
            dirty -> gx_dirty_area_widget = GX_NULL;
193
914
            dirty++;
194
914
            continue;
195
        }
196
197
        /* check to see if we need to modify the drawing level because of overlapping
198
           siblings
199
        */
200
195997
         _gx_system_dirty_overlap_check(dirty);
201
195997
        dirty++;
202
    }
203
204
    /* This loop tests to see if a dirty entry also has a parent
205
       that is marked as dirty. If the dirty rectangles overlap,
206
       just combine the rectangles and get rid of the child entry
207
     */
208
209
156747
    dirty =  canvas -> gx_canvas_dirty_list;
210
211
353687
    for (index_1 = 0; index_1 < canvas -> gx_canvas_dirty_count; index_1++)
212
    {
213
        /* Is there a widget for this dirty area entry?  */
214
196940
        if (dirty -> gx_dirty_area_widget == GX_NULL)
215
        {
216
3985
            dirty++;
217
3985
            continue;
218
        }
219
220
        /* Yes, there is a widget. Loop through the dirty area array.  */
221
633218
        for (index_2 = 0; index_2 < canvas -> gx_canvas_dirty_count; index_2++)
222
        {
223
            /* Pickup the next dirty area entry.  */
224
440263
            dirty2 = &canvas -> gx_canvas_dirty_list[index_2];
225
226
            /* Is is valid?  */
227

440263
            if ((dirty2 -> gx_dirty_area_widget) && (dirty != dirty2))
228
            {
229
228827
                parent = dirty2 -> gx_dirty_area_widget -> gx_widget_parent;
230
231

456860
                while (parent && (parent != dirty -> gx_dirty_area_widget))
232
                {
233
228033
                    parent = parent -> gx_widget_parent;
234
                }
235
236
                /* check to see if one is parent of the other */
237
228827
                if (parent == dirty -> gx_dirty_area_widget)
238
                {
239
                    /* dirty1 is parent of dirty2, do the dirty
240
                        rectangles overlap?  */
241
80382
                    if (_gx_utility_rectangle_overlap_detect(&dirty -> gx_dirty_area_rectangle, &dirty2 -> gx_dirty_area_rectangle, NULL))
242
                    {
243
                        /* Yes, combine the two entries into one and NULL out the child entry.  */
244
56173
                        _gx_utility_rectangle_combine(&dirty -> gx_dirty_area_rectangle, &dirty2 -> gx_dirty_area_rectangle);
245
246
                        /* NULL out the child entry.  */
247
56173
                        dirty2 -> gx_dirty_area_widget = GX_NULL;
248
56173
                        continue;
249
                    }
250
                }
251
252
                /* check to see if two entries for same widget */
253
172654
                if (dirty2 -> gx_dirty_area_widget == dirty -> gx_dirty_area_widget)
254
                {
255
                    /* same widget marked twice */
256
                    /* do the dirty rectangles overlap?  */
257
29966
                    if (_gx_utility_rectangle_overlap_detect(&dirty -> gx_dirty_area_rectangle, &dirty2 -> gx_dirty_area_rectangle, NULL))
258
                    {
259
                        /* Yes, combine the two entries into one and NULL out the child entry.  */
260
1188
                        _gx_utility_rectangle_combine(&dirty -> gx_dirty_area_rectangle, &dirty2 -> gx_dirty_area_rectangle);
261
262
                        /* NULL out the second entry.  */
263
1188
                        dirty2 -> gx_dirty_area_widget =  GX_NULL;
264
                    }
265
                }
266
            }
267
        }
268
269
        /* Add to our overall sum of dirty area.  */
270
192955
        _gx_utility_rectangle_combine(dirty_area, &(dirty -> gx_dirty_area_rectangle));
271
272
        /* Move to next dirty area entry.  */
273
192955
        dirty++;
274
    }
275
276
    /* Do we have anything to draw?  */
277
156747
    if ((dirty_area -> gx_rectangle_left <= dirty_area -> gx_rectangle_right) &&
278
122234
        (dirty_area -> gx_rectangle_top <= dirty_area -> gx_rectangle_bottom))
279
    {
280
281
        /* Yes, we have something to draw.  */
282
122158
        return(GX_TRUE);
283
    }
284
    else
285
    {
286
287
        /* No, nothing left after trimming duplicates.  */
288
34589
        return(GX_FALSE);
289
    }
290
}
291