]> code.ossystems Code Review - meta-freescale.git/blob
8201459c08dbce121fbed138469554615179a117
[meta-freescale.git] /
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