diff options
Diffstat (limited to 'recipes-graphics/wayland/weston/0006-MGS-389-Fix-for-wrong-FPS-throttling-when-multibuffe.patch')
-rw-r--r-- | recipes-graphics/wayland/weston/0006-MGS-389-Fix-for-wrong-FPS-throttling-when-multibuffe.patch | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/recipes-graphics/wayland/weston/0006-MGS-389-Fix-for-wrong-FPS-throttling-when-multibuffe.patch b/recipes-graphics/wayland/weston/0006-MGS-389-Fix-for-wrong-FPS-throttling-when-multibuffe.patch new file mode 100644 index 0000000..8201459 --- /dev/null +++ b/recipes-graphics/wayland/weston/0006-MGS-389-Fix-for-wrong-FPS-throttling-when-multibuffe.patch | |||
@@ -0,0 +1,247 @@ | |||
1 | From db720086b85046bd0806484bfe63915870bb4323 Mon Sep 17 00:00:00 2001 | ||
2 | From: Prabhu Sundararaj <prabhu.sundararaj@freescale.com> | ||
3 | Date: Tue, 30 Dec 2014 16:09:29 -0600 | ||
4 | Subject: [PATCH] MGS-389 - Fix for wrong FPS throttling when multibuffer is | ||
5 | set | ||
6 | Organization: O.S. Systems Software LTDA. | ||
7 | |||
8 | When the FB_MULTI_BUFFER=2 is set, throtling to 30FPS for a 60Hz display | ||
9 | which is suppose to have 60FPS. | ||
10 | Adding worker thread to output the frame in async mode for better | ||
11 | performance. | ||
12 | |||
13 | Upstream-Status: Pending | ||
14 | |||
15 | Signed-off-by: Prabhu Sundararaj <prabhu.sundararaj@freescale.com> | ||
16 | --- | ||
17 | src/gal2d-renderer.c | 109 +++++++++++++++++++++++++++++++++++++++------------ | ||
18 | 1 file changed, 83 insertions(+), 26 deletions(-) | ||
19 | |||
20 | diff --git a/src/gal2d-renderer.c b/src/gal2d-renderer.c | ||
21 | index fbe39f6..4cccaf1 100644 | ||
22 | --- a/src/gal2d-renderer.c | ||
23 | +++ b/src/gal2d-renderer.c | ||
24 | @@ -28,6 +28,8 @@ | ||
25 | #include <ctype.h> | ||
26 | #include <float.h> | ||
27 | #include <assert.h> | ||
28 | +#include <pthread.h> | ||
29 | + | ||
30 | #include "compositor.h" | ||
31 | #include "gal2d-renderer.h" | ||
32 | #include "vertex-clipping.h" | ||
33 | @@ -37,7 +39,6 @@ | ||
34 | |||
35 | #define galONERROR(x) if(status < 0) printf("Error in function %s\n", __func__); | ||
36 | |||
37 | - | ||
38 | struct gal2d_output_state { | ||
39 | |||
40 | int current_buffer; | ||
41 | @@ -48,7 +49,12 @@ struct gal2d_output_state { | ||
42 | int activebuffer; | ||
43 | gcoSURF offscreenSurface; | ||
44 | gceSURF_FORMAT format; | ||
45 | - gcoSURF tempSurf; | ||
46 | + pthread_mutex_t workerMutex; | ||
47 | + pthread_t workerId; | ||
48 | + gctUINT32 exitWorker; | ||
49 | + gctSIGNAL signal; | ||
50 | + gctSIGNAL busySignal; | ||
51 | + gcsHAL_INTERFACE iface; | ||
52 | }; | ||
53 | |||
54 | struct gal2d_surface_state { | ||
55 | @@ -373,8 +379,7 @@ gal2d_clear(struct weston_output *base) | ||
56 | gcmONERROR(gco2D_SetSource(gr->gcoEngine2d, &dstRect)); | ||
57 | gcmONERROR(gco2D_SetClipping(gr->gcoEngine2d, &dstRect)); | ||
58 | gcmONERROR(gco2D_Clear(gr->gcoEngine2d, 1, &dstRect, 0xff0000ff, 0xCC, 0xCC, go->format)); | ||
59 | - | ||
60 | - gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvFALSE)); | ||
61 | + gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvTRUE)); | ||
62 | |||
63 | OnError: | ||
64 | galONERROR(status); | ||
65 | @@ -465,7 +470,6 @@ gal2dBindBuffer(struct weston_surface* es) | ||
66 | static void | ||
67 | gal2d_flip_surface(struct weston_output *output) | ||
68 | { | ||
69 | - struct gal2d_renderer *gr = get_renderer(output->compositor); | ||
70 | struct gal2d_output_state *go = get_output_state(output); | ||
71 | |||
72 | if(go->nNumBuffers > 1) | ||
73 | @@ -473,17 +477,36 @@ gal2d_flip_surface(struct weston_output *output) | ||
74 | gctUINT Offset; | ||
75 | gctINT X; | ||
76 | gctINT Y; | ||
77 | - gcmVERIFY_OK(gcoHAL_Commit(gr->gcoHal, gcvTRUE)); | ||
78 | - | ||
79 | + | ||
80 | gcmVERIFY_OK(gcoOS_GetDisplayBackbuffer(go->display, gcvNULL, | ||
81 | gcvNULL, gcvNULL, &Offset, &X, &Y)); | ||
82 | |||
83 | gcmVERIFY_OK(gcoOS_SetDisplayVirtual(go->display, gcvNULL, | ||
84 | - Offset, X, Y)); | ||
85 | - | ||
86 | - go->activebuffer = (go->activebuffer+1) % go->nNumBuffers; | ||
87 | + Offset, X, Y)); | ||
88 | } | ||
89 | } | ||
90 | +static void *gal2d_output_worker(void *arg) | ||
91 | +{ | ||
92 | + struct weston_output *output = (struct weston_output *)arg; | ||
93 | + struct gal2d_output_state *go = get_output_state(output); | ||
94 | + | ||
95 | + while(1) | ||
96 | + { | ||
97 | + if(gcoOS_WaitSignal(gcvNULL, go->signal, gcvINFINITE) == gcvSTATUS_OK ) | ||
98 | + { | ||
99 | + gal2d_flip_surface(output); | ||
100 | + gcoOS_Signal(gcvNULL,go->busySignal, gcvTRUE); | ||
101 | + } | ||
102 | + pthread_mutex_lock(&go->workerMutex); | ||
103 | + if(go->exitWorker == 1) | ||
104 | + { | ||
105 | + pthread_mutex_unlock(&go->workerMutex); | ||
106 | + break; | ||
107 | + } | ||
108 | + pthread_mutex_unlock(&go->workerMutex); | ||
109 | + } | ||
110 | + return 0; | ||
111 | +} | ||
112 | |||
113 | static int | ||
114 | update_surface(struct weston_output *output) | ||
115 | @@ -520,11 +543,13 @@ update_surface(struct weston_output *output) | ||
116 | gcmONERROR(gco2D_SetClipping(gr->gcoEngine2d, &dstRect)); | ||
117 | gcmONERROR(gco2D_Blit(gr->gcoEngine2d, 1, &dstRect, 0xCC, 0xCC, go->format)); | ||
118 | gcmONERROR(gcoSURF_Unlock(srcSurface, (gctPOINTER *)&va)); | ||
119 | - gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvFALSE)); | ||
120 | + gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvFALSE)); | ||
121 | } | ||
122 | - | ||
123 | - gal2d_flip_surface(output); | ||
124 | - | ||
125 | + else if(go->nNumBuffers > 1) | ||
126 | + { | ||
127 | + gcoHAL_ScheduleEvent(gr->gcoHal, &go->iface); | ||
128 | + gcmVERIFY_OK(gcoHAL_Commit(gr->gcoHal, gcvFALSE)); | ||
129 | + } | ||
130 | OnError: | ||
131 | galONERROR(status); | ||
132 | return status; | ||
133 | @@ -746,6 +771,7 @@ repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2 | ||
134 | 0xCC, 0xCC, go->format)); | ||
135 | } | ||
136 | } | ||
137 | + | ||
138 | if(status < 0) | ||
139 | { | ||
140 | printf("cr l=%d r=%d t=%d b=%d w=%d h=%d\n", | ||
141 | @@ -759,12 +785,6 @@ repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2 | ||
142 | goto OnError; | ||
143 | } | ||
144 | } | ||
145 | - status = (gcoHAL_Commit(gr->gcoHal, gcvFALSE)); | ||
146 | - if(status < 0) | ||
147 | - { | ||
148 | - printf("Error in gcoHAL_Commit %s\n", __func__); | ||
149 | - goto OnError; | ||
150 | - } | ||
151 | } | ||
152 | |||
153 | OnError: | ||
154 | @@ -831,7 +851,15 @@ repaint_views(struct weston_output *output, pixman_region32_t *damage) | ||
155 | { | ||
156 | struct weston_compositor *compositor = output->compositor; | ||
157 | struct weston_view *view; | ||
158 | - | ||
159 | + struct gal2d_output_state *go = get_output_state(output); | ||
160 | + | ||
161 | + if(go->nNumBuffers > 1) | ||
162 | + { | ||
163 | + /*500ms is more than enough to process a frame */ | ||
164 | + gcoOS_WaitSignal(gcvNULL, go->busySignal, 500); | ||
165 | + } | ||
166 | + go->activebuffer = (go->activebuffer+1) % go->nNumBuffers; | ||
167 | + | ||
168 | wl_list_for_each_reverse(view, &compositor->view_list, link) | ||
169 | if (view->plane == &compositor->primary_plane) | ||
170 | draw_view(view, output, damage); | ||
171 | @@ -1090,12 +1118,19 @@ gal2d_renderer_output_destroy(struct weston_output *output) | ||
172 | if(go->offscreenSurface) | ||
173 | gcmVERIFY_OK(gcoSURF_Destroy(go->offscreenSurface)); | ||
174 | } | ||
175 | - | ||
176 | + else | ||
177 | + { | ||
178 | + gcoOS_Signal(gcvNULL,go->signal, gcvTRUE); | ||
179 | + pthread_mutex_lock(&go->workerMutex); | ||
180 | + go->exitWorker = 1; | ||
181 | + pthread_mutex_unlock(&go->workerMutex); | ||
182 | + pthread_join(go->workerId, NULL); | ||
183 | + } | ||
184 | + | ||
185 | for(i=0; i < go->nNumBuffers; i++) | ||
186 | { | ||
187 | gcmVERIFY_OK(gcoSURF_Destroy(go->renderSurf[i])); | ||
188 | } | ||
189 | - | ||
190 | free(go->renderSurf); | ||
191 | go->renderSurf = gcvNULL; | ||
192 | |||
193 | @@ -1182,9 +1217,28 @@ gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType dis | ||
194 | |||
195 | go->renderSurf = malloc(sizeof(gcoSURF) * go->nNumBuffers); | ||
196 | gcoOS_GetDisplayVirtual(go->display, &width, &height); | ||
197 | + gcoOS_SetSwapInterval(go->display, 1); | ||
198 | + | ||
199 | + /*Needed only for multi Buffer */ | ||
200 | + if(go->nNumBuffers > 1) | ||
201 | + { | ||
202 | + gcmVERIFY_OK(gcoOS_CreateSignal(gcvNULL, gcvFALSE, | ||
203 | + &go->signal)); | ||
204 | + gcmVERIFY_OK(gcoOS_CreateSignal(gcvNULL, gcvFALSE, | ||
205 | + &go->busySignal)); | ||
206 | + | ||
207 | + go->iface.command = gcvHAL_SIGNAL; | ||
208 | + go->iface.u.Signal.signal = gcmPTR_TO_UINT64(go->signal); | ||
209 | + go->iface.u.Signal.auxSignal = 0; | ||
210 | + go->iface.u.Signal.process = gcmPTR_TO_UINT64(gcoOS_GetCurrentProcessID()); | ||
211 | + go->iface.u.Signal.fromWhere = gcvKERNEL_PIXEL; | ||
212 | + | ||
213 | + go->exitWorker = 0; | ||
214 | + pthread_create(&go->workerId, NULL, gal2d_output_worker, output); | ||
215 | + pthread_mutex_init(&go->workerMutex, gcvNULL); | ||
216 | + } | ||
217 | for(i=0; i < go->nNumBuffers; i++) | ||
218 | { | ||
219 | - | ||
220 | gcmONERROR(gcoSURF_Construct(gr->gcoHal, info.width, info.height, 1, | ||
221 | gcvSURF_BITMAP, go->format, gcvPOOL_USER, &go->renderSurf[i])); | ||
222 | |||
223 | @@ -1200,7 +1254,7 @@ gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType dis | ||
224 | go->activebuffer = 0; | ||
225 | else | ||
226 | go->activebuffer = 1; | ||
227 | - | ||
228 | + | ||
229 | if(go->nNumBuffers <= 1 ) | ||
230 | { | ||
231 | gcmVERIFY_OK(gcoSURF_Construct(gr->gcoHal, | ||
232 | @@ -1213,8 +1267,11 @@ gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType dis | ||
233 | &go->offscreenSurface)); | ||
234 | make_current(gr, go->offscreenSurface); | ||
235 | gal2d_clear(output); | ||
236 | - gal2d_flip_surface(output); | ||
237 | } | ||
238 | + else | ||
239 | + { | ||
240 | + gcoOS_Signal(gcvNULL,go->busySignal, gcvTRUE); | ||
241 | + } | ||
242 | |||
243 | for (i = 0; i < 2; i++) | ||
244 | pixman_region32_init(&go->buffer_damage[i]); | ||
245 | -- | ||
246 | 2.1.4 | ||
247 | |||