ivi-shell: Fix crash due no transmitter screen
[AGL/meta-agl.git] / meta-agl-profile-graphical / recipes-graphics / wayland / weston / 0002-ivi-shell-Fix-crash-due-no-transmitter-screen.patch
1 From e1fd1c9fc08b9e1b8a2f2d958ce591bb8d256b84 Mon Sep 17 00:00:00 2001
2 From: Veeresh Kadasani <external.vkadasani@jp.adit-jv.com>
3 Date: Mon, 16 Dec 2019 19:24:15 +0900
4 Subject: [PATCH 1/1] ivi-shell: Fix crash due no transmitter screen
5
6 Registered the events for the output_created, destroyed,
7 resized events.So that the ivi_scrn can be destroyed,
8 created dynamically during destroyed and created events.
9 And the view properties are dynamically changed during
10 resized/moved events.
11
12 Signed-off-by: Veeresh Kadasani <external.vkadasani@jp.adit-jv.com>
13 ---
14  ivi-shell/ivi-layout-private.h |   5 ++
15  ivi-shell/ivi-layout.c         | 154 ++++++++++++++++++++++++++++++++++++-----
16  2 files changed, 140 insertions(+), 19 deletions(-)
17
18 diff --git a/ivi-shell/ivi-layout-private.h b/ivi-shell/ivi-layout-private.h
19 index c054130..8997edd 100644
20 --- a/ivi-shell/ivi-layout-private.h
21 +++ b/ivi-shell/ivi-layout-private.h
22 @@ -113,6 +113,11 @@ struct ivi_layout {
23  
24         struct ivi_layout_transition_set *transitions;
25         struct wl_list pending_transition_list; /* transition_node::link */
26 +
27 +       struct wl_listener output_created;
28 +       struct wl_listener output_destroyed;
29 +       struct wl_listener output_resized;
30 +       struct wl_listener output_moved;
31  };
32  
33  struct ivi_layout *get_instance(void);
34 diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
35 index 2c450f3..1fbfeeb 100644
36 --- a/ivi-shell/ivi-layout.c
37 +++ b/ivi-shell/ivi-layout.c
38 @@ -67,7 +67,7 @@
39  #include "ivi-layout-export.h"
40  #include "ivi-layout-private.h"
41  #include "ivi-layout-shell.h"
42 -
43 +#include "plugin-registry.h"
44  #include "shared/helpers.h"
45  #include "shared/os-compatibility.h"
46  
47 @@ -259,6 +259,87 @@ ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf)
48         free(ivisurf);
49  }
50  
51 +
52 +static void
53 +destroy_screen(struct ivi_layout_screen *iviscrn)
54 +{
55 +       struct ivi_layout_layer *ivilayer;
56 +       struct ivi_layout_layer *next;
57 +
58 +       /*we need to remove the layers from pending and order lists
59 +        *otherwise the memory will be corrupted during the
60 +        *wl_list_remove of pending.link or order.link from
61 +        *ivi_layout_screen_add_layer() or commit_screen_list()
62 +        *and on_screen has to be set as NULL otherwise the commit_changes()
63 +        *API will try to refer the freed iviscrn*/
64 +       wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) {
65 +               wl_list_remove(&ivilayer->pending.link);
66 +               wl_list_init(&ivilayer->pending.link);
67 +               ivilayer->on_screen = NULL;
68 +       }
69 +
70 +       wl_list_for_each_safe(ivilayer, next, &iviscrn->order.layer_list, order.link) {
71 +               wl_list_remove(&ivilayer->order.link);
72 +               wl_list_init(&ivilayer->order.link);
73 +               ivilayer->on_screen = NULL;
74 +       }
75 +
76 +       wl_list_init(&iviscrn->pending.layer_list);
77 +       wl_list_init(&iviscrn->order.layer_list);
78 +
79 +       wl_list_remove(&iviscrn->link);
80 +       free(iviscrn);
81 +}
82 +
83 +static void
84 +output_destroyed_event(struct wl_listener *listener, void *data)
85 +{
86 +       struct ivi_layout *layout =
87 +                       wl_container_of(listener, layout, output_destroyed);
88 +       struct ivi_layout_screen *iviscrn = NULL;
89 +       struct ivi_layout_screen *next = NULL;
90 +       struct weston_output *destroyed_output = (struct weston_output*)data;
91 +
92 +       wl_list_for_each_safe(iviscrn, next, &layout->screen_list, link) {
93 +               if (iviscrn->output == destroyed_output) {
94 +                       destroy_screen(iviscrn);
95 +               }
96 +       }
97 +       ivi_layout_commit_changes();
98 +}
99 +
100 +static void
101 +add_screen(struct weston_output *output)
102 +{
103 +       struct ivi_layout *layout = get_instance();
104 +       struct ivi_layout_screen *iviscrn = NULL;
105 +
106 +       if(!output)
107 +               return;
108 +
109 +       iviscrn = calloc(1, sizeof *iviscrn);
110 +       if (iviscrn == NULL) {
111 +               weston_log("fails to allocate memory\n");
112 +               return;
113 +       }
114 +
115 +       iviscrn->layout = layout;
116 +       iviscrn->output = output;
117 +
118 +       wl_list_init(&iviscrn->pending.layer_list);
119 +       wl_list_init(&iviscrn->order.layer_list);
120 +       wl_list_insert(&layout->screen_list, &iviscrn->link);
121 +}
122 +
123 +static void
124 +output_created_event(struct wl_listener *listener, void *data)
125 +{
126 +       struct weston_output *created_output = (struct weston_output*)data;
127 +
128 +       add_screen(created_output);
129 +       ivi_layout_commit_changes();
130 +}
131 +
132  /**
133   * Internal API to initialize ivi_screens found from output_list of weston_compositor.
134   * Called by ivi_layout_init_with_compositor.
135 @@ -266,27 +347,14 @@ ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf)
136  static void
137  create_screen(struct weston_compositor *ec)
138  {
139 +
140         struct ivi_layout *layout = get_instance();
141         struct ivi_layout_screen *iviscrn = NULL;
142 -       struct weston_output *output = NULL;
143 -
144 -       wl_list_for_each(output, &ec->output_list, link) {
145 -               iviscrn = calloc(1, sizeof *iviscrn);
146 -               if (iviscrn == NULL) {
147 -                       weston_log("fails to allocate memory\n");
148 -                       continue;
149 -               }
150  
151 -               iviscrn->layout = layout;
152 -
153 -               iviscrn->output = output;
154 -
155 -               wl_list_init(&iviscrn->pending.layer_list);
156 -
157 -               wl_list_init(&iviscrn->order.layer_list);
158 +       struct weston_output *output = NULL;
159  
160 -               wl_list_insert(&layout->screen_list, &iviscrn->link);
161 -       }
162 +       wl_list_for_each(output, &ec->output_list, link)
163 +               add_screen(output);
164  }
165  
166  /**
167 @@ -822,7 +890,18 @@ build_view_list(struct ivi_layout *layout)
168                 if (!ivi_view_is_mapped(ivi_view))
169                         weston_view_unmap(ivi_view->view);
170         }
171 +       struct weston_view *view = NULL;
172 +       struct weston_view *view_next = NULL;
173  
174 +       /* Earlier only the head node was reset, but the remaining links
175 +        * won't be changed. Due to this, faced crash issue (or sometimes
176 +        * list was looping) in weston_view_destroy API. So clearing the
177 +        * entire list*/
178 +       wl_list_for_each_safe(view, view_next,
179 +               &layout->layout_layer.view_list.link, layer_link.link) {
180 +               wl_list_remove(&view->layer_link.link);
181 +               wl_list_init(&view->layer_link.link);
182 +       }
183         /* Clear view list of layout ivi_layer */
184         wl_list_init(&layout->layout_layer.view_list.link);
185  
186 @@ -1791,7 +1870,22 @@ ivi_layout_commit_changes(void)
187  
188         return IVI_SUCCEEDED;
189  }
190 +static void
191 +output_resized_moved_events(struct wl_listener *listener, void *data)
192 +{
193 +       struct ivi_layout_screen *iviscrn = NULL;
194 +       struct ivi_layout_layer *ivilayer;
195 +       struct ivi_layout_view *ivi_view;
196 +       struct weston_output *output = (struct weston_output*)data;
197  
198 +       iviscrn = get_screen_from_output(output);
199 +
200 +       wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
201 +               wl_list_for_each(ivi_view, &ivilayer->order.view_list,
202 +                                order_link)
203 +                       update_prop(ivi_view);
204 +       }
205 +}
206  static int32_t
207  ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
208                                 enum ivi_layout_transition_type type,
209 @@ -1931,6 +2025,14 @@ surface_create(struct weston_surface *wl_surface, uint32_t id_surface)
210                 return NULL;
211         }
212  
213 +       ivisurf = get_surface(&layout->surface_list, id_surface);
214 +       if (ivisurf != NULL) {
215 +               if (ivisurf->surface != NULL) {
216 +                       weston_log("id_surface(%d) is already created\n", id_surface);
217 +                       return NULL;
218 +               }
219 +       }
220 +
221         ivisurf = calloc(1, sizeof *ivisurf);
222         if (ivisurf == NULL) {
223                 weston_log("fails to allocate memory\n");
224 @@ -1954,6 +2056,8 @@ surface_create(struct weston_surface *wl_surface, uint32_t id_surface)
225  
226         wl_list_insert(&layout->surface_list, &ivisurf->link);
227  
228 +       wl_signal_emit(&layout->surface_notification.created, ivisurf);
229 +
230         return ivisurf;
231  }
232  
233 @@ -2006,8 +2110,8 @@ ivi_layout_surface_create(struct weston_surface *wl_surface,
234         return ivisurf;
235  }
236  
237 -static struct ivi_layout_interface ivi_layout_interface;
238  
239 +static struct ivi_layout_interface ivi_layout_interface;
240  void
241  ivi_layout_init_with_compositor(struct weston_compositor *ec)
242  {
243 @@ -2035,6 +2139,18 @@ ivi_layout_init_with_compositor(struct weston_compositor *ec)
244  
245         create_screen(ec);
246  
247 +       layout->output_created.notify = output_created_event;
248 +       wl_signal_add(&ec->output_created_signal, &layout->output_created);
249 +
250 +       layout->output_destroyed.notify = output_destroyed_event;
251 +       wl_signal_add(&ec->output_destroyed_signal, &layout->output_destroyed);
252 +
253 +       layout->output_resized.notify = output_resized_moved_events;
254 +       wl_signal_add(&ec->output_resized_signal, &layout->output_resized);
255 +
256 +       layout->output_moved.notify = output_resized_moved_events;
257 +       wl_signal_add(&ec->output_moved_signal, &layout->output_moved);
258 +
259         layout->transitions = ivi_layout_transition_set_create(ec);
260         wl_list_init(&layout->pending_transition_list);
261  
262 -- 
263 2.7.4
264