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