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