summaryrefslogtreecommitdiffstats
path: root/recipes-graphics/wayland/weston/0002-MGS-1111-Add-GPU-VIV-suport-for-wayland-and-weston-1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-graphics/wayland/weston/0002-MGS-1111-Add-GPU-VIV-suport-for-wayland-and-weston-1.patch')
-rw-r--r--recipes-graphics/wayland/weston/0002-MGS-1111-Add-GPU-VIV-suport-for-wayland-and-weston-1.patch1708
1 files changed, 0 insertions, 1708 deletions
diff --git a/recipes-graphics/wayland/weston/0002-MGS-1111-Add-GPU-VIV-suport-for-wayland-and-weston-1.patch b/recipes-graphics/wayland/weston/0002-MGS-1111-Add-GPU-VIV-suport-for-wayland-and-weston-1.patch
deleted file mode 100644
index cfe8f605..00000000
--- a/recipes-graphics/wayland/weston/0002-MGS-1111-Add-GPU-VIV-suport-for-wayland-and-weston-1.patch
+++ /dev/null
@@ -1,1708 +0,0 @@
1From e766967ae24d15048c01d03de09fc39757d13ec3 Mon Sep 17 00:00:00 2001
2From: Prabhu <prabhu.sundararaj@freescale.com>
3Date: Sat, 3 Oct 2015 19:44:33 -0500
4Subject: [PATCH] MGS-1111: Add GPU-VIV suport for wayland and weston 1.9
5
6Add support GPU-VIV support for weston 1.9
7
8Signed-off-by: Prabhu <prabhu.sundararaj@freescale.com>
9---
10 Makefile.am | 12 +
11 src/compositor-fbdev.c | 128 ++++-
12 src/gal2d-renderer.c | 1342 ++++++++++++++++++++++++++++++++++++++++++++++++
13 src/gal2d-renderer.h | 50 ++
14 4 files changed, 1519 insertions(+), 13 deletions(-)
15 create mode 100644 src/gal2d-renderer.c
16 create mode 100644 src/gal2d-renderer.h
17
18Index: weston-1.11.1/Makefile.am
19===================================================================
20--- weston-1.11.1.orig/Makefile.am 2016-09-20 19:35:22.000000000 -0500
21+++ weston-1.11.1/Makefile.am 2017-01-14 08:35:10.000000000 -0600
22@@ -247,6 +247,18 @@
23 src/vertex-clipping.h \
24 shared/helpers.h
25 endif
26+module_LTLIBRARIES += gal2d-renderer.la
27+gal2d_renderer_la_LDFLAGS = -module -avoid-version
28+gal2d_renderer_la_LIBADD = $(COMPOSITOR_LIBS) $(EGL_LIBS)
29+gal2d_renderer_la_CFLAGS = \
30+ $(COMPOSITOR_CFLAGS) \
31+ $(EGL_CFLAGS) \
32+ $(GCC_CFLAGS)
33+gal2d_renderer_la_SOURCES = \
34+ src/gal2d-renderer.h \
35+ src/gal2d-renderer.c \
36+ src/vertex-clipping.c \
37+ src/vertex-clipping.h
38
39 if ENABLE_X11_COMPOSITOR
40 module_LTLIBRARIES += x11-backend.la
41Index: weston-1.11.1/src/compositor-fbdev.c
42===================================================================
43--- weston-1.11.1.orig/src/compositor-fbdev.c 2016-09-20 19:35:22.000000000 -0500
44+++ weston-1.11.1/src/compositor-fbdev.c 2017-01-14 08:35:11.000000000 -0600
45@@ -50,6 +50,7 @@
46 #include "libinput-seat.h"
47 #include "gl-renderer.h"
48 #include "presentation-time-server-protocol.h"
49+#include "gal2d-renderer.h"
50
51 struct fbdev_backend {
52 struct weston_backend base;
53@@ -59,8 +60,10 @@
54 struct udev *udev;
55 struct udev_input input;
56 int use_pixman;
57+ int use_gal2d;
58 uint32_t output_transform;
59 struct wl_listener session_listener;
60+ NativeDisplayType display;
61 };
62
63 struct fbdev_screeninfo {
64@@ -93,9 +96,13 @@
65 /* pixman details. */
66 pixman_image_t *hw_surface;
67 uint8_t depth;
68+
69+ NativeDisplayType display;
70+ NativeWindowType window;
71 };
72
73 struct gl_renderer_interface *gl_renderer;
74+struct gal2d_renderer_interface *gal2d_renderer;
75
76 static const char default_seat[] = "seat0";
77
78@@ -443,6 +450,10 @@
79 strerror(errno));
80
81 output->fb = NULL;
82+ if(output->window)
83+ fbDestroyWindow(output->window);
84+ if(output->display)
85+ fbDestroyDisplay(output->display);
86 }
87
88 static void fbdev_output_destroy(struct weston_output *base);
89@@ -450,13 +461,13 @@
90
91 static int
92 fbdev_output_create(struct fbdev_backend *backend,
93- const char *device)
94+ int x, int y, const char *device)
95 {
96 struct fbdev_output *output;
97 int fb_fd;
98 struct wl_event_loop *loop;
99
100- weston_log("Creating fbdev output.\n");
101+ weston_log("Creating fbdev output. %s x=%d y=%d\n", device, x, y);
102
103 output = zalloc(sizeof *output);
104 if (output == NULL)
105@@ -500,7 +511,7 @@
106 output->base.name = strdup("fbdev");
107
108 weston_output_init(&output->base, backend->compositor,
109- 0, 0, output->fb_info.width_mm,
110+ x, y, output->fb_info.width_mm,
111 output->fb_info.height_mm,
112 backend->output_transform,
113 1);
114@@ -508,10 +519,39 @@
115 if (backend->use_pixman) {
116 if (pixman_renderer_output_create(&output->base) < 0)
117 goto out_hw_surface;
118+ } else if(backend->use_gal2d) {
119+
120+ char* fbenv = getenv("FB_FRAMEBUFFER_0");
121+ setenv("FB_FRAMEBUFFER_0", device, 1);
122+ output->display = fbGetDisplay(backend->compositor->wl_display);
123+ if (output->display == NULL) {
124+ fprintf(stderr, "failed to get display\n");
125+ return 0;
126+ }
127+
128+ output->window = fbCreateWindow(output->display, -1, -1, 0, 0);
129+ if (output->window == NULL) {
130+ fprintf(stderr, "failed to create window\n");
131+ return 0;
132+ }
133+ setenv("FB_FRAMEBUFFER_0", fbenv, 1);
134+
135+ if (gal2d_renderer->output_create(&output->base,
136+ output->display,
137+ (NativeWindowType)output->window) < 0) {
138+ weston_log("gal_renderer_output_create failed.\n");
139+ goto out_hw_surface;
140+ }
141+
142 } else {
143 setenv("HYBRIS_EGLPLATFORM", "wayland", 1);
144+ output->window = fbCreateWindow(backend->display, -1, -1, 0, 0);
145+ if (output->window == NULL) {
146+ fprintf(stderr, "failed to create window\n");
147+ return 0;
148+ }
149 if (gl_renderer->output_create(&output->base,
150- (EGLNativeWindowType)NULL, NULL,
151+ (EGLNativeWindowType)output->window, NULL,
152 gl_renderer->opaque_attribs,
153 NULL, 0) < 0) {
154 weston_log("gl_renderer_output_create failed.\n");
155@@ -558,6 +598,8 @@
156 if (backend->use_pixman) {
157 if (base->renderer_state != NULL)
158 pixman_renderer_output_destroy(base);
159+ } else if (backend->use_gal2d) {
160+ gal2d_renderer->output_destroy(base);
161 } else {
162 gl_renderer->output_destroy(base);
163 }
164@@ -622,7 +664,7 @@
165 * are re-initialised. */
166 device = strdup(output->device);
167 fbdev_output_destroy(&output->base);
168- fbdev_output_create(backend, device);
169+ fbdev_output_create(backend, 0, 0, device);
170 free(device);
171
172 return 0;
173@@ -777,7 +819,50 @@
174 if (backend->use_pixman) {
175 if (pixman_renderer_init(compositor) < 0)
176 goto out_launcher;
177- } else {
178+ }
179+ else if (backend->use_gal2d) {
180+ int x = 0, y = 0;
181+ int i=0;
182+ int count = 0;
183+ int k=0, dispCount = 0;
184+ char displays[5][32];
185+ gal2d_renderer = weston_load_module("gal2d-renderer.so",
186+ "gal2d_renderer_interface");
187+ if (!gal2d_renderer) {
188+ weston_log("could not load gal2d renderer\n");
189+ goto out_launcher;
190+ }
191+
192+ if (gal2d_renderer->create(backend->compositor) < 0) {
193+ weston_log("gal2d_renderer_create failed.\n");
194+ goto out_launcher;
195+ }
196+
197+ weston_log("param->device=%s\n",param->device);
198+ count = strlen(param->device);
199+
200+ for(i= 0; i < count; i++) {
201+ if(param->device[i] == ',') {
202+ displays[dispCount][k] = '\0';
203+ dispCount++;
204+ k = 0;
205+ continue;
206+ }
207+ displays[dispCount][k++] = param->device[i];
208+ }
209+ displays[dispCount][k] = '\0';
210+ dispCount++;
211+
212+ for(i=0; i<dispCount; i++)
213+ {
214+ if (fbdev_output_create(backend, x, y, displays[i]) < 0)
215+ goto out_launcher;
216+ x += container_of(backend->compositor->output_list.prev,
217+ struct weston_output,
218+ link)->width;
219+ }
220+ }
221+ else {
222 gl_renderer = weston_load_module("gl-renderer.so",
223 "gl_renderer_interface");
224 if (!gl_renderer) {
225@@ -785,17 +870,22 @@
226 goto out_launcher;
227 }
228
229+ backend->display = fbGetDisplay(backend->compositor->wl_display);
230+ if (backend->display == NULL) {
231+ weston_log("fbGetDisplay failed.\n");
232+ goto out_launcher;
233+ }
234 if (gl_renderer->create(compositor, NO_EGL_PLATFORM,
235- EGL_DEFAULT_DISPLAY,
236+ backend->display,
237 gl_renderer->opaque_attribs,
238 NULL, 0) < 0) {
239 weston_log("gl_renderer_create failed.\n");
240 goto out_launcher;
241 }
242 }
243-
244- if (fbdev_output_create(backend, param->device) < 0)
245- goto out_launcher;
246+ if(!backend->use_gal2d)
247+ if (fbdev_output_create(backend, 0, 0, param->device) < 0)
248+ goto out_launcher;
249
250 udev_input_init(&backend->input, compositor, backend->udev, seat_id);
251
252@@ -822,7 +912,13 @@
253 * udev, rather than passing a device node in as a parameter. */
254 config->tty = 0; /* default to current tty */
255 config->device = "/dev/fb0"; /* default frame buffer */
256+#ifdef ENABLE_EGL
257+ config->use_gl = 1;
258+ config->use_gal2d = 0;
259+#else
260 config->use_gl = 0;
261+ config->use_gal2d = 1;
262+#endif
263 config->output_transform = WL_OUTPUT_TRANSFORM_NORMAL;
264 }
265
266Index: weston-1.11.1/src/gal2d-renderer.c
267===================================================================
268--- /dev/null 1970-01-01 00:00:00.000000000 +0000
269+++ weston-1.11.1/src/gal2d-renderer.c 2017-01-14 08:35:10.000000000 -0600
270@@ -0,0 +1,1342 @@
271+/*
272+ * Copyright (c) 2015 Freescale Semiconductor, Inc.
273+ * Copyright © 2012 Intel Corporation
274+ * Copyright © 2015 Collabora, Ltd.
275+ *
276+ * Permission is hereby granted, free of charge, to any person obtaining
277+ * a copy of this software and associated documentation files (the
278+ * "Software"), to deal in the Software without restriction, including
279+ * without limitation the rights to use, copy, modify, merge, publish,
280+ * distribute, sublicense, and/or sell copies of the Software, and to
281+ * permit persons to whom the Software is furnished to do so, subject to
282+ * the following conditions:
283+ *
284+ * The above copyright notice and this permission notice (including the
285+ * next paragraph) shall be included in all copies or substantial
286+ * portions of the Software.
287+ *
288+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
289+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
290+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
291+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
292+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
293+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
294+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
295+ * SOFTWARE.
296+ */
297+
298+#define _GNU_SOURCE
299+
300+#include <stdlib.h>
301+#include <string.h>
302+#include <ctype.h>
303+#include <float.h>
304+#include <assert.h>
305+#include <pthread.h>
306+
307+#include "compositor.h"
308+#include "gal2d-renderer.h"
309+#include "vertex-clipping.h"
310+#include "shared/helpers.h"
311+#include "HAL/gc_hal.h"
312+#include "HAL/gc_hal_raster.h"
313+#include "HAL/gc_hal_eglplatform.h"
314+
315+#define galONERROR(x) if(status < 0) printf("Error in function %s\n", __func__);
316+
317+struct gal2d_output_state {
318+
319+ int current_buffer;
320+ pixman_region32_t buffer_damage[2];
321+ NativeDisplayType display;
322+ gcoSURF* renderSurf;
323+ gctUINT32 nNumBuffers;
324+ int activebuffer;
325+ gcoSURF offscreenSurface;
326+ gceSURF_FORMAT format;
327+ pthread_mutex_t workerMutex;
328+ pthread_t workerId;
329+ gctUINT32 exitWorker;
330+ gctSIGNAL signal;
331+ gctSIGNAL busySignal;
332+ gcsHAL_INTERFACE iface;
333+ int directBlit;
334+ gctINT width;
335+ gctINT height;
336+};
337+
338+struct gal2d_surface_state {
339+ float color[4];
340+ struct weston_buffer_reference buffer_ref;
341+ int pitch; /* in pixels */
342+ pixman_region32_t texture_damage;
343+ gcoSURF gco_Surface;
344+
345+ struct weston_surface *surface;
346+ struct wl_listener surface_destroy_listener;
347+ struct wl_listener renderer_destroy_listener;
348+};
349+
350+struct gal2d_renderer {
351+ struct weston_renderer base;
352+ struct wl_signal destroy_signal;
353+ gcoOS gcos;
354+ gcoHAL gcoHal;
355+ gco2D gcoEngine2d;
356+ gctPOINTER localInfo;
357+};
358+
359+static int
360+gal2d_renderer_create_surface(struct weston_surface *surface);
361+
362+static inline struct gal2d_surface_state *
363+get_surface_state(struct weston_surface *surface)
364+{
365+ if (!surface->renderer_state)
366+ gal2d_renderer_create_surface(surface);
367+ return (struct gal2d_surface_state *)surface->renderer_state;
368+}
369+
370+static inline struct gal2d_renderer *
371+get_renderer(struct weston_compositor *ec)
372+{
373+ return (struct gal2d_renderer *)ec->renderer;
374+}
375+
376+
377+
378+#define max(a, b) (((a) > (b)) ? (a) : (b))
379+#define min(a, b) (((a) > (b)) ? (b) : (a))
380+/*
381+ * Compute the boundary vertices of the intersection of the global coordinate
382+ * aligned rectangle 'rect', and an arbitrary quadrilateral produced from
383+ * 'surf_rect' when transformed from surface coordinates into global coordinates.
384+ * The vertices are written to 'ex' and 'ey', and the return value is the
385+ * number of vertices. Vertices are produced in clockwise winding order.
386+ * Guarantees to produce either zero vertices, or 3-8 vertices with non-zero
387+ * polygon area.
388+ */
389+static int
390+calculate_edges(struct weston_view *ev, pixman_box32_t *rect,
391+ pixman_box32_t *surf_rect, float *ex, float *ey)
392+{
393+
394+ struct clip_context ctx;
395+ int i, n;
396+ float min_x, max_x, min_y, max_y;
397+ struct polygon8 surf = {
398+ { surf_rect->x1, surf_rect->x2, surf_rect->x2, surf_rect->x1 },
399+ { surf_rect->y1, surf_rect->y1, surf_rect->y2, surf_rect->y2 },
400+ 4
401+ };
402+
403+ ctx.clip.x1 = rect->x1;
404+ ctx.clip.y1 = rect->y1;
405+ ctx.clip.x2 = rect->x2;
406+ ctx.clip.y2 = rect->y2;
407+
408+ /* transform surface to screen space: */
409+ for (i = 0; i < surf.n; i++)
410+ weston_view_to_global_float(ev, surf.x[i], surf.y[i],
411+ &surf.x[i], &surf.y[i]);
412+
413+ /* find bounding box: */
414+ min_x = max_x = surf.x[0];
415+ min_y = max_y = surf.y[0];
416+
417+ for (i = 1; i < surf.n; i++) {
418+ min_x = min(min_x, surf.x[i]);
419+ max_x = max(max_x, surf.x[i]);
420+ min_y = min(min_y, surf.y[i]);
421+ max_y = max(max_y, surf.y[i]);
422+ }
423+
424+ /* First, simple bounding box check to discard early transformed
425+ * surface rects that do not intersect with the clip region:
426+ */
427+ if ((min_x >= ctx.clip.x2) || (max_x <= ctx.clip.x1) ||
428+ (min_y >= ctx.clip.y2) || (max_y <= ctx.clip.y1))
429+ return 0;
430+
431+ /* Simple case, bounding box edges are parallel to surface edges,
432+ * there will be only four edges. We just need to clip the surface
433+ * vertices to the clip rect bounds:
434+ */
435+ if (!ev->transform.enabled)
436+ return clip_simple(&ctx, &surf, ex, ey);
437+
438+ /* Transformed case: use a general polygon clipping algorithm to
439+ * clip the surface rectangle with each side of 'rect'.
440+ * The algorithm is Sutherland-Hodgman, as explained in
441+ * http://www.codeguru.com/cpp/misc/misc/graphics/article.php/c8965/Polygon-Clipping.htm
442+ * but without looking at any of that code.
443+ */
444+ n = clip_transformed(&ctx, &surf, ex, ey);
445+
446+ if (n < 3)
447+ return 0;
448+
449+ return n;
450+}
451+
452+
453+static inline struct gal2d_output_state *
454+get_output_state(struct weston_output *output)
455+{
456+ return (struct gal2d_output_state *)output->renderer_state;
457+}
458+
459+static gctUINT32
460+galGetStretchFactor(gctINT32 SrcSize, gctINT32 DestSize)
461+{
462+ gctUINT stretchFactor;
463+ if ( (SrcSize > 0) && (DestSize > 1) )
464+ {
465+ stretchFactor = ((SrcSize - 1) << 16) / (DestSize - 1);
466+ }
467+ else
468+ {
469+ stretchFactor = 0;
470+ }
471+ return stretchFactor;
472+}
473+
474+static gceSTATUS
475+galGetStretchFactors(
476+ IN gcsRECT_PTR SrcRect,
477+ IN gcsRECT_PTR DestRect,
478+ OUT gctUINT32 * HorFactor,
479+ OUT gctUINT32 * VerFactor
480+ )
481+{
482+ if (HorFactor != gcvNULL)
483+ {
484+ gctINT32 src, dest;
485+
486+ /* Compute width of rectangles. */
487+ gcmVERIFY_OK(gcsRECT_Width(SrcRect, &src));
488+ gcmVERIFY_OK(gcsRECT_Width(DestRect, &dest));
489+
490+ /* Compute and return horizontal stretch factor. */
491+ *HorFactor = galGetStretchFactor(src, dest);
492+ }
493+
494+ if (VerFactor != gcvNULL)
495+ {
496+ gctINT32 src, dest;
497+
498+ /* Compute height of rectangles. */
499+ gcmVERIFY_OK(gcsRECT_Height(SrcRect, &src));
500+ gcmVERIFY_OK(gcsRECT_Height(DestRect, &dest));
501+
502+ /* Compute and return vertical stretch factor. */
503+ *VerFactor = galGetStretchFactor(src, dest);
504+ }
505+ /* Success. */
506+ return gcvSTATUS_OK;
507+}
508+
509+static gceSTATUS
510+gal2d_getSurfaceFormat(halDISPLAY_INFO info, gceSURF_FORMAT * Format)
511+{
512+ /* Get the color format. */
513+ switch (info.greenLength)
514+ {
515+ case 4:
516+ if (info.blueOffset == 0)
517+ {
518+ *Format = (info.alphaLength == 0) ? gcvSURF_X4R4G4B4 : gcvSURF_A4R4G4B4;
519+ }
520+ else
521+ {
522+ *Format = (info.alphaLength == 0) ? gcvSURF_X4B4G4R4 : gcvSURF_A4B4G4R4;
523+ }
524+ break;
525+
526+ case 5:
527+ if (info.blueOffset == 0)
528+ {
529+ *Format = (info.alphaLength == 0) ? gcvSURF_X1R5G5B5 : gcvSURF_A1R5G5B5;
530+ }
531+ else
532+ {
533+ *Format = (info.alphaLength == 0) ? gcvSURF_X1B5G5R5 : gcvSURF_A1B5G5R5;
534+ }
535+ break;
536+
537+ case 6:
538+ *Format = gcvSURF_R5G6B5;
539+ break;
540+
541+ case 8:
542+ if (info.blueOffset == 0)
543+ {
544+ *Format = (info.alphaLength == 0) ? gcvSURF_X8R8G8B8 : gcvSURF_A8R8G8B8;
545+ }
546+ else
547+ {
548+ *Format = (info.alphaLength == 0) ? gcvSURF_X8B8G8R8 : gcvSURF_A8B8G8R8;
549+ }
550+ break;
551+
552+ default:
553+ /* Unsupported color depth. */
554+ return gcvSTATUS_INVALID_ARGUMENT;
555+ }
556+ /* Success. */
557+ return gcvSTATUS_OK;
558+}
559+
560+static gceSTATUS galIsYUVFormat(IN gceSURF_FORMAT Format)
561+{
562+ switch (Format)
563+ {
564+ case gcvSURF_YUY2:
565+ case gcvSURF_UYVY:
566+ case gcvSURF_I420:
567+ case gcvSURF_YV12:
568+ case gcvSURF_NV16:
569+ case gcvSURF_NV12:
570+ case gcvSURF_NV61:
571+ case gcvSURF_NV21:
572+
573+ return gcvSTATUS_TRUE;
574+
575+ default:
576+ return gcvSTATUS_FALSE;
577+ }
578+}
579+
580+static gceSTATUS galQueryUVStride(
581+ IN gceSURF_FORMAT Format,
582+ IN gctUINT32 yStride,
583+ OUT gctUINT32_PTR uStride,
584+ OUT gctUINT32_PTR vStride
585+ )
586+{
587+ switch (Format)
588+ {
589+ case gcvSURF_YUY2:
590+ case gcvSURF_UYVY:
591+ *uStride = *vStride = 0;
592+ break;
593+
594+ case gcvSURF_I420:
595+ case gcvSURF_YV12:
596+ *uStride = *vStride = yStride / 2;
597+ break;
598+
599+ case gcvSURF_NV16:
600+ case gcvSURF_NV12:
601+ case gcvSURF_NV61:
602+ case gcvSURF_NV21:
603+
604+ *uStride = yStride;
605+ *vStride = 0;
606+ break;
607+
608+ default:
609+ return gcvSTATUS_NOT_SUPPORTED;
610+ }
611+
612+ return gcvSTATUS_OK;
613+}
614+
615+static int
616+make_current(struct gal2d_renderer *gr, gcoSURF surface)
617+{
618+ gceSTATUS status = gcvSTATUS_OK;
619+ gctUINT width = 0;
620+ gctUINT height = 0;
621+ gctINT stride = 0;
622+ gctUINT32 physical[3];
623+ gctPOINTER va =0;
624+ gceSURF_FORMAT format;
625+
626+ if(!surface)
627+ goto OnError;
628+
629+
630+ gcmONERROR(gcoSURF_GetAlignedSize(surface, &width, &height, &stride));
631+ gcmONERROR(gcoSURF_GetFormat(surface, gcvNULL, &format));
632+ gcmONERROR(gcoSURF_Lock(surface, &physical[0], (gctPOINTER *)&va));
633+ gco2D_SetGenericTarget(gr->gcoEngine2d,
634+ &physical[0], 1,
635+ &stride, 1,
636+ gcvLINEAR, format,
637+ gcvSURF_0_DEGREE, width, height);
638+
639+ gcmONERROR(gcoSURF_Unlock(surface, (gctPOINTER *)&va));
640+OnError:
641+ galONERROR(status);
642+ return status;
643+}
644+
645+static gceSTATUS
646+gal2d_clear(struct weston_output *base)
647+{
648+ struct gal2d_renderer *gr = get_renderer(base->compositor);
649+ struct gal2d_output_state *go = get_output_state(base);
650+ gceSTATUS status = gcvSTATUS_OK;
651+
652+ gctINT stride = 0;
653+ gctUINT width = 0, height = 0;
654+ gcsRECT dstRect = {0};
655+ gcmONERROR(gcoSURF_GetAlignedSize(go->renderSurf[go->activebuffer],
656+ &width, &height, &stride));
657+ dstRect.right = width;
658+ dstRect.bottom = height;
659+ gcmONERROR(gco2D_SetSource(gr->gcoEngine2d, &dstRect));
660+ gcmONERROR(gco2D_SetClipping(gr->gcoEngine2d, &dstRect));
661+ gcmONERROR(gco2D_Clear(gr->gcoEngine2d, 1, &dstRect, 0xff0000ff, 0xCC, 0xCC, go->format));
662+ gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvTRUE));
663+
664+OnError:
665+ galONERROR(status);
666+
667+ return status;
668+}
669+
670+static gcoSURF getSurfaceFromShm(struct weston_surface *es, struct weston_buffer *buffer)
671+{
672+ struct gal2d_renderer *gr = get_renderer(es->compositor);
673+
674+ gcoSURF surface = 0;
675+ gceSURF_FORMAT format;
676+ gcePOOL pool = gcvPOOL_DEFAULT;
677+
678+ if (wl_shm_buffer_get_format(buffer->shm_buffer) == WL_SHM_FORMAT_XRGB8888)
679+ format = gcvSURF_X8R8G8B8;
680+ else
681+ format = gcvSURF_A8R8G8B8;
682+
683+ if(buffer->width == ((buffer->width + 0x7) & ~0x7))
684+ {
685+ pool = gcvPOOL_USER;
686+ }
687+
688+ gcmVERIFY_OK(gcoSURF_Construct(gr->gcoHal,
689+ (gctUINT) buffer->width,
690+ (gctUINT) buffer->height,
691+ 1, gcvSURF_BITMAP,
692+ format, pool, &surface));
693+
694+ if(pool == gcvPOOL_USER)
695+ {
696+ gcmVERIFY_OK(gcoSURF_MapUserSurface(surface, 1,
697+ (gctPOINTER)wl_shm_buffer_get_data(buffer->shm_buffer), gcvINVALID_ADDRESS));
698+ }
699+
700+ return surface;
701+}
702+
703+static int
704+gal2dBindBuffer(struct weston_surface* es)
705+{
706+ struct gal2d_surface_state *gs = get_surface_state(es);
707+ gceSTATUS status = gcvSTATUS_OK;
708+ gcoSURF surface = gs->gco_Surface;
709+ struct weston_buffer *buffer = gs->buffer_ref.buffer;
710+ gcePOOL pool = gcvPOOL_DEFAULT;
711+
712+ gcmVERIFY_OK(gcoSURF_QueryVidMemNode(surface, gcvNULL,
713+ &pool, gcvNULL));
714+
715+ if(pool != gcvPOOL_USER)
716+ {
717+ gctUINT alignedWidth;
718+ gctPOINTER logical = (gctPOINTER)wl_shm_buffer_get_data(buffer->shm_buffer);
719+ gctPOINTER va =0;
720+
721+
722+ gcmVERIFY_OK(gcoSURF_GetAlignedSize(surface, &alignedWidth, gcvNULL, gcvNULL));
723+ gcmVERIFY_OK(gcoSURF_Lock(surface, gcvNULL, (gctPOINTER *)&va));
724+
725+ if(alignedWidth == (unsigned int)buffer->width)
726+ {
727+ int size = wl_shm_buffer_get_stride(buffer->shm_buffer)*buffer->height;
728+ memcpy(va, logical, size);
729+ }
730+ else
731+ {
732+ int i, j;
733+ for (i = 0; i < buffer->height; i++)
734+ {
735+ for (j = 0; j < buffer->width; j++)
736+ {
737+ gctUINT dstOff = i * alignedWidth + j;
738+ gctUINT srcOff = (i * buffer->width + j);
739+
740+ memcpy(va + dstOff * 4, logical + srcOff * 4, 4);
741+ }
742+ }
743+ }
744+ gcmVERIFY_OK(gcoSURF_Unlock(surface, (gctPOINTER)va));
745+ }
746+
747+ return status;
748+}
749+
750+static void
751+gal2d_flip_surface(struct weston_output *output)
752+{
753+ struct gal2d_output_state *go = get_output_state(output);
754+
755+ if(go->nNumBuffers > 1)
756+ {
757+ gctUINT Offset;
758+ gctINT X;
759+ gctINT Y;
760+
761+ gcmVERIFY_OK(gcoOS_GetDisplayBackbuffer(go->display, gcvNULL,
762+ gcvNULL, gcvNULL, &Offset, &X, &Y));
763+
764+ gcmVERIFY_OK(gcoOS_SetDisplayVirtual(go->display, gcvNULL,
765+ Offset, X, Y));
766+ }
767+}
768+
769+static void *gal2d_output_worker(void *arg)
770+{
771+ struct weston_output *output = (struct weston_output *)arg;
772+ struct gal2d_output_state *go = get_output_state(output);
773+
774+ while(1)
775+ {
776+ if(gcoOS_WaitSignal(gcvNULL, go->signal, gcvINFINITE) == gcvSTATUS_OK )
777+ {
778+ gal2d_flip_surface(output);
779+ gcoOS_Signal(gcvNULL,go->busySignal, gcvTRUE);
780+ }
781+ pthread_mutex_lock(&go->workerMutex);
782+ if(go->exitWorker == 1)
783+ {
784+ pthread_mutex_unlock(&go->workerMutex);
785+ break;
786+ }
787+ pthread_mutex_unlock(&go->workerMutex);
788+ }
789+ return 0;
790+}
791+
792+static int
793+update_surface(struct weston_output *output)
794+{
795+ struct gal2d_renderer *gr = get_renderer(output->compositor);
796+ struct gal2d_output_state *go = get_output_state(output);
797+ gceSTATUS status = gcvSTATUS_OK;
798+
799+ if(go->nNumBuffers == 1)
800+ {
801+ if(!go->directBlit && go->offscreenSurface)
802+ {
803+ make_current(gr, go->renderSurf[go->activebuffer]);
804+
805+ gctUINT srcWidth = 0;
806+ gctUINT srcHeight = 0;
807+ gceSURF_FORMAT srcFormat;;
808+ gcsRECT dstRect = {0};
809+ gcoSURF srcSurface = go->offscreenSurface;
810+ gctUINT32 srcPhyAddr[3];
811+ gctUINT32 srcStride[3];
812+
813+ gctPOINTER va =0;
814+
815+ gcmONERROR(gcoSURF_GetAlignedSize(srcSurface, &srcWidth, &srcHeight, (gctINT *)&srcStride[0]));
816+ gcmONERROR(gcoSURF_GetFormat(srcSurface, gcvNULL, &srcFormat));
817+
818+ gcmONERROR(gcoSURF_Lock(srcSurface, srcPhyAddr, (gctPOINTER *)&va));
819+ gcmONERROR(gco2D_SetCurrentSourceIndex(gr->gcoEngine2d, 0U));
820+
821+ gco2D_SetGenericSource(gr->gcoEngine2d, srcPhyAddr, 1,
822+ srcStride, 1,
823+ gcvLINEAR, srcFormat, gcvSURF_0_DEGREE,
824+ srcWidth, srcHeight);
825+
826+ dstRect.left = 0;
827+ dstRect.top = 0;
828+ dstRect.right = srcWidth;
829+ dstRect.bottom = srcHeight;
830+
831+ gcmONERROR(gco2D_SetSource(gr->gcoEngine2d, &dstRect));
832+ gcmONERROR(gco2D_SetClipping(gr->gcoEngine2d, &dstRect));
833+ gcmONERROR(gco2D_Blit(gr->gcoEngine2d, 1, &dstRect, 0xCC, 0xCC, go->format));
834+ gcmONERROR(gcoSURF_Unlock(srcSurface, (gctPOINTER *)&va));
835+ }
836+ gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvFALSE));
837+ }
838+ else if(go->nNumBuffers > 1)
839+ {
840+ gcoHAL_ScheduleEvent(gr->gcoHal, &go->iface);
841+ gcmVERIFY_OK(gcoHAL_Commit(gr->gcoHal, gcvFALSE));
842+ }
843+OnError:
844+ galONERROR(status);
845+ return status;
846+ }
847+
848+static int
849+is_view_visible(struct weston_view *view)
850+{
851+ /* Return false, if surface is guaranteed to be totally obscured. */
852+ int ret;
853+ pixman_region32_t unocc;
854+
855+ pixman_region32_init(&unocc);
856+ pixman_region32_subtract(&unocc, &view->transform.boundingbox,
857+ &view->clip);
858+ ret = pixman_region32_not_empty(&unocc);
859+ pixman_region32_fini(&unocc);
860+
861+ return ret;
862+}
863+
864+static int
865+use_output(struct weston_output *output)
866+{
867+ struct weston_compositor *compositor = output->compositor;
868+ struct weston_view *view;
869+ struct gal2d_output_state *go = get_output_state(output);
870+ struct gal2d_renderer *gr = get_renderer(output->compositor);
871+ gceSTATUS status = gcvSTATUS_OK;
872+
873+ gcoSURF surface;
874+ int visibleViews=0;
875+ int fullscreenViews=0;
876+
877+ surface = go->renderSurf[go->activebuffer];
878+ if(go->nNumBuffers == 1)
879+ {
880+ wl_list_for_each_reverse(view, &compositor->view_list, link)
881+ if (view->plane == &compositor->primary_plane && is_view_visible(view))
882+ {
883+ visibleViews++;
884+ if(view->surface->width == go->width && view->surface->height == go->height)
885+ {
886+ pixman_box32_t *bb_rects;
887+ int nbb=0;
888+ bb_rects = pixman_region32_rectangles(&view->transform.boundingbox, &nbb);
889+ if(nbb == 1)
890+ if(bb_rects[0].x1 == 0 && bb_rects[0].y1 ==0)
891+ fullscreenViews++;
892+ }
893+ }
894+
895+ go->directBlit = ((visibleViews == 1) || (fullscreenViews > 1));
896+
897+ if(!go->directBlit)
898+ {
899+ surface = go->offscreenSurface;
900+ }
901+ }
902+ make_current(gr, surface);
903+ return status;
904+}
905+
906+static int
907+gal2d_renderer_read_pixels(struct weston_output *output,
908+ pixman_format_code_t format, void *pixels,
909+ uint32_t x, uint32_t y,
910+ uint32_t width, uint32_t height)
911+{
912+ return 0;
913+}
914+
915+static int gal2d_int_from_double(double d)
916+{
917+ return wl_fixed_to_int(wl_fixed_from_double(d));
918+}
919+
920+static void
921+repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2d_output_state *go, pixman_region32_t *region,
922+ pixman_region32_t *surf_region){
923+
924+ struct gal2d_renderer *gr = get_renderer(ev->surface->compositor);
925+ struct gal2d_surface_state *gs = get_surface_state(ev->surface);
926+
927+ pixman_box32_t *rects, *surf_rects, *bb_rects;
928+ int i, j, nrects, nsurf, nbb=0;
929+ gceSTATUS status = gcvSTATUS_OK;
930+ gcoSURF srcSurface = gs->gco_Surface;
931+ gcsRECT srcRect = {0};
932+ gcsRECT dstrect = {0};
933+ gctUINT32 horFactor, verFactor;
934+ int useStretch =1;
935+ int useFilterBlit = 0;
936+ gctUINT srcWidth = 0;
937+ gctUINT srcHeight = 0;
938+ gctUINT32 srcStride[3];
939+ gceSURF_FORMAT srcFormat;;
940+ gctUINT32 srcPhyAddr[3];
941+ gctUINT32 dstPhyAddr[3];
942+ gctUINT dstWidth = 0;
943+ gctUINT dstHeight = 0;
944+ gctUINT32 dstStrides[3];
945+ gcoSURF dstsurface;
946+ int geoWidth = ev->surface->width;
947+ int geoheight = ev->surface->height;
948+ gceTILING tiling;
949+
950+ bb_rects = pixman_region32_rectangles(&ev->transform.boundingbox, &nbb);
951+
952+ if(!srcSurface || nbb <= 0)
953+ goto OnError;
954+ rects = pixman_region32_rectangles(region, &nrects);
955+ surf_rects = pixman_region32_rectangles(surf_region, &nsurf);
956+
957+ gcmVERIFY_OK(gcoSURF_GetAlignedSize(srcSurface, &srcWidth, &srcHeight, (gctINT *)&srcStride[0]));
958+
959+ gcmVERIFY_OK(gcoSURF_GetFormat(srcSurface, gcvNULL, &srcFormat));
960+
961+ if(galIsYUVFormat(srcFormat) == gcvSTATUS_TRUE)
962+ {
963+ useFilterBlit = 1;
964+ }
965+
966+ gcmVERIFY_OK(gcoSURF_Lock(srcSurface, &srcPhyAddr[0], gcvNULL));
967+
968+ gcmVERIFY_OK(gcoSURF_Unlock(srcSurface, gcvNULL));
969+
970+ srcRect.left = ev->geometry.x < 0.0 ? gal2d_int_from_double(fabsf(ev->geometry.x)) : 0;
971+ srcRect.top = 0; /*es->geometry.y < 0.0 ? gal2d_int_from_double(fabsf(es->geometry.y)) : 0;*/
972+ srcRect.right = ev->surface->width;
973+ srcRect.bottom = ev->surface->height;
974+
975+ if(useFilterBlit)
976+ {
977+ dstsurface = go->nNumBuffers > 1 ?
978+ go->renderSurf[go->activebuffer] :
979+ go->offscreenSurface;
980+ gcmVERIFY_OK(gcoSURF_GetAlignedSize(dstsurface, &dstWidth, &dstHeight, (gctINT *)&dstStrides));
981+ gcmVERIFY_OK(gcoSURF_Lock(dstsurface, &dstPhyAddr[0], gcvNULL));
982+ gcmVERIFY_OK(gcoSURF_Unlock(dstsurface, gcvNULL));
983+ }
984+ else
985+ {
986+ gcoSURF_GetTiling(srcSurface, &tiling);
987+ if (gcoHAL_IsFeatureAvailable(gr->gcoHal, gcvFEATURE_2D_TILING) != gcvTRUE && (tiling > gcvLINEAR))
988+ {
989+ weston_log("Tiling not supported \n");
990+ status = gcvSTATUS_NOT_SUPPORTED;
991+ gcmONERROR(status);
992+ }
993+ gco2D_SetGenericSource(gr->gcoEngine2d, srcPhyAddr, 1,
994+ srcStride, 1,
995+ tiling, srcFormat, gcvSURF_0_DEGREE,
996+ srcWidth, srcHeight);
997+ /* Setup mirror. */
998+ gcmONERROR(gco2D_SetBitBlitMirror(gr->gcoEngine2d, gcvFALSE, gcvFALSE));
999+ gcmONERROR(gco2D_SetROP(gr->gcoEngine2d, 0xCC, 0xCC));
1000+ }
1001+
1002+ for (i = 0; i < nrects; i++)
1003+ {
1004+ pixman_box32_t *rect = &rects[i];
1005+ gctFLOAT min_x, max_x, min_y, max_y;
1006+
1007+ dstrect.left = (bb_rects[0].x1 < 0) ? rect->x1 : bb_rects[0].x1;
1008+ dstrect.top = (bb_rects[0].y1 < 0) ? rect->y1 : bb_rects[0].y1;
1009+ dstrect.right = bb_rects[0].x2;
1010+ dstrect.bottom = bb_rects[0].y2;
1011+
1012+ if(dstrect.right < 0 || dstrect.bottom < 0)
1013+ {
1014+ break;
1015+ }
1016+
1017+ for (j = 0; j < nsurf; j++)
1018+ {
1019+ pixman_box32_t *surf_rect = &surf_rects[j];
1020+ gctFLOAT ex[8], ey[8]; /* edge points in screen space */
1021+ int n;
1022+ gcsRECT clipRect = {0};
1023+ int m=0;
1024+ n = calculate_edges(ev, rect, surf_rect, ex, ey);
1025+ if (n < 3)
1026+ continue;
1027+
1028+ min_x = max_x = ex[0];
1029+ min_y = max_y = ey[0];
1030+ for (m = 1; m < n; m++)
1031+ {
1032+ min_x = min(min_x, ex[m]);
1033+ max_x = max(max_x, ex[m]);
1034+ min_y = min(min_y, ey[m]);
1035+ max_y = max(max_y, ey[m]);
1036+ }
1037+
1038+ clipRect.left = gal2d_int_from_double(min_x);
1039+ clipRect.top = gal2d_int_from_double(min_y);
1040+ clipRect.right = gal2d_int_from_double(max_x);
1041+ clipRect.bottom = gal2d_int_from_double(max_y);
1042+
1043+ if(output->x > 0)
1044+ {
1045+ dstrect.left = dstrect.left - output->x;
1046+ dstrect.right = dstrect.right - output->x;
1047+ clipRect.left = clipRect.left - output->x;
1048+ clipRect.right = clipRect.right - output->x;
1049+ }
1050+
1051+ dstrect.left = (dstrect.left < 0) ? 0 : dstrect.left;
1052+
1053+ status = gco2D_SetClipping(gr->gcoEngine2d, &clipRect);
1054+ if(status < 0)
1055+ {
1056+ weston_log("Error in gco2D_SetClipping %s\n", __func__);
1057+ goto OnError;
1058+ }
1059+
1060+ if(useFilterBlit)
1061+ {
1062+ gctINT srcStrideNum;
1063+ gctINT srcAddressNum;
1064+ gcmVERIFY_OK(galQueryUVStride(srcFormat, srcStride[0],
1065+ &srcStride[1], &srcStride[2]));
1066+
1067+ switch (srcFormat)
1068+ {
1069+ case gcvSURF_YUY2:
1070+ case gcvSURF_UYVY:
1071+ srcStrideNum = srcAddressNum = 1;
1072+ break;
1073+
1074+ case gcvSURF_I420:
1075+ case gcvSURF_YV12:
1076+ srcStrideNum = srcAddressNum = 3;
1077+ break;
1078+
1079+ case gcvSURF_NV16:
1080+ case gcvSURF_NV12:
1081+ case gcvSURF_NV61:
1082+ case gcvSURF_NV21:
1083+ srcStrideNum = srcAddressNum = 2;
1084+ break;
1085+
1086+ default:
1087+ gcmONERROR(gcvSTATUS_NOT_SUPPORTED);
1088+ }
1089+ gco2D_FilterBlitEx2(gr->gcoEngine2d,
1090+ srcPhyAddr, srcAddressNum,
1091+ srcStride, srcStrideNum,
1092+ gcvLINEAR, srcFormat, gcvSURF_0_DEGREE,
1093+ geoWidth, geoheight, &srcRect,
1094+ dstPhyAddr, 1,
1095+ dstStrides, 1,
1096+ gcvLINEAR, go->format, gcvSURF_0_DEGREE,
1097+ dstWidth, dstHeight,
1098+ &dstrect, gcvNULL);
1099+ }
1100+ else
1101+ {
1102+ if(useStretch)
1103+ gcmVERIFY_OK(galGetStretchFactors(&srcRect, &dstrect, &horFactor, &verFactor));
1104+
1105+ if(verFactor == 65536 && horFactor == 65536)
1106+ {
1107+ gcmVERIFY_OK(gco2D_Blit(gr->gcoEngine2d, 1, &dstrect,
1108+ 0xCC, 0xCC, go->format));
1109+ }
1110+ else
1111+ {
1112+ /* Program the stretch factors. */
1113+ gcmVERIFY_OK(gco2D_SetStretchFactors(gr->gcoEngine2d, horFactor, verFactor));
1114+
1115+ gcmVERIFY_OK(gco2D_StretchBlit(gr->gcoEngine2d, 1, &dstrect,
1116+ 0xCC, 0xCC, go->format));
1117+ }
1118+ }
1119+
1120+ if(status < 0)
1121+ {
1122+ printf("cr l=%d r=%d t=%d b=%d w=%d h=%d\n",
1123+ clipRect.left, clipRect.right, clipRect.top ,clipRect.bottom,
1124+ clipRect.right - clipRect.left, clipRect.bottom -clipRect.top);
1125+ printf("dr l=%d r=%d t=%d b=%d w=%d h=%d\n",
1126+ dstrect.left, dstrect.right, dstrect.top ,dstrect.bottom,
1127+ dstrect.right - dstrect.left, dstrect.bottom -dstrect.top);
1128+ printf("horFactor=%d, verFactor=%d\n",horFactor, verFactor);
1129+
1130+ goto OnError;
1131+ }
1132+ }
1133+ }
1134+
1135+OnError:
1136+ galONERROR(status);
1137+}
1138+
1139+static void
1140+draw_view(struct weston_view *ev, struct weston_output *output,
1141+ pixman_region32_t *damage) /* in global coordinates */
1142+{
1143+ struct weston_compositor *ec = ev->surface->compositor;
1144+ struct gal2d_output_state *go = get_output_state(output);
1145+ /* repaint bounding region in global coordinates: */
1146+ pixman_region32_t repaint;
1147+ /* non-opaque region in surface coordinates: */
1148+ pixman_region32_t surface_blend;
1149+ pixman_region32_t *buffer_damage;
1150+
1151+ pixman_region32_init(&repaint);
1152+ pixman_region32_intersect(&repaint,
1153+ &ev->transform.boundingbox, damage);
1154+ pixman_region32_subtract(&repaint, &repaint, &ev->clip);
1155+
1156+ if (!pixman_region32_not_empty(&repaint))
1157+ goto out;
1158+
1159+ buffer_damage = &go->buffer_damage[go->current_buffer];
1160+ pixman_region32_subtract(buffer_damage, buffer_damage, &repaint);
1161+
1162+ /* blended region is whole surface minus opaque region: */
1163+ pixman_region32_init_rect(&surface_blend, 0, 0,
1164+ ev->surface->width, ev->surface->height);
1165+ pixman_region32_subtract(&surface_blend, &surface_blend, &ev->surface->opaque);
1166+
1167+ struct gal2d_renderer *gr = get_renderer(ec);
1168+ gco2D_SetCurrentSourceIndex(gr->gcoEngine2d, 0U);
1169+
1170+ if (pixman_region32_not_empty(&ev->surface->opaque)) {
1171+ repaint_region(ev, output, go, &repaint, &ev->surface->opaque);
1172+ }
1173+
1174+ if (pixman_region32_not_empty(&surface_blend)) {
1175+ gco2D_EnableAlphaBlend(gr->gcoEngine2d,
1176+ ev->alpha * 0xFF, ev->alpha * 0xFF,
1177+ gcvSURF_PIXEL_ALPHA_STRAIGHT, gcvSURF_PIXEL_ALPHA_STRAIGHT,
1178+ gcvSURF_GLOBAL_ALPHA_SCALE, gcvSURF_GLOBAL_ALPHA_SCALE,
1179+ gcvSURF_BLEND_STRAIGHT, gcvSURF_BLEND_INVERSED,
1180+ gcvSURF_COLOR_STRAIGHT, gcvSURF_COLOR_STRAIGHT);
1181+
1182+ repaint_region(ev, output, go, &repaint, &surface_blend);
1183+ }
1184+
1185+ gco2D_DisableAlphaBlend(gr->gcoEngine2d);
1186+ pixman_region32_fini(&surface_blend);
1187+
1188+out:
1189+ pixman_region32_fini(&repaint);
1190+
1191+}
1192+
1193+static void
1194+repaint_views(struct weston_output *output, pixman_region32_t *damage)
1195+{
1196+ struct weston_compositor *compositor = output->compositor;
1197+ struct weston_view *view;
1198+ struct gal2d_output_state *go = get_output_state(output);
1199+
1200+ if(go->nNumBuffers > 1)
1201+ {
1202+ /*500ms is more than enough to process a frame */
1203+ gcoOS_WaitSignal(gcvNULL, go->busySignal, 500);
1204+ }
1205+ go->activebuffer = (go->activebuffer+1) % go->nNumBuffers;
1206+
1207+ wl_list_for_each_reverse(view, &compositor->view_list, link)
1208+ if (view->plane == &compositor->primary_plane)
1209+ draw_view(view, output, damage);
1210+}
1211+
1212+static void
1213+gal2d_renderer_repaint_output(struct weston_output *output,
1214+ pixman_region32_t *output_damage)
1215+{
1216+ struct gal2d_output_state *go = get_output_state(output);
1217+ gctUINT32 i;
1218+
1219+ if (use_output(output) < 0)
1220+ return;
1221+
1222+ for (i = 0; i < 2; i++)
1223+ pixman_region32_union(&go->buffer_damage[i],
1224+ &go->buffer_damage[i],
1225+ output_damage);
1226+
1227+ pixman_region32_union(output_damage, output_damage,
1228+ &go->buffer_damage[go->current_buffer]);
1229+
1230+ repaint_views(output, output_damage);
1231+
1232+ pixman_region32_copy(&output->previous_damage, output_damage);
1233+ wl_signal_emit(&output->frame_signal, output);
1234+
1235+ update_surface(output);
1236+
1237+ go->current_buffer ^= 1;
1238+}
1239+
1240+static void
1241+gal2d_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer)
1242+{
1243+ gcsWL_VIV_BUFFER *vivBuffer = wl_resource_get_user_data(buffer->resource);
1244+ gcoSURF srcSurf = vivBuffer->surface;
1245+ gceSTATUS status = gcvSTATUS_OK;
1246+ struct gal2d_surface_state *gs = get_surface_state(es);
1247+
1248+ if(gs->gco_Surface != gcvNULL)
1249+ {
1250+ gcmONERROR(gcoSURF_Destroy(gs->gco_Surface));
1251+ }
1252+
1253+ gs->gco_Surface = srcSurf;
1254+ gcoSURF_ReferenceSurface(srcSurf);
1255+ buffer->width = vivBuffer->width;
1256+ buffer->height = vivBuffer->height;
1257+
1258+ OnError:
1259+ galONERROR(status);
1260+}
1261+
1262+static void
1263+gal2d_renderer_flush_damage(struct weston_surface *surface)
1264+{
1265+ struct gal2d_surface_state *gs = get_surface_state(surface);
1266+ struct weston_buffer *buffer = gs->buffer_ref.buffer;
1267+ struct weston_view *view;
1268+ int texture_used;
1269+ pixman_region32_union(&gs->texture_damage,
1270+ &gs->texture_damage, &surface->damage);
1271+
1272+ if (!buffer)
1273+ return;
1274+
1275+ texture_used = 0;
1276+ wl_list_for_each(view, &surface->views, surface_link) {
1277+ if (view->plane == &surface->compositor->primary_plane) {
1278+ texture_used = 1;
1279+ break;
1280+ }
1281+ }
1282+ if (!texture_used)
1283+ return;
1284+
1285+ if (!pixman_region32_not_empty(&gs->texture_damage))
1286+ goto done;
1287+
1288+ if(wl_shm_buffer_get(buffer->resource))
1289+ {
1290+ if(gs->gco_Surface==NULL)
1291+ {
1292+ gs->gco_Surface = getSurfaceFromShm(surface, buffer);
1293+ }
1294+ gal2dBindBuffer(surface);
1295+ }
1296+ else
1297+ gal2d_renderer_attach_egl(surface, buffer);
1298+
1299+done:
1300+ pixman_region32_fini(&gs->texture_damage);
1301+ pixman_region32_init(&gs->texture_damage);
1302+
1303+ weston_buffer_reference(&gs->buffer_ref, NULL);
1304+}
1305+
1306+static void
1307+gal2d_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
1308+{
1309+ struct gal2d_surface_state *gs = get_surface_state(es);
1310+ struct wl_shm_buffer *shm_buffer;
1311+ weston_buffer_reference(&gs->buffer_ref, buffer);
1312+
1313+ if(buffer==NULL)
1314+ return;
1315+
1316+ shm_buffer = wl_shm_buffer_get(buffer->resource);
1317+
1318+ if(shm_buffer)
1319+ {
1320+ buffer->width = wl_shm_buffer_get_width(shm_buffer);
1321+ buffer->height = wl_shm_buffer_get_height(shm_buffer);
1322+ buffer->shm_buffer = shm_buffer;
1323+
1324+ if(gs->gco_Surface)
1325+ {
1326+ gcoSURF_Destroy(gs->gco_Surface);
1327+ gs->gco_Surface = getSurfaceFromShm(es, buffer);
1328+ }
1329+ }
1330+ else
1331+ gal2d_renderer_attach_egl(es, buffer);
1332+}
1333+
1334+static void
1335+surface_state_destroy(struct gal2d_surface_state *gs, struct gal2d_renderer *gr)
1336+{
1337+ if(gs->gco_Surface)
1338+ {
1339+ gcoSURF_Destroy(gs->gco_Surface);
1340+ }
1341+ wl_list_remove(&gs->surface_destroy_listener.link);
1342+ wl_list_remove(&gs->renderer_destroy_listener.link);
1343+ if(gs->surface)
1344+ gs->surface->renderer_state = NULL;
1345+
1346+ weston_buffer_reference(&gs->buffer_ref, NULL);
1347+ free(gs);
1348+}
1349+
1350+static void
1351+surface_state_handle_surface_destroy(struct wl_listener *listener, void *data)
1352+{
1353+ struct gal2d_surface_state *gs;
1354+ struct gal2d_renderer *gr;
1355+
1356+ gs = container_of(listener, struct gal2d_surface_state,
1357+ surface_destroy_listener);
1358+
1359+ gr = get_renderer(gs->surface->compositor);
1360+ surface_state_destroy(gs, gr);
1361+}
1362+
1363+static void
1364+surface_state_handle_renderer_destroy(struct wl_listener *listener, void *data)
1365+{
1366+ struct gal2d_surface_state *gs;
1367+ struct gal2d_renderer *gr;
1368+
1369+ gr = data;
1370+
1371+ gs = container_of(listener, struct gal2d_surface_state,
1372+ renderer_destroy_listener);
1373+
1374+ surface_state_destroy(gs, gr);
1375+}
1376+
1377+
1378+static int
1379+gal2d_renderer_create_surface(struct weston_surface *surface)
1380+{
1381+ struct gal2d_surface_state *gs;
1382+ struct gal2d_renderer *gr = get_renderer(surface->compositor);
1383+
1384+ gs = zalloc(sizeof *gs);
1385+ if (gs == NULL)
1386+ return -1;
1387+
1388+ /* A buffer is never attached to solid color surfaces, yet
1389+ * they still go through texcoord computations. Do not divide
1390+ * by zero there.
1391+ */
1392+ gs->pitch = 1;
1393+
1394+ gs->surface = surface;
1395+
1396+ pixman_region32_init(&gs->texture_damage);
1397+ surface->renderer_state = gs;
1398+
1399+ gs->surface_destroy_listener.notify =
1400+ surface_state_handle_surface_destroy;
1401+ wl_signal_add(&surface->destroy_signal,
1402+ &gs->surface_destroy_listener);
1403+
1404+ gs->renderer_destroy_listener.notify =
1405+ surface_state_handle_renderer_destroy;
1406+ wl_signal_add(&gr->destroy_signal,
1407+ &gs->renderer_destroy_listener);
1408+
1409+ if (surface->buffer_ref.buffer) {
1410+ gal2d_renderer_attach(surface, surface->buffer_ref.buffer);
1411+ gal2d_renderer_flush_damage(surface);
1412+ }
1413+
1414+ return 0;
1415+}
1416+
1417+static void
1418+gal2d_renderer_surface_set_color(struct weston_surface *surface,
1419+ float red, float green, float blue, float alpha)
1420+{
1421+ struct gal2d_surface_state *gs = get_surface_state(surface);
1422+
1423+ gs->color[0] = red;
1424+ gs->color[1] = green;
1425+ gs->color[2] = blue;
1426+ gs->color[3] = alpha;
1427+}
1428+
1429+
1430+static void
1431+gal2d_renderer_output_destroy(struct weston_output *output)
1432+{
1433+ struct gal2d_output_state *go = get_output_state(output);
1434+ gctUINT32 i;
1435+
1436+ for (i = 0; i < 2; i++)
1437+ {
1438+ pixman_region32_fini(&go->buffer_damage[i]);
1439+ }
1440+ if(go->nNumBuffers <= 1 )
1441+ {
1442+ if(go->offscreenSurface)
1443+ gcmVERIFY_OK(gcoSURF_Destroy(go->offscreenSurface));
1444+ }
1445+ else
1446+ {
1447+ gcoOS_Signal(gcvNULL,go->signal, gcvTRUE);
1448+ pthread_mutex_lock(&go->workerMutex);
1449+ go->exitWorker = 1;
1450+ pthread_mutex_unlock(&go->workerMutex);
1451+ pthread_join(go->workerId, NULL);
1452+ }
1453+
1454+ for(i=0; i < go->nNumBuffers; i++)
1455+ {
1456+ gcmVERIFY_OK(gcoSURF_Destroy(go->renderSurf[i]));
1457+ }
1458+ free(go->renderSurf);
1459+ go->renderSurf = gcvNULL;
1460+
1461+ free(go);
1462+}
1463+
1464+static void
1465+gal2d_renderer_destroy(struct weston_compositor *ec)
1466+{
1467+ struct gal2d_renderer *gr = get_renderer(ec);
1468+
1469+ wl_signal_emit(&gr->destroy_signal, gr);
1470+ free(ec->renderer);
1471+ ec->renderer = NULL;
1472+}
1473+
1474+
1475+static int
1476+gal2d_renderer_create(struct weston_compositor *ec)
1477+{
1478+ struct gal2d_renderer *gr;
1479+ gceSTATUS status = gcvSTATUS_OK;
1480+ gr = malloc(sizeof *gr);
1481+ if (gr == NULL)
1482+ return -1;
1483+
1484+ gr->base.read_pixels = gal2d_renderer_read_pixels;
1485+ gr->base.repaint_output = gal2d_renderer_repaint_output;
1486+ gr->base.flush_damage = gal2d_renderer_flush_damage;
1487+ gr->base.attach = gal2d_renderer_attach;
1488+ gr->base.surface_set_color = gal2d_renderer_surface_set_color;
1489+ gr->base.destroy = gal2d_renderer_destroy;
1490+
1491+ /* Construct the gcoOS object. */
1492+ gcmONERROR(gcoOS_Construct(gcvNULL, &gr->gcos));
1493+
1494+ /* Construct the gcoHAL object. */
1495+ gcmONERROR(gcoHAL_Construct(gcvNULL, gr->gcos, &gr->gcoHal));
1496+ gcmONERROR(gcoHAL_Get2DEngine(gr->gcoHal, &gr->gcoEngine2d));
1497+ gcmONERROR(gcoHAL_SetHardwareType(gr->gcoHal, gcvHARDWARE_2D));
1498+
1499+ ec->renderer = &gr->base;
1500+ wl_signal_init(&gr->destroy_signal);
1501+OnError:
1502+ galONERROR(status);
1503+
1504+ /* Return the status. */
1505+ return status;
1506+
1507+}
1508+
1509+static int
1510+gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType display,
1511+ NativeWindowType window)
1512+
1513+ {
1514+ struct gal2d_renderer *gr = get_renderer(output->compositor);
1515+ struct gal2d_output_state *go;
1516+ halDISPLAY_INFO info;
1517+ gctUINT32 backOffset = 0;
1518+ gceSTATUS status = gcvSTATUS_OK;
1519+ gctUINT32 i;
1520+
1521+ go = zalloc(sizeof *go);
1522+ if (go == NULL)
1523+ return -1;
1524+
1525+ output->renderer_state = go;
1526+ go->display = display;
1527+ gcmONERROR(gcoOS_InitLocalDisplayInfo(go->display, &gr->localInfo));
1528+
1529+ /* Get display information. */
1530+ gcmONERROR(gcoOS_GetDisplayInfoEx2(
1531+ go->display, gcvNULL, gr->localInfo,
1532+ sizeof(info), &info));
1533+ go->nNumBuffers = info.multiBuffer;
1534+
1535+ weston_log("Number of buffers=%d\n",go->nNumBuffers);
1536+
1537+ gcmONERROR(gal2d_getSurfaceFormat(info, &go->format));
1538+ backOffset = (gctUINT32)(info.stride * info.height );
1539+
1540+ go->activebuffer = 0;
1541+
1542+ go->renderSurf = malloc(sizeof(gcoSURF) * go->nNumBuffers);
1543+ gcoOS_GetDisplayVirtual(go->display, &go->width, &go->height);
1544+ gcoOS_SetSwapInterval(go->display, 1);
1545+
1546+ /*Needed only for multi Buffer */
1547+ if(go->nNumBuffers > 1)
1548+ {
1549+ gcmVERIFY_OK(gcoOS_CreateSignal(gcvNULL, gcvFALSE,
1550+ &go->signal));
1551+ gcmVERIFY_OK(gcoOS_CreateSignal(gcvNULL, gcvFALSE,
1552+ &go->busySignal));
1553+
1554+ go->iface.command = gcvHAL_SIGNAL;
1555+ go->iface.u.Signal.signal = gcmPTR_TO_UINT64(go->signal);
1556+ go->iface.u.Signal.auxSignal = 0;
1557+ go->iface.u.Signal.process = gcmPTR_TO_UINT64(gcoOS_GetCurrentProcessID());
1558+ go->iface.u.Signal.fromWhere = gcvKERNEL_PIXEL;
1559+
1560+ go->exitWorker = 0;
1561+ pthread_create(&go->workerId, NULL, gal2d_output_worker, output);
1562+ pthread_mutex_init(&go->workerMutex, gcvNULL);
1563+ }
1564+ for(i=0; i < go->nNumBuffers; i++)
1565+ {
1566+ gcmONERROR(gcoSURF_Construct(gr->gcoHal, info.width, info.height, 1,
1567+ gcvSURF_BITMAP, go->format, gcvPOOL_USER, &go->renderSurf[i]));
1568+
1569+ gcoSURF_MapUserSurface(go->renderSurf[i], 0,info.logical + (i * backOffset),
1570+ info.physical + (i * backOffset));
1571+
1572+ //Clear surfaces
1573+ make_current(gr, go->renderSurf[go->activebuffer]);
1574+ gal2d_clear(output);
1575+ gal2d_flip_surface(output);
1576+ }
1577+ if(go->nNumBuffers <= 1)
1578+ go->activebuffer = 0;
1579+ else
1580+ go->activebuffer = 1;
1581+
1582+ if(go->nNumBuffers <= 1 )
1583+ {
1584+ gcmVERIFY_OK(gcoSURF_Construct(gr->gcoHal,
1585+ (gctUINT) info.width,
1586+ (gctUINT) info.height,
1587+ 1,
1588+ gcvSURF_BITMAP,
1589+ go->format,
1590+ gcvPOOL_DEFAULT,
1591+ &go->offscreenSurface));
1592+ make_current(gr, go->offscreenSurface);
1593+ gal2d_clear(output);
1594+ }
1595+ else
1596+ {
1597+ gcoOS_Signal(gcvNULL,go->busySignal, gcvTRUE);
1598+ }
1599+
1600+ for (i = 0; i < 2; i++)
1601+ pixman_region32_init(&go->buffer_damage[i]);
1602+OnError:
1603+ galONERROR(status);
1604+ /* Return the status. */
1605+ return status;
1606+ }
1607+
1608+ WL_EXPORT struct gal2d_renderer_interface gal2d_renderer_interface = {
1609+ .create = gal2d_renderer_create,
1610+ .output_create = gal2d_renderer_output_create,
1611+ .output_destroy = gal2d_renderer_output_destroy,
1612+};
1613Index: weston-1.11.1/src/gal2d-renderer.h
1614===================================================================
1615--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1616+++ weston-1.11.1/src/gal2d-renderer.h 2017-01-14 08:35:10.000000000 -0600
1617@@ -0,0 +1,50 @@
1618+/*
1619+ * Copyright (c) 2015 Freescale Semiconductor, Inc.
1620+ * Copyright © 2013 Vasily Khoruzhick <anarsoul@gmail.com>
1621+ *
1622+ * Permission is hereby granted, free of charge, to any person obtaining
1623+ * a copy of this software and associated documentation files (the
1624+ * "Software"), to deal in the Software without restriction, including
1625+ * without limitation the rights to use, copy, modify, merge, publish,
1626+ * distribute, sublicense, and/or sell copies of the Software, and to
1627+ * permit persons to whom the Software is furnished to do so, subject to
1628+ * the following conditions:
1629+ *
1630+ * The above copyright notice and this permission notice (including the
1631+ * next paragraph) shall be included in all copies or substantial
1632+ * portions of the Software.
1633+ *
1634+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1635+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1636+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1637+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1638+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1639+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1640+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1641+ * SOFTWARE.
1642+ */
1643+#ifndef __gal_2d_renderer_h_
1644+#define __gal_2d_renderer_h_
1645+
1646+#include "compositor.h"
1647+#ifdef ENABLE_EGL
1648+#include <EGL/egl.h>
1649+#else
1650+#include <HAL/gc_hal_eglplatform.h>
1651+typedef HALNativeDisplayType NativeDisplayType;
1652+typedef HALNativeWindowType NativeWindowType;
1653+#endif
1654+
1655+
1656+struct gal2d_renderer_interface {
1657+
1658+ int (*create)(struct weston_compositor *ec);
1659+
1660+ int (*output_create)(struct weston_output *output,
1661+ NativeDisplayType display,
1662+ NativeWindowType window);
1663+
1664+ void (*output_destroy)(struct weston_output *output);
1665+};
1666+
1667+#endif
1668Index: weston-1.11.1/src/compositor-fbdev.h
1669===================================================================
1670--- weston-1.11.1.orig/src/compositor-fbdev.h 2016-09-20 19:35:22.000000000 -0500
1671+++ weston-1.11.1/src/compositor-fbdev.h 2017-01-14 08:35:10.000000000 -0600
1672@@ -40,6 +40,7 @@
1673 int tty;
1674 char *device;
1675 int use_gl;
1676+ int use_gal2d;
1677
1678 uint32_t output_transform;
1679 };
1680Index: weston-1.11.1/src/main.c
1681===================================================================
1682--- weston-1.11.1.orig/src/main.c 2017-01-14 08:34:10.030218137 -0600
1683+++ weston-1.11.1/src/main.c 2017-01-14 08:54:45.000000000 -0600
1684@@ -285,7 +285,13 @@
1685 "Options for fbdev-backend.so:\n\n"
1686 " --tty=TTY\t\tThe tty to use\n"
1687 " --device=DEVICE\tThe framebuffer device to use\n"
1688- " --use-gl\t\tUse the GL renderer\n\n");
1689+#if defined ENABLE_EGL
1690+ " --use-gl=1\t\tUse the GL renderer (default is 1)\n"
1691+ " --use-gal2d=1\t\tUse the GAL2D renderer (default is 0)\n\n");
1692+#else
1693+ " --use-gl=1\t\tUse the GL renderer (default is 0)\n"
1694+ " --use-gal2d=1\t\tUse the GAL2D renderer (default is 1)\n\n");
1695+#endif
1696 #endif
1697
1698 #if defined(BUILD_HEADLESS_COMPOSITOR)
1699@@ -868,7 +874,8 @@
1700 const struct weston_option fbdev_options[] = {
1701 { WESTON_OPTION_INTEGER, "tty", 0, &config.tty },
1702 { WESTON_OPTION_STRING, "device", 0, &config.device },
1703- { WESTON_OPTION_BOOLEAN, "use-gl", 0, &config.use_gl },
1704+ { WESTON_OPTION_INTEGER, "use-gl", 0, &config.use_gl },
1705+ { WESTON_OPTION_INTEGER, "use-gal2d", 0, &config.use_gal2d },
1706 };
1707
1708 parse_options(fbdev_options, ARRAY_LENGTH(fbdev_options), argc, argv);