1 /*
2  * Copyright (C) 2007,2008,2009,2010,2011  Intel Corporation.
3  * Copyright (C) 2020 Red Hat Inc
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "clutter-build-config.h"
20 
21 #include "clutter-damage-history.h"
22 
23 #define DAMAGE_HISTORY_LENGTH 0x10
24 
25 struct _ClutterDamageHistory
26 {
27   cairo_region_t *damages[DAMAGE_HISTORY_LENGTH];
28   int index;
29 };
30 
31 ClutterDamageHistory *
clutter_damage_history_new(void)32 clutter_damage_history_new (void)
33 {
34   ClutterDamageHistory *history;
35 
36   history = g_new0 (ClutterDamageHistory, 1);
37 
38   return history;
39 }
40 
41 void
clutter_damage_history_free(ClutterDamageHistory * history)42 clutter_damage_history_free (ClutterDamageHistory *history)
43 {
44   int i;
45 
46   for (i = 0; i < G_N_ELEMENTS (history->damages); i++)
47     g_clear_pointer (&history->damages[i], cairo_region_destroy);
48 
49   g_free (history);
50 }
51 
52 gboolean
clutter_damage_history_is_age_valid(ClutterDamageHistory * history,int age)53 clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
54                                      int                   age)
55 {
56   if (age >= DAMAGE_HISTORY_LENGTH ||
57       age < 1)
58     return FALSE;
59 
60   if (!clutter_damage_history_lookup (history, age))
61     return FALSE;
62 
63   return TRUE;
64 }
65 
66 void
clutter_damage_history_record(ClutterDamageHistory * history,const cairo_region_t * damage)67 clutter_damage_history_record (ClutterDamageHistory *history,
68                                const cairo_region_t *damage)
69 {
70   g_clear_pointer (&history->damages[history->index], cairo_region_destroy);
71   history->damages[history->index] = cairo_region_copy (damage);
72 }
73 
74 static inline int
step_damage_index(int current,int diff)75 step_damage_index (int current,
76                    int diff)
77 {
78   return (current + diff) & (DAMAGE_HISTORY_LENGTH - 1);
79 }
80 
81 void
clutter_damage_history_step(ClutterDamageHistory * history)82 clutter_damage_history_step (ClutterDamageHistory *history)
83 {
84   history->index = step_damage_index (history->index, 1);
85 }
86 
87 const cairo_region_t *
clutter_damage_history_lookup(ClutterDamageHistory * history,int age)88 clutter_damage_history_lookup (ClutterDamageHistory *history,
89                                int                   age)
90 {
91   return history->damages[step_damage_index (history->index, -age)];
92 }
93