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