From d9c60161a34c7cf127cda1782e4adf0d52aab947 Mon Sep 17 00:00:00 2001 From: Neena Busireddy Date: Thu, 18 Feb 2016 15:23:48 -0600 Subject: weston: Fix issues with 1.9 version These set of patches are required to address the issues with weston 1.9 Signed-off-by: Neena Busireddy Signed-off-by: Otavio Salvador --- ...0001-MGS-840-Add-i.MX6-support-for-weston.patch | 1709 -------------------- ...d-GPU-VIV-suport-for-wayland-and-weston-1.patch | 1695 +++++++++++++++++++ ...x6qp-imx6dl-First-frame-distored-when-som.patch | 106 ++ ...imx6qp-imx6dl-First-frame-distored-when-s.patch | 51 + recipes-graphics/wayland/weston_%.bbappend | 8 +- 5 files changed, 1857 insertions(+), 1712 deletions(-) delete mode 100644 recipes-graphics/wayland/weston/0001-MGS-840-Add-i.MX6-support-for-weston.patch create mode 100644 recipes-graphics/wayland/weston/0002-MGS-1111-Add-GPU-VIV-suport-for-wayland-and-weston-1.patch create mode 100644 recipes-graphics/wayland/weston/0006-MGS-1236-imx6qp-imx6dl-First-frame-distored-when-som.patch create mode 100644 recipes-graphics/wayland/weston/0007-MGS-1236-1-imx6qp-imx6dl-First-frame-distored-when-s.patch (limited to 'recipes-graphics') diff --git a/recipes-graphics/wayland/weston/0001-MGS-840-Add-i.MX6-support-for-weston.patch b/recipes-graphics/wayland/weston/0001-MGS-840-Add-i.MX6-support-for-weston.patch deleted file mode 100644 index 80505bdc..00000000 --- a/recipes-graphics/wayland/weston/0001-MGS-840-Add-i.MX6-support-for-weston.patch +++ /dev/null @@ -1,1709 +0,0 @@ -From 0da66b0b96a7059392f0b62d3a13fcedf1023ba8 Mon Sep 17 00:00:00 2001 -From: Prabhu -Date: Wed, 24 Jun 2015 17:29:03 -0500 -Subject: [PATCH] MGS-840 Add i.MX6 support for weston - -Add fbdev backend support for Vivante FBdev EGL - -Date: June 24, 2015 -Signed-off-by: Prabhu ---- - Makefile.am | 13 + - src/compositor-fbdev.c | 139 ++++- - src/gal2d-renderer.c | 1337 ++++++++++++++++++++++++++++++++++++++++++++++++ - src/gal2d-renderer.h | 47 ++ - 4 files changed, 1519 insertions(+), 17 deletions(-) - mode change 100644 => 100755 Makefile.am - create mode 100644 src/gal2d-renderer.c - create mode 100644 src/gal2d-renderer.h - -diff --git a/Makefile.am b/Makefile.am -old mode 100644 -new mode 100755 -index 5819b19..e7e2d49 ---- a/Makefile.am -+++ b/Makefile.am -@@ -207,6 +207,19 @@ gl_renderer_la_SOURCES = \ - src/vertex-clipping.h - endif - -+module_LTLIBRARIES += gal2d-renderer.la -+gal2d_renderer_la_LDFLAGS = -module -avoid-version -+gal2d_renderer_la_LIBADD = $(COMPOSITOR_LIBS) $(EGL_LIBS) -+gal2d_renderer_la_CFLAGS = \ -+ $(COMPOSITOR_CFLAGS) \ -+ $(EGL_CFLAGS) \ -+ $(GCC_CFLAGS) -+gal2d_renderer_la_SOURCES = \ -+ src/gal2d-renderer.h \ -+ src/gal2d-renderer.c \ -+ src/vertex-clipping.c \ -+ src/vertex-clipping.h -+ - if ENABLE_X11_COMPOSITOR - module_LTLIBRARIES += x11-backend.la - x11_backend_la_LDFLAGS = -module -avoid-version -diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c -index 3f3394f..9d18c45 100644 ---- a/src/compositor-fbdev.c -+++ b/src/compositor-fbdev.c -@@ -45,6 +45,7 @@ - #include "libinput-seat.h" - #include "gl-renderer.h" - #include "presentation_timing-server-protocol.h" -+#include "gal2d-renderer.h" - - struct fbdev_compositor { - struct weston_compositor base; -@@ -53,7 +54,9 @@ struct fbdev_compositor { - struct udev *udev; - struct udev_input input; - int use_pixman; -+ int use_gal2d; - struct wl_listener session_listener; -+ NativeDisplayType display; - }; - - struct fbdev_screeninfo { -@@ -88,15 +91,20 @@ struct fbdev_output { - pixman_image_t *shadow_surface; - void *shadow_buf; - uint8_t depth; -+ -+ NativeDisplayType display; -+ NativeWindowType window; - }; - - struct fbdev_parameters { - int tty; - char *device; - int use_gl; -+ int use_gal2d; - }; - - struct gl_renderer_interface *gl_renderer; -+struct gal2d_renderer_interface *gal2d_renderer; - - static const char default_seat[] = "seat0"; - -@@ -471,6 +479,10 @@ fbdev_frame_buffer_destroy(struct fbdev_output *output) - strerror(errno)); - - output->fb = NULL; -+ if(output->window) -+ fbDestroyWindow(output->window); -+ if(output->display) -+ fbDestroyDisplay(output->display); - } - - static void fbdev_output_destroy(struct weston_output *base); -@@ -478,7 +490,7 @@ static void fbdev_output_disable(struct weston_output *base); - - static int - fbdev_output_create(struct fbdev_compositor *compositor, -- const char *device) -+ int x, int y, const char *device) - { - struct fbdev_output *output; - struct weston_config_section *section; -@@ -489,7 +501,7 @@ fbdev_output_create(struct fbdev_compositor *compositor, - uint32_t config_transform; - char *s; - -- weston_log("Creating fbdev output.\n"); -+ weston_log("Creating fbdev output. %s x=%d y=%d\n", device, x, y); - - output = zalloc(sizeof *output); - if (output == NULL) -@@ -542,7 +554,7 @@ fbdev_output_create(struct fbdev_compositor *compositor, - free(s); - - weston_output_init(&output->base, &compositor->base, -- 0, 0, output->fb_info.width_mm, -+ x, y, output->fb_info.width_mm, - output->fb_info.height_mm, - config_transform, - 1); -@@ -565,12 +577,43 @@ fbdev_output_create(struct fbdev_compositor *compositor, - if (compositor->use_pixman) { - if (pixman_renderer_output_create(&output->base) < 0) - goto out_shadow_surface; -- } else { -+ } -+ else if(compositor->use_gal2d) { -+ -+ char* fbenv = getenv("FB_FRAMEBUFFER_0"); -+ setenv("FB_FRAMEBUFFER_0", device, 1); -+ output->display = fbGetDisplay(compositor->base.wl_display); -+ if (output->display == NULL) { -+ fprintf(stderr, "failed to get display\n"); -+ return 0; -+ } -+ -+ output->window = fbCreateWindow(output->display, -1, -1, 0, 0); -+ if (output->window == NULL) { -+ fprintf(stderr, "failed to create window\n"); -+ return 0; -+ } -+ setenv("FB_FRAMEBUFFER_0", fbenv, 1); -+ -+ if (gal2d_renderer->output_create(&output->base, -+ output->display, -+ (NativeWindowType)output->window) < 0) { -+ weston_log("gal_renderer_output_create failed.\n"); -+ goto out_shadow_surface; -+ } -+ -+ } -+ else { - setenv("HYBRIS_EGLPLATFORM", "wayland", 1); -+ output->window = fbCreateWindow(compositor->display, -1, -1, 0, 0); -+ if (output->window == NULL) { -+ fprintf(stderr, "failed to create window\n"); -+ return 0; -+ } - if (gl_renderer->output_create(&output->base, -- (EGLNativeWindowType)NULL, NULL, -- gl_renderer->opaque_attribs, -- NULL, 0) < 0) { -+ (NativeWindowType)output->window, NULL, -+ gl_renderer->opaque_attribs, -+ NULL, 0) < 0) { - weston_log("gl_renderer_output_create failed.\n"); - goto out_shadow_surface; - } -@@ -629,7 +672,11 @@ fbdev_output_destroy(struct weston_output *base) - free(output->shadow_buf); - output->shadow_buf = NULL; - } -- } else { -+ } -+ else if (compositor->use_gal2d) { -+ gal2d_renderer->output_destroy(base); -+ } -+ else { - gl_renderer->output_destroy(base); - } - -@@ -692,7 +739,7 @@ fbdev_output_reenable(struct fbdev_compositor *compositor, - * are re-initialised. */ - device = output->device; - fbdev_output_destroy(base); -- fbdev_output_create(compositor, device); -+ fbdev_output_create(compositor, 0, 0, device); - - return 0; - } -@@ -850,7 +897,10 @@ fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[], - compositor->base.restore = fbdev_restore; - - compositor->prev_state = WESTON_COMPOSITOR_ACTIVE; -- compositor->use_pixman = !param->use_gl; -+ compositor->use_gal2d = param->use_gal2d; -+ weston_log("compositor->use_gal2d=%d\n", compositor->use_gal2d); -+ if(param->use_gl == 0 && param->use_gal2d == 0) -+ compositor->use_pixman = 1; - - for (key = KEY_F1; key < KEY_F9; key++) - weston_compositor_add_key_binding(&compositor->base, key, -@@ -860,7 +910,50 @@ fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[], - if (compositor->use_pixman) { - if (pixman_renderer_init(&compositor->base) < 0) - goto out_launcher; -- } else { -+ } -+ else if (compositor->use_gal2d) { -+ int x = 0, y = 0; -+ int i=0; -+ int count = 0; -+ int k=0, dispCount = 0; -+ char displays[5][32]; -+ gal2d_renderer = weston_load_module("gal2d-renderer.so", -+ "gal2d_renderer_interface"); -+ if (!gal2d_renderer) { -+ weston_log("could not load gal2d renderer\n"); -+ goto out_launcher; -+ } -+ -+ if (gal2d_renderer->create(&compositor->base) < 0) { -+ weston_log("gal2d_renderer_create failed.\n"); -+ goto out_launcher; -+ } -+ -+ weston_log("param->device=%s\n",param->device); -+ count = strlen(param->device); -+ -+ for(i= 0; i < count; i++) { -+ if(param->device[i] == ',') { -+ displays[dispCount][k] = '\0'; -+ dispCount++; -+ k = 0; -+ continue; -+ } -+ displays[dispCount][k++] = param->device[i]; -+ } -+ displays[dispCount][k] = '\0'; -+ dispCount++; -+ -+ for(i=0; ibase.output_list.prev, -+ struct weston_output, -+ link)->width; -+ } -+ } -+ else { - gl_renderer = weston_load_module("gl-renderer.so", - "gl_renderer_interface"); - if (!gl_renderer) { -@@ -868,17 +961,22 @@ fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[], - goto out_launcher; - } - -- if (gl_renderer->create(&compositor->base, NO_EGL_PLATFORM, -- EGL_DEFAULT_DISPLAY, -+ compositor->display = fbGetDisplay(compositor->base.wl_display); -+ if (compositor->display == NULL) { -+ weston_log("fbGetDisplay failed.\n"); -+ goto out_launcher; -+ } -+ -+ if (gl_renderer->create(&compositor->base, NO_EGL_PLATFORM, compositor->display, - gl_renderer->opaque_attribs, - NULL, 0) < 0) { - weston_log("gl_renderer_create failed.\n"); - goto out_launcher; - } - } -- -- if (fbdev_output_create(compositor, param->device) < 0) -- goto out_pixman; -+ if(!compositor->use_gal2d) -+ if (fbdev_output_create(compositor, 0, 0, param->device) < 0) -+ goto out_pixman; - - udev_input_init(&compositor->input, &compositor->base, compositor->udev, seat_id); - -@@ -911,13 +1009,20 @@ backend_init(struct wl_display *display, int *argc, char *argv[], - struct fbdev_parameters param = { - .tty = 0, /* default to current tty */ - .device = "/dev/fb0", /* default frame buffer */ -+#ifdef ENABLE_EGL -+ .use_gl = 1, -+ .use_gal2d = 0, -+#else - .use_gl = 0, -+ .use_gal2d = 1, -+#endif - }; - - const struct weston_option fbdev_options[] = { - { WESTON_OPTION_INTEGER, "tty", 0, ¶m.tty }, - { WESTON_OPTION_STRING, "device", 0, ¶m.device }, -- { WESTON_OPTION_BOOLEAN, "use-gl", 0, ¶m.use_gl }, -+ { WESTON_OPTION_INTEGER, "use-gl", 0, ¶m.use_gl }, -+ { WESTON_OPTION_INTEGER, "use-gal2d", 0, ¶m.use_gal2d }, - }; - - parse_options(fbdev_options, ARRAY_LENGTH(fbdev_options), argc, argv); -diff --git a/src/gal2d-renderer.c b/src/gal2d-renderer.c -new file mode 100644 -index 0000000..7ebbf98 ---- /dev/null -+++ b/src/gal2d-renderer.c -@@ -0,0 +1,1337 @@ -+/* -+ * Copyright (c) 2015 Freescale Semiconductor, Inc. -+ * Copyright © 2012 Intel Corporation -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and -+ * its documentation for any purpose is hereby granted without fee, provided -+ * that the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of the copyright holders not be used in -+ * advertising or publicity pertaining to distribution of the software -+ * without specific, written prior permission. The copyright holders make -+ * no representations about the suitability of this software for any -+ * purpose. It is provided "as is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#define _GNU_SOURCE -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "compositor.h" -+#include "gal2d-renderer.h" -+#include "vertex-clipping.h" -+#include "HAL/gc_hal.h" -+#include "HAL/gc_hal_raster.h" -+#include "HAL/gc_hal_eglplatform.h" -+ -+#define galONERROR(x) if(status < 0) printf("Error in function %s\n", __func__); -+ -+struct gal2d_output_state { -+ -+ int current_buffer; -+ pixman_region32_t buffer_damage[2]; -+ NativeDisplayType display; -+ gcoSURF* renderSurf; -+ gctUINT32 nNumBuffers; -+ int activebuffer; -+ gcoSURF offscreenSurface; -+ gceSURF_FORMAT format; -+ pthread_mutex_t workerMutex; -+ pthread_t workerId; -+ gctUINT32 exitWorker; -+ gctSIGNAL signal; -+ gctSIGNAL busySignal; -+ gcsHAL_INTERFACE iface; -+ int directBlit; -+ gctINT width; -+ gctINT height; -+}; -+ -+struct gal2d_surface_state { -+ float color[4]; -+ struct weston_buffer_reference buffer_ref; -+ int pitch; /* in pixels */ -+ pixman_region32_t texture_damage; -+ gcoSURF gco_Surface; -+ -+ struct weston_surface *surface; -+ struct wl_listener surface_destroy_listener; -+ struct wl_listener renderer_destroy_listener; -+}; -+ -+struct gal2d_renderer { -+ struct weston_renderer base; -+ struct wl_signal destroy_signal; -+ gcoOS gcos; -+ gcoHAL gcoHal; -+ gco2D gcoEngine2d; -+ gctPOINTER localInfo; -+}; -+ -+static int -+gal2d_renderer_create_surface(struct weston_surface *surface); -+ -+static inline struct gal2d_surface_state * -+get_surface_state(struct weston_surface *surface) -+{ -+ if (!surface->renderer_state) -+ gal2d_renderer_create_surface(surface); -+ return (struct gal2d_surface_state *)surface->renderer_state; -+} -+ -+static inline struct gal2d_renderer * -+get_renderer(struct weston_compositor *ec) -+{ -+ return (struct gal2d_renderer *)ec->renderer; -+} -+ -+ -+ -+#define max(a, b) (((a) > (b)) ? (a) : (b)) -+#define min(a, b) (((a) > (b)) ? (b) : (a)) -+/* -+ * Compute the boundary vertices of the intersection of the global coordinate -+ * aligned rectangle 'rect', and an arbitrary quadrilateral produced from -+ * 'surf_rect' when transformed from surface coordinates into global coordinates. -+ * The vertices are written to 'ex' and 'ey', and the return value is the -+ * number of vertices. Vertices are produced in clockwise winding order. -+ * Guarantees to produce either zero vertices, or 3-8 vertices with non-zero -+ * polygon area. -+ */ -+static int -+calculate_edges(struct weston_view *ev, pixman_box32_t *rect, -+ pixman_box32_t *surf_rect, float *ex, float *ey) -+{ -+ -+ struct clip_context ctx; -+ int i, n; -+ float min_x, max_x, min_y, max_y; -+ struct polygon8 surf = { -+ { surf_rect->x1, surf_rect->x2, surf_rect->x2, surf_rect->x1 }, -+ { surf_rect->y1, surf_rect->y1, surf_rect->y2, surf_rect->y2 }, -+ 4 -+ }; -+ -+ ctx.clip.x1 = rect->x1; -+ ctx.clip.y1 = rect->y1; -+ ctx.clip.x2 = rect->x2; -+ ctx.clip.y2 = rect->y2; -+ -+ /* transform surface to screen space: */ -+ for (i = 0; i < surf.n; i++) -+ weston_view_to_global_float(ev, surf.x[i], surf.y[i], -+ &surf.x[i], &surf.y[i]); -+ -+ /* find bounding box: */ -+ min_x = max_x = surf.x[0]; -+ min_y = max_y = surf.y[0]; -+ -+ for (i = 1; i < surf.n; i++) { -+ min_x = min(min_x, surf.x[i]); -+ max_x = max(max_x, surf.x[i]); -+ min_y = min(min_y, surf.y[i]); -+ max_y = max(max_y, surf.y[i]); -+ } -+ -+ /* First, simple bounding box check to discard early transformed -+ * surface rects that do not intersect with the clip region: -+ */ -+ if ((min_x >= ctx.clip.x2) || (max_x <= ctx.clip.x1) || -+ (min_y >= ctx.clip.y2) || (max_y <= ctx.clip.y1)) -+ return 0; -+ -+ /* Simple case, bounding box edges are parallel to surface edges, -+ * there will be only four edges. We just need to clip the surface -+ * vertices to the clip rect bounds: -+ */ -+ if (!ev->transform.enabled) -+ return clip_simple(&ctx, &surf, ex, ey); -+ -+ /* Transformed case: use a general polygon clipping algorithm to -+ * clip the surface rectangle with each side of 'rect'. -+ * The algorithm is Sutherland-Hodgman, as explained in -+ * http://www.codeguru.com/cpp/misc/misc/graphics/article.php/c8965/Polygon-Clipping.htm -+ * but without looking at any of that code. -+ */ -+ n = clip_transformed(&ctx, &surf, ex, ey); -+ -+ if (n < 3) -+ return 0; -+ -+ return n; -+} -+ -+ -+static inline struct gal2d_output_state * -+get_output_state(struct weston_output *output) -+{ -+ return (struct gal2d_output_state *)output->renderer_state; -+} -+ -+static gctUINT32 -+galGetStretchFactor(gctINT32 SrcSize, gctINT32 DestSize) -+{ -+ gctUINT stretchFactor; -+ if ( (SrcSize > 0) && (DestSize > 1) ) -+ { -+ stretchFactor = ((SrcSize - 1) << 16) / (DestSize - 1); -+ } -+ else -+ { -+ stretchFactor = 0; -+ } -+ return stretchFactor; -+} -+ -+static gceSTATUS -+galGetStretchFactors( -+ IN gcsRECT_PTR SrcRect, -+ IN gcsRECT_PTR DestRect, -+ OUT gctUINT32 * HorFactor, -+ OUT gctUINT32 * VerFactor -+ ) -+{ -+ if (HorFactor != gcvNULL) -+ { -+ gctINT32 src, dest; -+ -+ /* Compute width of rectangles. */ -+ gcmVERIFY_OK(gcsRECT_Width(SrcRect, &src)); -+ gcmVERIFY_OK(gcsRECT_Width(DestRect, &dest)); -+ -+ /* Compute and return horizontal stretch factor. */ -+ *HorFactor = galGetStretchFactor(src, dest); -+ } -+ -+ if (VerFactor != gcvNULL) -+ { -+ gctINT32 src, dest; -+ -+ /* Compute height of rectangles. */ -+ gcmVERIFY_OK(gcsRECT_Height(SrcRect, &src)); -+ gcmVERIFY_OK(gcsRECT_Height(DestRect, &dest)); -+ -+ /* Compute and return vertical stretch factor. */ -+ *VerFactor = galGetStretchFactor(src, dest); -+ } -+ /* Success. */ -+ return gcvSTATUS_OK; -+} -+ -+static gceSTATUS -+gal2d_getSurfaceFormat(halDISPLAY_INFO info, gceSURF_FORMAT * Format) -+{ -+ /* Get the color format. */ -+ switch (info.greenLength) -+ { -+ case 4: -+ if (info.blueOffset == 0) -+ { -+ *Format = (info.alphaLength == 0) ? gcvSURF_X4R4G4B4 : gcvSURF_A4R4G4B4; -+ } -+ else -+ { -+ *Format = (info.alphaLength == 0) ? gcvSURF_X4B4G4R4 : gcvSURF_A4B4G4R4; -+ } -+ break; -+ -+ case 5: -+ if (info.blueOffset == 0) -+ { -+ *Format = (info.alphaLength == 0) ? gcvSURF_X1R5G5B5 : gcvSURF_A1R5G5B5; -+ } -+ else -+ { -+ *Format = (info.alphaLength == 0) ? gcvSURF_X1B5G5R5 : gcvSURF_A1B5G5R5; -+ } -+ break; -+ -+ case 6: -+ *Format = gcvSURF_R5G6B5; -+ break; -+ -+ case 8: -+ if (info.blueOffset == 0) -+ { -+ *Format = (info.alphaLength == 0) ? gcvSURF_X8R8G8B8 : gcvSURF_A8R8G8B8; -+ } -+ else -+ { -+ *Format = (info.alphaLength == 0) ? gcvSURF_X8B8G8R8 : gcvSURF_A8B8G8R8; -+ } -+ break; -+ -+ default: -+ /* Unsupported color depth. */ -+ return gcvSTATUS_INVALID_ARGUMENT; -+ } -+ /* Success. */ -+ return gcvSTATUS_OK; -+} -+ -+static gceSTATUS galIsYUVFormat(IN gceSURF_FORMAT Format) -+{ -+ switch (Format) -+ { -+ case gcvSURF_YUY2: -+ case gcvSURF_UYVY: -+ case gcvSURF_I420: -+ case gcvSURF_YV12: -+ case gcvSURF_NV16: -+ case gcvSURF_NV12: -+ case gcvSURF_NV61: -+ case gcvSURF_NV21: -+ -+ return gcvSTATUS_TRUE; -+ -+ default: -+ return gcvSTATUS_FALSE; -+ } -+} -+ -+static gceSTATUS galQueryUVStride( -+ IN gceSURF_FORMAT Format, -+ IN gctUINT32 yStride, -+ OUT gctUINT32_PTR uStride, -+ OUT gctUINT32_PTR vStride -+ ) -+{ -+ switch (Format) -+ { -+ case gcvSURF_YUY2: -+ case gcvSURF_UYVY: -+ *uStride = *vStride = 0; -+ break; -+ -+ case gcvSURF_I420: -+ case gcvSURF_YV12: -+ *uStride = *vStride = yStride / 2; -+ break; -+ -+ case gcvSURF_NV16: -+ case gcvSURF_NV12: -+ case gcvSURF_NV61: -+ case gcvSURF_NV21: -+ -+ *uStride = yStride; -+ *vStride = 0; -+ break; -+ -+ default: -+ return gcvSTATUS_NOT_SUPPORTED; -+ } -+ -+ return gcvSTATUS_OK; -+} -+ -+static int -+make_current(struct gal2d_renderer *gr, gcoSURF surface) -+{ -+ gceSTATUS status = gcvSTATUS_OK; -+ gctUINT width = 0; -+ gctUINT height = 0; -+ gctINT stride = 0; -+ gctUINT32 physical[3]; -+ gctPOINTER va =0; -+ gceSURF_FORMAT format; -+ -+ if(!surface) -+ goto OnError; -+ -+ -+ gcmONERROR(gcoSURF_GetAlignedSize(surface, &width, &height, &stride)); -+ gcmONERROR(gcoSURF_GetFormat(surface, gcvNULL, &format)); -+ gcmONERROR(gcoSURF_Lock(surface, &physical[0], (gctPOINTER *)&va)); -+ gco2D_SetGenericTarget(gr->gcoEngine2d, -+ &physical[0], 1, -+ &stride, 1, -+ gcvLINEAR, format, -+ gcvSURF_0_DEGREE, width, height); -+ -+ gcmONERROR(gcoSURF_Unlock(surface, (gctPOINTER *)&va)); -+OnError: -+ galONERROR(status); -+ return status; -+} -+ -+static gceSTATUS -+gal2d_clear(struct weston_output *base) -+{ -+ struct gal2d_renderer *gr = get_renderer(base->compositor); -+ struct gal2d_output_state *go = get_output_state(base); -+ gceSTATUS status = gcvSTATUS_OK; -+ -+ gctINT stride = 0; -+ gctUINT width = 0, height = 0; -+ gcsRECT dstRect = {0}; -+ gcmONERROR(gcoSURF_GetAlignedSize(go->renderSurf[go->activebuffer], -+ &width, &height, &stride)); -+ dstRect.right = width; -+ dstRect.bottom = height; -+ gcmONERROR(gco2D_SetSource(gr->gcoEngine2d, &dstRect)); -+ gcmONERROR(gco2D_SetClipping(gr->gcoEngine2d, &dstRect)); -+ gcmONERROR(gco2D_Clear(gr->gcoEngine2d, 1, &dstRect, 0xff0000ff, 0xCC, 0xCC, go->format)); -+ gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvTRUE)); -+ -+OnError: -+ galONERROR(status); -+ -+ return status; -+} -+ -+static gcoSURF getSurfaceFromShm(struct weston_surface *es, struct weston_buffer *buffer) -+{ -+ struct gal2d_renderer *gr = get_renderer(es->compositor); -+ -+ gcoSURF surface = 0; -+ gceSURF_FORMAT format; -+ gcePOOL pool = gcvPOOL_DEFAULT; -+ -+ if (wl_shm_buffer_get_format(buffer->shm_buffer) == WL_SHM_FORMAT_XRGB8888) -+ format = gcvSURF_X8R8G8B8; -+ else -+ format = gcvSURF_A8R8G8B8; -+ -+ if(buffer->width == ((buffer->width + 0x7) & ~0x7)) -+ { -+ pool = gcvPOOL_USER; -+ } -+ -+ gcmVERIFY_OK(gcoSURF_Construct(gr->gcoHal, -+ (gctUINT) buffer->width, -+ (gctUINT) buffer->height, -+ 1, gcvSURF_BITMAP, -+ format, pool, &surface)); -+ -+ if(pool == gcvPOOL_USER) -+ { -+ gcmVERIFY_OK(gcoSURF_MapUserSurface(surface, 1, -+ (gctPOINTER)wl_shm_buffer_get_data(buffer->shm_buffer), gcvINVALID_ADDRESS)); -+ } -+ -+ return surface; -+} -+ -+static int -+gal2dBindBuffer(struct weston_surface* es) -+{ -+ struct gal2d_surface_state *gs = get_surface_state(es); -+ gceSTATUS status = gcvSTATUS_OK; -+ gcoSURF surface = gs->gco_Surface; -+ struct weston_buffer *buffer = gs->buffer_ref.buffer; -+ gcePOOL pool = gcvPOOL_DEFAULT; -+ -+ gcmVERIFY_OK(gcoSURF_QueryVidMemNode(surface, gcvNULL, -+ &pool, gcvNULL)); -+ -+ if(pool != gcvPOOL_USER) -+ { -+ gctUINT alignedWidth; -+ gctPOINTER logical = (gctPOINTER)wl_shm_buffer_get_data(buffer->shm_buffer); -+ gctPOINTER va =0; -+ -+ -+ gcmVERIFY_OK(gcoSURF_GetAlignedSize(surface, &alignedWidth, gcvNULL, gcvNULL)); -+ gcmVERIFY_OK(gcoSURF_Lock(surface, gcvNULL, (gctPOINTER *)&va)); -+ -+ if(alignedWidth == (unsigned int)buffer->width) -+ { -+ int size = wl_shm_buffer_get_stride(buffer->shm_buffer)*buffer->height; -+ memcpy(va, logical, size); -+ } -+ else -+ { -+ int i, j; -+ for (i = 0; i < buffer->height; i++) -+ { -+ for (j = 0; j < buffer->width; j++) -+ { -+ gctUINT dstOff = i * alignedWidth + j; -+ gctUINT srcOff = (i * buffer->width + j); -+ -+ memcpy(va + dstOff * 4, logical + srcOff * 4, 4); -+ } -+ } -+ } -+ gcmVERIFY_OK(gcoSURF_Unlock(surface, (gctPOINTER)va)); -+ } -+ -+ return status; -+} -+ -+static void -+gal2d_flip_surface(struct weston_output *output) -+{ -+ struct gal2d_output_state *go = get_output_state(output); -+ -+ if(go->nNumBuffers > 1) -+ { -+ gctUINT Offset; -+ gctINT X; -+ gctINT Y; -+ -+ gcmVERIFY_OK(gcoOS_GetDisplayBackbuffer(go->display, gcvNULL, -+ gcvNULL, gcvNULL, &Offset, &X, &Y)); -+ -+ gcmVERIFY_OK(gcoOS_SetDisplayVirtual(go->display, gcvNULL, -+ Offset, X, Y)); -+ } -+} -+ -+static void *gal2d_output_worker(void *arg) -+{ -+ struct weston_output *output = (struct weston_output *)arg; -+ struct gal2d_output_state *go = get_output_state(output); -+ -+ while(1) -+ { -+ if(gcoOS_WaitSignal(gcvNULL, go->signal, gcvINFINITE) == gcvSTATUS_OK ) -+ { -+ gal2d_flip_surface(output); -+ gcoOS_Signal(gcvNULL,go->busySignal, gcvTRUE); -+ } -+ pthread_mutex_lock(&go->workerMutex); -+ if(go->exitWorker == 1) -+ { -+ pthread_mutex_unlock(&go->workerMutex); -+ break; -+ } -+ pthread_mutex_unlock(&go->workerMutex); -+ } -+ return 0; -+} -+ -+static int -+update_surface(struct weston_output *output) -+{ -+ struct gal2d_renderer *gr = get_renderer(output->compositor); -+ struct gal2d_output_state *go = get_output_state(output); -+ gceSTATUS status = gcvSTATUS_OK; -+ -+ if(go->nNumBuffers == 1) -+ { -+ if(!go->directBlit && go->offscreenSurface) -+ { -+ make_current(gr, go->renderSurf[go->activebuffer]); -+ -+ gctUINT srcWidth = 0; -+ gctUINT srcHeight = 0; -+ gceSURF_FORMAT srcFormat;; -+ gcsRECT dstRect = {0}; -+ gcoSURF srcSurface = go->offscreenSurface; -+ gctUINT32 srcPhyAddr[3]; -+ gctUINT32 srcStride[3]; -+ -+ gctPOINTER va =0; -+ -+ gcmONERROR(gcoSURF_GetAlignedSize(srcSurface, &srcWidth, &srcHeight, (gctINT *)&srcStride[0])); -+ gcmONERROR(gcoSURF_GetFormat(srcSurface, gcvNULL, &srcFormat)); -+ -+ gcmONERROR(gcoSURF_Lock(srcSurface, srcPhyAddr, (gctPOINTER *)&va)); -+ gcmONERROR(gco2D_SetCurrentSourceIndex(gr->gcoEngine2d, 0U)); -+ -+ gco2D_SetGenericSource(gr->gcoEngine2d, srcPhyAddr, 1, -+ srcStride, 1, -+ gcvLINEAR, srcFormat, gcvSURF_0_DEGREE, -+ srcWidth, srcHeight); -+ -+ dstRect.left = 0; -+ dstRect.top = 0; -+ dstRect.right = srcWidth; -+ dstRect.bottom = srcHeight; -+ -+ gcmONERROR(gco2D_SetSource(gr->gcoEngine2d, &dstRect)); -+ gcmONERROR(gco2D_SetClipping(gr->gcoEngine2d, &dstRect)); -+ gcmONERROR(gco2D_Blit(gr->gcoEngine2d, 1, &dstRect, 0xCC, 0xCC, go->format)); -+ gcmONERROR(gcoSURF_Unlock(srcSurface, (gctPOINTER *)&va)); -+ } -+ gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvFALSE)); -+ } -+ else if(go->nNumBuffers > 1) -+ { -+ gcoHAL_ScheduleEvent(gr->gcoHal, &go->iface); -+ gcmVERIFY_OK(gcoHAL_Commit(gr->gcoHal, gcvFALSE)); -+ } -+OnError: -+ galONERROR(status); -+ return status; -+ } -+ -+static int -+is_view_visible(struct weston_view *view) -+{ -+ /* Return false, if surface is guaranteed to be totally obscured. */ -+ int ret; -+ pixman_region32_t unocc; -+ -+ pixman_region32_init(&unocc); -+ pixman_region32_subtract(&unocc, &view->transform.boundingbox, -+ &view->clip); -+ ret = pixman_region32_not_empty(&unocc); -+ pixman_region32_fini(&unocc); -+ -+ return ret; -+} -+ -+static int -+use_output(struct weston_output *output) -+{ -+ struct weston_compositor *compositor = output->compositor; -+ struct weston_view *view; -+ struct gal2d_output_state *go = get_output_state(output); -+ struct gal2d_renderer *gr = get_renderer(output->compositor); -+ gceSTATUS status = gcvSTATUS_OK; -+ -+ gcoSURF surface; -+ int visibleViews=0; -+ int fullscreenViews=0; -+ -+ surface = go->renderSurf[go->activebuffer]; -+ if(go->nNumBuffers == 1) -+ { -+ wl_list_for_each_reverse(view, &compositor->view_list, link) -+ if (view->plane == &compositor->primary_plane && is_view_visible(view)) -+ { -+ visibleViews++; -+ if(view->surface->width == go->width && view->surface->height == go->height) -+ { -+ pixman_box32_t *bb_rects; -+ int nbb=0; -+ bb_rects = pixman_region32_rectangles(&view->transform.boundingbox, &nbb); -+ if(nbb == 1) -+ if(bb_rects[0].x1 == 0 && bb_rects[0].y1 ==0) -+ fullscreenViews++; -+ } -+ } -+ -+ go->directBlit = ((visibleViews == 1) || (fullscreenViews > 1)); -+ -+ if(!go->directBlit) -+ { -+ surface = go->offscreenSurface; -+ } -+ } -+ make_current(gr, surface); -+ return status; -+} -+ -+static int -+gal2d_renderer_read_pixels(struct weston_output *output, -+ pixman_format_code_t format, void *pixels, -+ uint32_t x, uint32_t y, -+ uint32_t width, uint32_t height) -+{ -+ return 0; -+} -+ -+static int gal2d_int_from_double(double d) -+{ -+ return wl_fixed_to_int(wl_fixed_from_double(d)); -+} -+ -+static void -+repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2d_output_state *go, pixman_region32_t *region, -+ pixman_region32_t *surf_region){ -+ -+ struct gal2d_renderer *gr = get_renderer(ev->surface->compositor); -+ struct gal2d_surface_state *gs = get_surface_state(ev->surface); -+ -+ pixman_box32_t *rects, *surf_rects, *bb_rects; -+ int i, j, nrects, nsurf, nbb=0; -+ gceSTATUS status = gcvSTATUS_OK; -+ gcoSURF srcSurface = gs->gco_Surface; -+ gcsRECT srcRect = {0}; -+ gcsRECT dstrect = {0}; -+ gctUINT32 horFactor, verFactor; -+ int useStretch =1; -+ int useFilterBlit = 0; -+ gctUINT srcWidth = 0; -+ gctUINT srcHeight = 0; -+ gctUINT32 srcStride[3]; -+ gceSURF_FORMAT srcFormat;; -+ gctUINT32 srcPhyAddr[3]; -+ gctUINT32 dstPhyAddr[3]; -+ gctUINT dstWidth = 0; -+ gctUINT dstHeight = 0; -+ gctUINT32 dstStrides[3]; -+ gcoSURF dstsurface; -+ int geoWidth = ev->surface->width; -+ int geoheight = ev->surface->height; -+ gceTILING tiling; -+ -+ bb_rects = pixman_region32_rectangles(&ev->transform.boundingbox, &nbb); -+ -+ if(!srcSurface || nbb <= 0) -+ goto OnError; -+ rects = pixman_region32_rectangles(region, &nrects); -+ surf_rects = pixman_region32_rectangles(surf_region, &nsurf); -+ -+ gcmVERIFY_OK(gcoSURF_GetAlignedSize(srcSurface, &srcWidth, &srcHeight, (gctINT *)&srcStride[0])); -+ -+ gcmVERIFY_OK(gcoSURF_GetFormat(srcSurface, gcvNULL, &srcFormat)); -+ -+ if(galIsYUVFormat(srcFormat) == gcvSTATUS_TRUE) -+ { -+ useFilterBlit = 1; -+ } -+ -+ gcmVERIFY_OK(gcoSURF_Lock(srcSurface, &srcPhyAddr[0], gcvNULL)); -+ -+ gcmVERIFY_OK(gcoSURF_Unlock(srcSurface, gcvNULL)); -+ -+ srcRect.left = ev->geometry.x < 0.0 ? gal2d_int_from_double(fabsf(ev->geometry.x)) : 0; -+ srcRect.top = 0; /*es->geometry.y < 0.0 ? gal2d_int_from_double(fabsf(es->geometry.y)) : 0;*/ -+ srcRect.right = ev->surface->width; -+ srcRect.bottom = ev->surface->height; -+ -+ if(useFilterBlit) -+ { -+ dstsurface = go->nNumBuffers > 1 ? -+ go->renderSurf[go->activebuffer] : -+ go->offscreenSurface; -+ gcmVERIFY_OK(gcoSURF_GetAlignedSize(dstsurface, &dstWidth, &dstHeight, (gctINT *)&dstStrides)); -+ gcmVERIFY_OK(gcoSURF_Lock(dstsurface, &dstPhyAddr[0], gcvNULL)); -+ gcmVERIFY_OK(gcoSURF_Unlock(dstsurface, gcvNULL)); -+ } -+ else -+ { -+ gcoSURF_GetTiling(srcSurface, &tiling); -+ if (gcoHAL_IsFeatureAvailable(gr->gcoHal, gcvFEATURE_2D_TILING) != gcvTRUE && (tiling > gcvLINEAR)) -+ { -+ weston_log("Tiling not supported \n"); -+ status = gcvSTATUS_NOT_SUPPORTED; -+ gcmONERROR(status); -+ } -+ gco2D_SetGenericSource(gr->gcoEngine2d, srcPhyAddr, 1, -+ srcStride, 1, -+ tiling, srcFormat, gcvSURF_0_DEGREE, -+ srcWidth, srcHeight); -+ /* Setup mirror. */ -+ gcmONERROR(gco2D_SetBitBlitMirror(gr->gcoEngine2d, gcvFALSE, gcvFALSE)); -+ gcmONERROR(gco2D_SetROP(gr->gcoEngine2d, 0xCC, 0xCC)); -+ } -+ -+ for (i = 0; i < nrects; i++) -+ { -+ pixman_box32_t *rect = &rects[i]; -+ gctFLOAT min_x, max_x, min_y, max_y; -+ -+ dstrect.left = (bb_rects[0].x1 < 0) ? rect->x1 : bb_rects[0].x1; -+ dstrect.top = (bb_rects[0].y1 < 0) ? rect->y1 : bb_rects[0].y1; -+ dstrect.right = bb_rects[0].x2; -+ dstrect.bottom = bb_rects[0].y2; -+ -+ if(dstrect.right < 0 || dstrect.bottom < 0) -+ { -+ break; -+ } -+ -+ for (j = 0; j < nsurf; j++) -+ { -+ pixman_box32_t *surf_rect = &surf_rects[j]; -+ gctFLOAT ex[8], ey[8]; /* edge points in screen space */ -+ int n; -+ gcsRECT clipRect = {0}; -+ int m=0; -+ n = calculate_edges(ev, rect, surf_rect, ex, ey); -+ if (n < 3) -+ continue; -+ -+ min_x = max_x = ex[0]; -+ min_y = max_y = ey[0]; -+ for (m = 1; m < n; m++) -+ { -+ min_x = min(min_x, ex[m]); -+ max_x = max(max_x, ex[m]); -+ min_y = min(min_y, ey[m]); -+ max_y = max(max_y, ey[m]); -+ } -+ -+ clipRect.left = gal2d_int_from_double(min_x); -+ clipRect.top = gal2d_int_from_double(min_y); -+ clipRect.right = gal2d_int_from_double(max_x); -+ clipRect.bottom = gal2d_int_from_double(max_y); -+ -+ if(output->x > 0) -+ { -+ dstrect.left = dstrect.left - output->x; -+ dstrect.right = dstrect.right - output->x; -+ clipRect.left = clipRect.left - output->x; -+ clipRect.right = clipRect.right - output->x; -+ } -+ -+ dstrect.left = (dstrect.left < 0) ? 0 : dstrect.left; -+ -+ status = gco2D_SetClipping(gr->gcoEngine2d, &clipRect); -+ if(status < 0) -+ { -+ weston_log("Error in gco2D_SetClipping %s\n", __func__); -+ goto OnError; -+ } -+ -+ if(useFilterBlit) -+ { -+ gctINT srcStrideNum; -+ gctINT srcAddressNum; -+ gcmVERIFY_OK(galQueryUVStride(srcFormat, srcStride[0], -+ &srcStride[1], &srcStride[2])); -+ -+ switch (srcFormat) -+ { -+ case gcvSURF_YUY2: -+ case gcvSURF_UYVY: -+ srcStrideNum = srcAddressNum = 1; -+ break; -+ -+ case gcvSURF_I420: -+ case gcvSURF_YV12: -+ srcStrideNum = srcAddressNum = 3; -+ break; -+ -+ case gcvSURF_NV16: -+ case gcvSURF_NV12: -+ case gcvSURF_NV61: -+ case gcvSURF_NV21: -+ srcStrideNum = srcAddressNum = 2; -+ break; -+ -+ default: -+ gcmONERROR(gcvSTATUS_NOT_SUPPORTED); -+ } -+ gco2D_FilterBlitEx2(gr->gcoEngine2d, -+ srcPhyAddr, srcAddressNum, -+ srcStride, srcStrideNum, -+ gcvLINEAR, srcFormat, gcvSURF_0_DEGREE, -+ geoWidth, geoheight, &srcRect, -+ dstPhyAddr, 1, -+ dstStrides, 1, -+ gcvLINEAR, go->format, gcvSURF_0_DEGREE, -+ dstWidth, dstHeight, -+ &dstrect, gcvNULL); -+ } -+ else -+ { -+ if(useStretch) -+ gcmVERIFY_OK(galGetStretchFactors(&srcRect, &dstrect, &horFactor, &verFactor)); -+ -+ if(verFactor == 65536 && horFactor == 65536) -+ { -+ gcmVERIFY_OK(gco2D_Blit(gr->gcoEngine2d, 1, &dstrect, -+ 0xCC, 0xCC, go->format)); -+ } -+ else -+ { -+ /* Program the stretch factors. */ -+ gcmVERIFY_OK(gco2D_SetStretchFactors(gr->gcoEngine2d, horFactor, verFactor)); -+ -+ gcmVERIFY_OK(gco2D_StretchBlit(gr->gcoEngine2d, 1, &dstrect, -+ 0xCC, 0xCC, go->format)); -+ } -+ } -+ -+ if(status < 0) -+ { -+ printf("cr l=%d r=%d t=%d b=%d w=%d h=%d\n", -+ clipRect.left, clipRect.right, clipRect.top ,clipRect.bottom, -+ clipRect.right - clipRect.left, clipRect.bottom -clipRect.top); -+ printf("dr l=%d r=%d t=%d b=%d w=%d h=%d\n", -+ dstrect.left, dstrect.right, dstrect.top ,dstrect.bottom, -+ dstrect.right - dstrect.left, dstrect.bottom -dstrect.top); -+ printf("horFactor=%d, verFactor=%d\n",horFactor, verFactor); -+ -+ goto OnError; -+ } -+ } -+ } -+ -+OnError: -+ galONERROR(status); -+} -+ -+static void -+draw_view(struct weston_view *ev, struct weston_output *output, -+ pixman_region32_t *damage) /* in global coordinates */ -+{ -+ struct weston_compositor *ec = ev->surface->compositor; -+ struct gal2d_output_state *go = get_output_state(output); -+ /* repaint bounding region in global coordinates: */ -+ pixman_region32_t repaint; -+ /* non-opaque region in surface coordinates: */ -+ pixman_region32_t surface_blend; -+ pixman_region32_t *buffer_damage; -+ -+ pixman_region32_init(&repaint); -+ pixman_region32_intersect(&repaint, -+ &ev->transform.boundingbox, damage); -+ pixman_region32_subtract(&repaint, &repaint, &ev->clip); -+ -+ if (!pixman_region32_not_empty(&repaint)) -+ goto out; -+ -+ buffer_damage = &go->buffer_damage[go->current_buffer]; -+ pixman_region32_subtract(buffer_damage, buffer_damage, &repaint); -+ -+ /* blended region is whole surface minus opaque region: */ -+ pixman_region32_init_rect(&surface_blend, 0, 0, -+ ev->surface->width, ev->surface->height); -+ pixman_region32_subtract(&surface_blend, &surface_blend, &ev->surface->opaque); -+ -+ struct gal2d_renderer *gr = get_renderer(ec); -+ gco2D_SetCurrentSourceIndex(gr->gcoEngine2d, 0U); -+ -+ if (pixman_region32_not_empty(&ev->surface->opaque)) { -+ repaint_region(ev, output, go, &repaint, &ev->surface->opaque); -+ } -+ -+ if (pixman_region32_not_empty(&surface_blend)) { -+ gco2D_EnableAlphaBlend(gr->gcoEngine2d, -+ ev->alpha * 0xFF, ev->alpha * 0xFF, -+ gcvSURF_PIXEL_ALPHA_STRAIGHT, gcvSURF_PIXEL_ALPHA_STRAIGHT, -+ gcvSURF_GLOBAL_ALPHA_SCALE, gcvSURF_GLOBAL_ALPHA_SCALE, -+ gcvSURF_BLEND_STRAIGHT, gcvSURF_BLEND_INVERSED, -+ gcvSURF_COLOR_STRAIGHT, gcvSURF_COLOR_STRAIGHT); -+ -+ repaint_region(ev, output, go, &repaint, &surface_blend); -+ } -+ -+ gco2D_DisableAlphaBlend(gr->gcoEngine2d); -+ pixman_region32_fini(&surface_blend); -+ -+out: -+ pixman_region32_fini(&repaint); -+ -+} -+ -+static void -+repaint_views(struct weston_output *output, pixman_region32_t *damage) -+{ -+ struct weston_compositor *compositor = output->compositor; -+ struct weston_view *view; -+ struct gal2d_output_state *go = get_output_state(output); -+ -+ if(go->nNumBuffers > 1) -+ { -+ /*500ms is more than enough to process a frame */ -+ gcoOS_WaitSignal(gcvNULL, go->busySignal, 500); -+ } -+ go->activebuffer = (go->activebuffer+1) % go->nNumBuffers; -+ -+ wl_list_for_each_reverse(view, &compositor->view_list, link) -+ if (view->plane == &compositor->primary_plane) -+ draw_view(view, output, damage); -+} -+ -+static void -+gal2d_renderer_repaint_output(struct weston_output *output, -+ pixman_region32_t *output_damage) -+{ -+ struct gal2d_output_state *go = get_output_state(output); -+ gctUINT32 i; -+ -+ if (use_output(output) < 0) -+ return; -+ -+ for (i = 0; i < 2; i++) -+ pixman_region32_union(&go->buffer_damage[i], -+ &go->buffer_damage[i], -+ output_damage); -+ -+ pixman_region32_union(output_damage, output_damage, -+ &go->buffer_damage[go->current_buffer]); -+ -+ repaint_views(output, output_damage); -+ -+ pixman_region32_copy(&output->previous_damage, output_damage); -+ wl_signal_emit(&output->frame_signal, output); -+ -+ update_surface(output); -+ -+ go->current_buffer ^= 1; -+} -+ -+static void -+gal2d_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer) -+{ -+ gcsWL_VIV_BUFFER *vivBuffer = wl_resource_get_user_data(buffer->resource); -+ gcoSURF srcSurf = vivBuffer->surface; -+ gceSTATUS status = gcvSTATUS_OK; -+ struct gal2d_surface_state *gs = get_surface_state(es); -+ -+ if(gs->gco_Surface != gcvNULL) -+ { -+ gcmONERROR(gcoSURF_Destroy(gs->gco_Surface)); -+ } -+ -+ gs->gco_Surface = srcSurf; -+ gcoSURF_ReferenceSurface(srcSurf); -+ buffer->width = vivBuffer->width; -+ buffer->height = vivBuffer->height; -+ -+ OnError: -+ galONERROR(status); -+} -+ -+static void -+gal2d_renderer_flush_damage(struct weston_surface *surface) -+{ -+ struct gal2d_surface_state *gs = get_surface_state(surface); -+ struct weston_buffer *buffer = gs->buffer_ref.buffer; -+ struct weston_view *view; -+ int texture_used; -+ pixman_region32_union(&gs->texture_damage, -+ &gs->texture_damage, &surface->damage); -+ -+ if (!buffer) -+ return; -+ -+ texture_used = 0; -+ wl_list_for_each(view, &surface->views, surface_link) { -+ if (view->plane == &surface->compositor->primary_plane) { -+ texture_used = 1; -+ break; -+ } -+ } -+ if (!texture_used) -+ return; -+ -+ if (!pixman_region32_not_empty(&gs->texture_damage)) -+ goto done; -+ -+ if(wl_shm_buffer_get(buffer->resource)) -+ { -+ if(gs->gco_Surface==NULL) -+ { -+ gs->gco_Surface = getSurfaceFromShm(surface, buffer); -+ } -+ gal2dBindBuffer(surface); -+ } -+ else -+ gal2d_renderer_attach_egl(surface, buffer); -+ -+done: -+ pixman_region32_fini(&gs->texture_damage); -+ pixman_region32_init(&gs->texture_damage); -+ -+ weston_buffer_reference(&gs->buffer_ref, NULL); -+} -+ -+static void -+gal2d_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) -+{ -+ struct gal2d_surface_state *gs = get_surface_state(es); -+ struct wl_shm_buffer *shm_buffer; -+ weston_buffer_reference(&gs->buffer_ref, buffer); -+ -+ if(buffer==NULL) -+ return; -+ -+ shm_buffer = wl_shm_buffer_get(buffer->resource); -+ -+ if(shm_buffer) -+ { -+ buffer->width = wl_shm_buffer_get_width(shm_buffer); -+ buffer->height = wl_shm_buffer_get_height(shm_buffer); -+ buffer->shm_buffer = shm_buffer; -+ -+ if(gs->gco_Surface) -+ { -+ gcoSURF_Destroy(gs->gco_Surface); -+ gs->gco_Surface = getSurfaceFromShm(es, buffer); -+ } -+ } -+ else -+ gal2d_renderer_attach_egl(es, buffer); -+} -+ -+static void -+surface_state_destroy(struct gal2d_surface_state *gs, struct gal2d_renderer *gr) -+{ -+ if(gs->gco_Surface) -+ { -+ gcoSURF_Destroy(gs->gco_Surface); -+ } -+ wl_list_remove(&gs->surface_destroy_listener.link); -+ wl_list_remove(&gs->renderer_destroy_listener.link); -+ if(gs->surface) -+ gs->surface->renderer_state = NULL; -+ -+ weston_buffer_reference(&gs->buffer_ref, NULL); -+ free(gs); -+} -+ -+static void -+surface_state_handle_surface_destroy(struct wl_listener *listener, void *data) -+{ -+ struct gal2d_surface_state *gs; -+ struct gal2d_renderer *gr; -+ -+ gs = container_of(listener, struct gal2d_surface_state, -+ surface_destroy_listener); -+ -+ gr = get_renderer(gs->surface->compositor); -+ surface_state_destroy(gs, gr); -+} -+ -+static void -+surface_state_handle_renderer_destroy(struct wl_listener *listener, void *data) -+{ -+ struct gal2d_surface_state *gs; -+ struct gal2d_renderer *gr; -+ -+ gr = data; -+ -+ gs = container_of(listener, struct gal2d_surface_state, -+ renderer_destroy_listener); -+ -+ surface_state_destroy(gs, gr); -+} -+ -+ -+static int -+gal2d_renderer_create_surface(struct weston_surface *surface) -+{ -+ struct gal2d_surface_state *gs; -+ struct gal2d_renderer *gr = get_renderer(surface->compositor); -+ -+ gs = zalloc(sizeof *gs); -+ if (gs == NULL) -+ return -1; -+ -+ /* A buffer is never attached to solid color surfaces, yet -+ * they still go through texcoord computations. Do not divide -+ * by zero there. -+ */ -+ gs->pitch = 1; -+ -+ gs->surface = surface; -+ -+ pixman_region32_init(&gs->texture_damage); -+ surface->renderer_state = gs; -+ -+ gs->surface_destroy_listener.notify = -+ surface_state_handle_surface_destroy; -+ wl_signal_add(&surface->destroy_signal, -+ &gs->surface_destroy_listener); -+ -+ gs->renderer_destroy_listener.notify = -+ surface_state_handle_renderer_destroy; -+ wl_signal_add(&gr->destroy_signal, -+ &gs->renderer_destroy_listener); -+ -+ if (surface->buffer_ref.buffer) { -+ gal2d_renderer_attach(surface, surface->buffer_ref.buffer); -+ gal2d_renderer_flush_damage(surface); -+ } -+ -+ return 0; -+} -+ -+static void -+gal2d_renderer_surface_set_color(struct weston_surface *surface, -+ float red, float green, float blue, float alpha) -+{ -+ struct gal2d_surface_state *gs = get_surface_state(surface); -+ -+ gs->color[0] = red; -+ gs->color[1] = green; -+ gs->color[2] = blue; -+ gs->color[3] = alpha; -+} -+ -+ -+static void -+gal2d_renderer_output_destroy(struct weston_output *output) -+{ -+ struct gal2d_output_state *go = get_output_state(output); -+ gctUINT32 i; -+ -+ for (i = 0; i < 2; i++) -+ { -+ pixman_region32_fini(&go->buffer_damage[i]); -+ } -+ if(go->nNumBuffers <= 1 ) -+ { -+ if(go->offscreenSurface) -+ gcmVERIFY_OK(gcoSURF_Destroy(go->offscreenSurface)); -+ } -+ else -+ { -+ gcoOS_Signal(gcvNULL,go->signal, gcvTRUE); -+ pthread_mutex_lock(&go->workerMutex); -+ go->exitWorker = 1; -+ pthread_mutex_unlock(&go->workerMutex); -+ pthread_join(go->workerId, NULL); -+ } -+ -+ for(i=0; i < go->nNumBuffers; i++) -+ { -+ gcmVERIFY_OK(gcoSURF_Destroy(go->renderSurf[i])); -+ } -+ free(go->renderSurf); -+ go->renderSurf = gcvNULL; -+ -+ free(go); -+} -+ -+static void -+gal2d_renderer_destroy(struct weston_compositor *ec) -+{ -+ struct gal2d_renderer *gr = get_renderer(ec); -+ -+ wl_signal_emit(&gr->destroy_signal, gr); -+ free(ec->renderer); -+ ec->renderer = NULL; -+} -+ -+ -+static int -+gal2d_renderer_create(struct weston_compositor *ec) -+{ -+ struct gal2d_renderer *gr; -+ gceSTATUS status = gcvSTATUS_OK; -+ gr = malloc(sizeof *gr); -+ if (gr == NULL) -+ return -1; -+ -+ gr->base.read_pixels = gal2d_renderer_read_pixels; -+ gr->base.repaint_output = gal2d_renderer_repaint_output; -+ gr->base.flush_damage = gal2d_renderer_flush_damage; -+ gr->base.attach = gal2d_renderer_attach; -+ gr->base.surface_set_color = gal2d_renderer_surface_set_color; -+ gr->base.destroy = gal2d_renderer_destroy; -+ -+ /* Construct the gcoOS object. */ -+ gcmONERROR(gcoOS_Construct(gcvNULL, &gr->gcos)); -+ -+ /* Construct the gcoHAL object. */ -+ gcmONERROR(gcoHAL_Construct(gcvNULL, gr->gcos, &gr->gcoHal)); -+ gcmONERROR(gcoHAL_Get2DEngine(gr->gcoHal, &gr->gcoEngine2d)); -+ gcmONERROR(gcoHAL_SetHardwareType(gr->gcoHal, gcvHARDWARE_2D)); -+ -+ ec->renderer = &gr->base; -+ wl_signal_init(&gr->destroy_signal); -+OnError: -+ galONERROR(status); -+ -+ /* Return the status. */ -+ return status; -+ -+} -+ -+static int -+gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType display, -+ NativeWindowType window) -+ -+ { -+ struct gal2d_renderer *gr = get_renderer(output->compositor); -+ struct gal2d_output_state *go; -+ halDISPLAY_INFO info; -+ gctUINT32 backOffset = 0; -+ gceSTATUS status = gcvSTATUS_OK; -+ gctUINT32 i; -+ -+ go = zalloc(sizeof *go); -+ if (go == NULL) -+ return -1; -+ -+ output->renderer_state = go; -+ go->display = display; -+ gcmONERROR(gcoOS_InitLocalDisplayInfo(go->display, &gr->localInfo)); -+ -+ /* Get display information. */ -+ gcmONERROR(gcoOS_GetDisplayInfoEx2( -+ go->display, gcvNULL, gr->localInfo, -+ sizeof(info), &info)); -+ go->nNumBuffers = info.multiBuffer; -+ -+ weston_log("Number of buffers=%d\n",go->nNumBuffers); -+ -+ gcmONERROR(gal2d_getSurfaceFormat(info, &go->format)); -+ backOffset = (gctUINT32)(info.stride * info.height ); -+ -+ go->activebuffer = 0; -+ -+ go->renderSurf = malloc(sizeof(gcoSURF) * go->nNumBuffers); -+ gcoOS_GetDisplayVirtual(go->display, &go->width, &go->height); -+ gcoOS_SetSwapInterval(go->display, 1); -+ -+ /*Needed only for multi Buffer */ -+ if(go->nNumBuffers > 1) -+ { -+ gcmVERIFY_OK(gcoOS_CreateSignal(gcvNULL, gcvFALSE, -+ &go->signal)); -+ gcmVERIFY_OK(gcoOS_CreateSignal(gcvNULL, gcvFALSE, -+ &go->busySignal)); -+ -+ go->iface.command = gcvHAL_SIGNAL; -+ go->iface.u.Signal.signal = gcmPTR_TO_UINT64(go->signal); -+ go->iface.u.Signal.auxSignal = 0; -+ go->iface.u.Signal.process = gcmPTR_TO_UINT64(gcoOS_GetCurrentProcessID()); -+ go->iface.u.Signal.fromWhere = gcvKERNEL_PIXEL; -+ -+ go->exitWorker = 0; -+ pthread_create(&go->workerId, NULL, gal2d_output_worker, output); -+ pthread_mutex_init(&go->workerMutex, gcvNULL); -+ } -+ for(i=0; i < go->nNumBuffers; i++) -+ { -+ gcmONERROR(gcoSURF_Construct(gr->gcoHal, info.width, info.height, 1, -+ gcvSURF_BITMAP, go->format, gcvPOOL_USER, &go->renderSurf[i])); -+ -+ gcoSURF_MapUserSurface(go->renderSurf[i], 0,info.logical + (i * backOffset), -+ info.physical + (i * backOffset)); -+ -+ //Clear surfaces -+ make_current(gr, go->renderSurf[go->activebuffer]); -+ gal2d_clear(output); -+ gal2d_flip_surface(output); -+ } -+ if(go->nNumBuffers <= 1) -+ go->activebuffer = 0; -+ else -+ go->activebuffer = 1; -+ -+ if(go->nNumBuffers <= 1 ) -+ { -+ gcmVERIFY_OK(gcoSURF_Construct(gr->gcoHal, -+ (gctUINT) info.width, -+ (gctUINT) info.height, -+ 1, -+ gcvSURF_BITMAP, -+ go->format, -+ gcvPOOL_DEFAULT, -+ &go->offscreenSurface)); -+ make_current(gr, go->offscreenSurface); -+ gal2d_clear(output); -+ } -+ else -+ { -+ gcoOS_Signal(gcvNULL,go->busySignal, gcvTRUE); -+ } -+ -+ for (i = 0; i < 2; i++) -+ pixman_region32_init(&go->buffer_damage[i]); -+OnError: -+ galONERROR(status); -+ /* Return the status. */ -+ return status; -+ } -+ -+ WL_EXPORT struct gal2d_renderer_interface gal2d_renderer_interface = { -+ .create = gal2d_renderer_create, -+ .output_create = gal2d_renderer_output_create, -+ .output_destroy = gal2d_renderer_output_destroy, -+}; -diff --git a/src/gal2d-renderer.h b/src/gal2d-renderer.h -new file mode 100644 -index 0000000..fefcfd1 ---- /dev/null -+++ b/src/gal2d-renderer.h -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (c) 2015 Freescale Semiconductor, Inc. -+ * Copyright © 2013 Vasily Khoruzhick -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and -+ * its documentation for any purpose is hereby granted without fee, provided -+ * that the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of the copyright holders not be used in -+ * advertising or publicity pertaining to distribution of the software -+ * without specific, written prior permission. The copyright holders make -+ * no representations about the suitability of this software for any -+ * purpose. It is provided "as is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+#ifndef __gal_2d_renderer_h_ -+#define __gal_2d_renderer_h_ -+ -+#include "compositor.h" -+#ifdef ENABLE_EGL -+#include -+#else -+#include -+typedef HALNativeDisplayType NativeDisplayType; -+typedef HALNativeWindowType NativeWindowType; -+#endif -+ -+ -+struct gal2d_renderer_interface { -+ -+ int (*create)(struct weston_compositor *ec); -+ -+ int (*output_create)(struct weston_output *output, -+ NativeDisplayType display, -+ NativeWindowType window); -+ -+ void (*output_destroy)(struct weston_output *output); -+}; -+ -+#endif --- -2.3.6 - 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 @@ +From e766967ae24d15048c01d03de09fc39757d13ec3 Mon Sep 17 00:00:00 2001 +From: Prabhu +Date: Sat, 3 Oct 2015 19:44:33 -0500 +Subject: [PATCH] MGS-1111: Add GPU-VIV suport for wayland and weston 1.9 + +Add support GPU-VIV support for weston 1.9 + +Signed-off-by: Prabhu +--- + Makefile.am | 12 + + src/compositor-fbdev.c | 128 ++++- + src/gal2d-renderer.c | 1342 ++++++++++++++++++++++++++++++++++++++++++++++++ + src/gal2d-renderer.h | 50 ++ + 4 files changed, 1519 insertions(+), 13 deletions(-) + create mode 100644 src/gal2d-renderer.c + create mode 100644 src/gal2d-renderer.h + +diff --git a/Makefile.am b/Makefile.am +index 62719c9..86d3dfa 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -214,6 +214,18 @@ gl_renderer_la_SOURCES = \ + src/vertex-clipping.h \ + shared/helpers.h + endif ++module_LTLIBRARIES += gal2d-renderer.la ++gal2d_renderer_la_LDFLAGS = -module -avoid-version ++gal2d_renderer_la_LIBADD = $(COMPOSITOR_LIBS) $(EGL_LIBS) ++gal2d_renderer_la_CFLAGS = \ ++ $(COMPOSITOR_CFLAGS) \ ++ $(EGL_CFLAGS) \ ++ $(GCC_CFLAGS) ++gal2d_renderer_la_SOURCES = \ ++ src/gal2d-renderer.h \ ++ src/gal2d-renderer.c \ ++ src/vertex-clipping.c \ ++ src/vertex-clipping.h + + if ENABLE_X11_COMPOSITOR + module_LTLIBRARIES += x11-backend.la +diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c +index 81281d0..c6f732e 100644 +--- a/src/compositor-fbdev.c ++++ b/src/compositor-fbdev.c +@@ -49,6 +49,7 @@ + #include "libinput-seat.h" + #include "gl-renderer.h" + #include "presentation_timing-server-protocol.h" ++#include "gal2d-renderer.h" + + struct fbdev_backend { + struct weston_backend base; +@@ -58,7 +59,9 @@ struct fbdev_backend { + struct udev *udev; + struct udev_input input; + int use_pixman; ++ int use_gal2d; + struct wl_listener session_listener; ++ NativeDisplayType display; + }; + + struct fbdev_screeninfo { +@@ -93,15 +96,20 @@ struct fbdev_output { + pixman_image_t *shadow_surface; + void *shadow_buf; + uint8_t depth; ++ ++ NativeDisplayType display; ++ NativeWindowType window; + }; + + struct fbdev_parameters { + int tty; + char *device; + int use_gl; ++ int use_gal2d; + }; + + struct gl_renderer_interface *gl_renderer; ++struct gal2d_renderer_interface *gal2d_renderer; + + static const char default_seat[] = "seat0"; + +@@ -476,6 +484,10 @@ fbdev_frame_buffer_destroy(struct fbdev_output *output) + strerror(errno)); + + output->fb = NULL; ++ if(output->window) ++ fbDestroyWindow(output->window); ++ if(output->display) ++ fbDestroyDisplay(output->display); + } + + static void fbdev_output_destroy(struct weston_output *base); +@@ -483,7 +495,7 @@ static void fbdev_output_disable(struct weston_output *base); + + static int + fbdev_output_create(struct fbdev_backend *backend, +- const char *device) ++ int x, int y, const char *device) + { + struct fbdev_output *output; + struct weston_config_section *section; +@@ -494,7 +506,7 @@ fbdev_output_create(struct fbdev_backend *backend, + uint32_t config_transform; + char *s; + +- weston_log("Creating fbdev output.\n"); ++ weston_log("Creating fbdev output. %s x=%d y=%d\n", device, x, y); + + output = zalloc(sizeof *output); + if (output == NULL) +@@ -547,7 +559,7 @@ fbdev_output_create(struct fbdev_backend *backend, + free(s); + + weston_output_init(&output->base, backend->compositor, +- 0, 0, output->fb_info.width_mm, ++ x, y, output->fb_info.width_mm, + output->fb_info.height_mm, + config_transform, + 1); +@@ -570,10 +582,41 @@ fbdev_output_create(struct fbdev_backend *backend, + if (backend->use_pixman) { + if (pixman_renderer_output_create(&output->base) < 0) + goto out_shadow_surface; +- } else { ++ } ++ else if(backend->use_gal2d) { ++ ++ char* fbenv = getenv("FB_FRAMEBUFFER_0"); ++ setenv("FB_FRAMEBUFFER_0", device, 1); ++ output->display = fbGetDisplay(backend->compositor->wl_display); ++ if (output->display == NULL) { ++ fprintf(stderr, "failed to get display\n"); ++ return 0; ++ } ++ ++ output->window = fbCreateWindow(output->display, -1, -1, 0, 0); ++ if (output->window == NULL) { ++ fprintf(stderr, "failed to create window\n"); ++ return 0; ++ } ++ setenv("FB_FRAMEBUFFER_0", fbenv, 1); ++ ++ if (gal2d_renderer->output_create(&output->base, ++ output->display, ++ (NativeWindowType)output->window) < 0) { ++ weston_log("gal_renderer_output_create failed.\n"); ++ goto out_shadow_surface; ++ } ++ ++ } ++ else { + setenv("HYBRIS_EGLPLATFORM", "wayland", 1); ++ output->window = fbCreateWindow(backend->display, -1, -1, 0, 0); ++ if (output->window == NULL) { ++ fprintf(stderr, "failed to create window\n"); ++ return 0; ++ } + if (gl_renderer->output_create(&output->base, +- (EGLNativeWindowType)NULL, NULL, ++ (EGLNativeWindowType)output->window, NULL, + gl_renderer->opaque_attribs, + NULL, 0) < 0) { + weston_log("gl_renderer_output_create failed.\n"); +@@ -634,7 +677,11 @@ fbdev_output_destroy(struct weston_output *base) + free(output->shadow_buf); + output->shadow_buf = NULL; + } +- } else { ++ } ++ else if (backend->use_gal2d) { ++ gal2d_renderer->output_destroy(base); ++ } ++ else { + gl_renderer->output_destroy(base); + } + +@@ -697,7 +744,7 @@ fbdev_output_reenable(struct fbdev_backend *backend, + * are re-initialised. */ + device = output->device; + fbdev_output_destroy(base); +- fbdev_output_create(backend, device); ++ fbdev_output_create(backend, 0, 0, device); + + return 0; + } +@@ -863,7 +910,50 @@ fbdev_backend_create(struct weston_compositor *compositor, int *argc, char *argv + if (backend->use_pixman) { + if (pixman_renderer_init(compositor) < 0) + goto out_launcher; +- } else { ++ } ++ else if (backend->use_gal2d) { ++ int x = 0, y = 0; ++ int i=0; ++ int count = 0; ++ int k=0, dispCount = 0; ++ char displays[5][32]; ++ gal2d_renderer = weston_load_module("gal2d-renderer.so", ++ "gal2d_renderer_interface"); ++ if (!gal2d_renderer) { ++ weston_log("could not load gal2d renderer\n"); ++ goto out_launcher; ++ } ++ ++ if (gal2d_renderer->create(backend->compositor) < 0) { ++ weston_log("gal2d_renderer_create failed.\n"); ++ goto out_launcher; ++ } ++ ++ weston_log("param->device=%s\n",param->device); ++ count = strlen(param->device); ++ ++ for(i= 0; i < count; i++) { ++ if(param->device[i] == ',') { ++ displays[dispCount][k] = '\0'; ++ dispCount++; ++ k = 0; ++ continue; ++ } ++ displays[dispCount][k++] = param->device[i]; ++ } ++ displays[dispCount][k] = '\0'; ++ dispCount++; ++ ++ for(i=0; icompositor->output_list.prev, ++ struct weston_output, ++ link)->width; ++ } ++ } ++ else { + gl_renderer = weston_load_module("gl-renderer.so", + "gl_renderer_interface"); + if (!gl_renderer) { +@@ -871,17 +961,22 @@ fbdev_backend_create(struct weston_compositor *compositor, int *argc, char *argv + goto out_launcher; + } + ++ backend->display = fbGetDisplay(backend->compositor->wl_display); ++ if (backend->display == NULL) { ++ weston_log("fbGetDisplay failed.\n"); ++ goto out_launcher; ++ } + if (gl_renderer->create(compositor, NO_EGL_PLATFORM, +- EGL_DEFAULT_DISPLAY, ++ backend->display, + gl_renderer->opaque_attribs, + NULL, 0) < 0) { + weston_log("gl_renderer_create failed.\n"); + goto out_launcher; + } + } +- +- if (fbdev_output_create(backend, param->device) < 0) +- goto out_launcher; ++ if(!backend->use_gal2d) ++ if (fbdev_output_create(backend, 0, 0, param->device) < 0) ++ goto out_launcher; + + udev_input_init(&backend->input, compositor, backend->udev, seat_id); + +@@ -911,13 +1006,20 @@ backend_init(struct weston_compositor *compositor, int *argc, char *argv[], + struct fbdev_parameters param = { + .tty = 0, /* default to current tty */ + .device = "/dev/fb0", /* default frame buffer */ ++#ifdef ENABLE_EGL ++ .use_gl = 1, ++ .use_gal2d = 0, ++#else + .use_gl = 0, ++ .use_gal2d = 1, ++#endif + }; + + const struct weston_option fbdev_options[] = { + { WESTON_OPTION_INTEGER, "tty", 0, ¶m.tty }, + { WESTON_OPTION_STRING, "device", 0, ¶m.device }, +- { WESTON_OPTION_BOOLEAN, "use-gl", 0, ¶m.use_gl }, ++ { WESTON_OPTION_INTEGER, "use-gl", 0, ¶m.use_gl }, ++ { WESTON_OPTION_INTEGER, "use-gal2d", 0, ¶m.use_gal2d }, + }; + + parse_options(fbdev_options, ARRAY_LENGTH(fbdev_options), argc, argv); +diff --git a/src/gal2d-renderer.c b/src/gal2d-renderer.c +new file mode 100644 +index 0000000..c68f02c +--- /dev/null ++++ b/src/gal2d-renderer.c +@@ -0,0 +1,1342 @@ ++/* ++ * Copyright (c) 2015 Freescale Semiconductor, Inc. ++ * Copyright © 2012 Intel Corporation ++ * Copyright © 2015 Collabora, Ltd. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "compositor.h" ++#include "gal2d-renderer.h" ++#include "vertex-clipping.h" ++#include "shared/helpers.h" ++#include "HAL/gc_hal.h" ++#include "HAL/gc_hal_raster.h" ++#include "HAL/gc_hal_eglplatform.h" ++ ++#define galONERROR(x) if(status < 0) printf("Error in function %s\n", __func__); ++ ++struct gal2d_output_state { ++ ++ int current_buffer; ++ pixman_region32_t buffer_damage[2]; ++ NativeDisplayType display; ++ gcoSURF* renderSurf; ++ gctUINT32 nNumBuffers; ++ int activebuffer; ++ gcoSURF offscreenSurface; ++ gceSURF_FORMAT format; ++ pthread_mutex_t workerMutex; ++ pthread_t workerId; ++ gctUINT32 exitWorker; ++ gctSIGNAL signal; ++ gctSIGNAL busySignal; ++ gcsHAL_INTERFACE iface; ++ int directBlit; ++ gctINT width; ++ gctINT height; ++}; ++ ++struct gal2d_surface_state { ++ float color[4]; ++ struct weston_buffer_reference buffer_ref; ++ int pitch; /* in pixels */ ++ pixman_region32_t texture_damage; ++ gcoSURF gco_Surface; ++ ++ struct weston_surface *surface; ++ struct wl_listener surface_destroy_listener; ++ struct wl_listener renderer_destroy_listener; ++}; ++ ++struct gal2d_renderer { ++ struct weston_renderer base; ++ struct wl_signal destroy_signal; ++ gcoOS gcos; ++ gcoHAL gcoHal; ++ gco2D gcoEngine2d; ++ gctPOINTER localInfo; ++}; ++ ++static int ++gal2d_renderer_create_surface(struct weston_surface *surface); ++ ++static inline struct gal2d_surface_state * ++get_surface_state(struct weston_surface *surface) ++{ ++ if (!surface->renderer_state) ++ gal2d_renderer_create_surface(surface); ++ return (struct gal2d_surface_state *)surface->renderer_state; ++} ++ ++static inline struct gal2d_renderer * ++get_renderer(struct weston_compositor *ec) ++{ ++ return (struct gal2d_renderer *)ec->renderer; ++} ++ ++ ++ ++#define max(a, b) (((a) > (b)) ? (a) : (b)) ++#define min(a, b) (((a) > (b)) ? (b) : (a)) ++/* ++ * Compute the boundary vertices of the intersection of the global coordinate ++ * aligned rectangle 'rect', and an arbitrary quadrilateral produced from ++ * 'surf_rect' when transformed from surface coordinates into global coordinates. ++ * The vertices are written to 'ex' and 'ey', and the return value is the ++ * number of vertices. Vertices are produced in clockwise winding order. ++ * Guarantees to produce either zero vertices, or 3-8 vertices with non-zero ++ * polygon area. ++ */ ++static int ++calculate_edges(struct weston_view *ev, pixman_box32_t *rect, ++ pixman_box32_t *surf_rect, float *ex, float *ey) ++{ ++ ++ struct clip_context ctx; ++ int i, n; ++ float min_x, max_x, min_y, max_y; ++ struct polygon8 surf = { ++ { surf_rect->x1, surf_rect->x2, surf_rect->x2, surf_rect->x1 }, ++ { surf_rect->y1, surf_rect->y1, surf_rect->y2, surf_rect->y2 }, ++ 4 ++ }; ++ ++ ctx.clip.x1 = rect->x1; ++ ctx.clip.y1 = rect->y1; ++ ctx.clip.x2 = rect->x2; ++ ctx.clip.y2 = rect->y2; ++ ++ /* transform surface to screen space: */ ++ for (i = 0; i < surf.n; i++) ++ weston_view_to_global_float(ev, surf.x[i], surf.y[i], ++ &surf.x[i], &surf.y[i]); ++ ++ /* find bounding box: */ ++ min_x = max_x = surf.x[0]; ++ min_y = max_y = surf.y[0]; ++ ++ for (i = 1; i < surf.n; i++) { ++ min_x = min(min_x, surf.x[i]); ++ max_x = max(max_x, surf.x[i]); ++ min_y = min(min_y, surf.y[i]); ++ max_y = max(max_y, surf.y[i]); ++ } ++ ++ /* First, simple bounding box check to discard early transformed ++ * surface rects that do not intersect with the clip region: ++ */ ++ if ((min_x >= ctx.clip.x2) || (max_x <= ctx.clip.x1) || ++ (min_y >= ctx.clip.y2) || (max_y <= ctx.clip.y1)) ++ return 0; ++ ++ /* Simple case, bounding box edges are parallel to surface edges, ++ * there will be only four edges. We just need to clip the surface ++ * vertices to the clip rect bounds: ++ */ ++ if (!ev->transform.enabled) ++ return clip_simple(&ctx, &surf, ex, ey); ++ ++ /* Transformed case: use a general polygon clipping algorithm to ++ * clip the surface rectangle with each side of 'rect'. ++ * The algorithm is Sutherland-Hodgman, as explained in ++ * http://www.codeguru.com/cpp/misc/misc/graphics/article.php/c8965/Polygon-Clipping.htm ++ * but without looking at any of that code. ++ */ ++ n = clip_transformed(&ctx, &surf, ex, ey); ++ ++ if (n < 3) ++ return 0; ++ ++ return n; ++} ++ ++ ++static inline struct gal2d_output_state * ++get_output_state(struct weston_output *output) ++{ ++ return (struct gal2d_output_state *)output->renderer_state; ++} ++ ++static gctUINT32 ++galGetStretchFactor(gctINT32 SrcSize, gctINT32 DestSize) ++{ ++ gctUINT stretchFactor; ++ if ( (SrcSize > 0) && (DestSize > 1) ) ++ { ++ stretchFactor = ((SrcSize - 1) << 16) / (DestSize - 1); ++ } ++ else ++ { ++ stretchFactor = 0; ++ } ++ return stretchFactor; ++} ++ ++static gceSTATUS ++galGetStretchFactors( ++ IN gcsRECT_PTR SrcRect, ++ IN gcsRECT_PTR DestRect, ++ OUT gctUINT32 * HorFactor, ++ OUT gctUINT32 * VerFactor ++ ) ++{ ++ if (HorFactor != gcvNULL) ++ { ++ gctINT32 src, dest; ++ ++ /* Compute width of rectangles. */ ++ gcmVERIFY_OK(gcsRECT_Width(SrcRect, &src)); ++ gcmVERIFY_OK(gcsRECT_Width(DestRect, &dest)); ++ ++ /* Compute and return horizontal stretch factor. */ ++ *HorFactor = galGetStretchFactor(src, dest); ++ } ++ ++ if (VerFactor != gcvNULL) ++ { ++ gctINT32 src, dest; ++ ++ /* Compute height of rectangles. */ ++ gcmVERIFY_OK(gcsRECT_Height(SrcRect, &src)); ++ gcmVERIFY_OK(gcsRECT_Height(DestRect, &dest)); ++ ++ /* Compute and return vertical stretch factor. */ ++ *VerFactor = galGetStretchFactor(src, dest); ++ } ++ /* Success. */ ++ return gcvSTATUS_OK; ++} ++ ++static gceSTATUS ++gal2d_getSurfaceFormat(halDISPLAY_INFO info, gceSURF_FORMAT * Format) ++{ ++ /* Get the color format. */ ++ switch (info.greenLength) ++ { ++ case 4: ++ if (info.blueOffset == 0) ++ { ++ *Format = (info.alphaLength == 0) ? gcvSURF_X4R4G4B4 : gcvSURF_A4R4G4B4; ++ } ++ else ++ { ++ *Format = (info.alphaLength == 0) ? gcvSURF_X4B4G4R4 : gcvSURF_A4B4G4R4; ++ } ++ break; ++ ++ case 5: ++ if (info.blueOffset == 0) ++ { ++ *Format = (info.alphaLength == 0) ? gcvSURF_X1R5G5B5 : gcvSURF_A1R5G5B5; ++ } ++ else ++ { ++ *Format = (info.alphaLength == 0) ? gcvSURF_X1B5G5R5 : gcvSURF_A1B5G5R5; ++ } ++ break; ++ ++ case 6: ++ *Format = gcvSURF_R5G6B5; ++ break; ++ ++ case 8: ++ if (info.blueOffset == 0) ++ { ++ *Format = (info.alphaLength == 0) ? gcvSURF_X8R8G8B8 : gcvSURF_A8R8G8B8; ++ } ++ else ++ { ++ *Format = (info.alphaLength == 0) ? gcvSURF_X8B8G8R8 : gcvSURF_A8B8G8R8; ++ } ++ break; ++ ++ default: ++ /* Unsupported color depth. */ ++ return gcvSTATUS_INVALID_ARGUMENT; ++ } ++ /* Success. */ ++ return gcvSTATUS_OK; ++} ++ ++static gceSTATUS galIsYUVFormat(IN gceSURF_FORMAT Format) ++{ ++ switch (Format) ++ { ++ case gcvSURF_YUY2: ++ case gcvSURF_UYVY: ++ case gcvSURF_I420: ++ case gcvSURF_YV12: ++ case gcvSURF_NV16: ++ case gcvSURF_NV12: ++ case gcvSURF_NV61: ++ case gcvSURF_NV21: ++ ++ return gcvSTATUS_TRUE; ++ ++ default: ++ return gcvSTATUS_FALSE; ++ } ++} ++ ++static gceSTATUS galQueryUVStride( ++ IN gceSURF_FORMAT Format, ++ IN gctUINT32 yStride, ++ OUT gctUINT32_PTR uStride, ++ OUT gctUINT32_PTR vStride ++ ) ++{ ++ switch (Format) ++ { ++ case gcvSURF_YUY2: ++ case gcvSURF_UYVY: ++ *uStride = *vStride = 0; ++ break; ++ ++ case gcvSURF_I420: ++ case gcvSURF_YV12: ++ *uStride = *vStride = yStride / 2; ++ break; ++ ++ case gcvSURF_NV16: ++ case gcvSURF_NV12: ++ case gcvSURF_NV61: ++ case gcvSURF_NV21: ++ ++ *uStride = yStride; ++ *vStride = 0; ++ break; ++ ++ default: ++ return gcvSTATUS_NOT_SUPPORTED; ++ } ++ ++ return gcvSTATUS_OK; ++} ++ ++static int ++make_current(struct gal2d_renderer *gr, gcoSURF surface) ++{ ++ gceSTATUS status = gcvSTATUS_OK; ++ gctUINT width = 0; ++ gctUINT height = 0; ++ gctINT stride = 0; ++ gctUINT32 physical[3]; ++ gctPOINTER va =0; ++ gceSURF_FORMAT format; ++ ++ if(!surface) ++ goto OnError; ++ ++ ++ gcmONERROR(gcoSURF_GetAlignedSize(surface, &width, &height, &stride)); ++ gcmONERROR(gcoSURF_GetFormat(surface, gcvNULL, &format)); ++ gcmONERROR(gcoSURF_Lock(surface, &physical[0], (gctPOINTER *)&va)); ++ gco2D_SetGenericTarget(gr->gcoEngine2d, ++ &physical[0], 1, ++ &stride, 1, ++ gcvLINEAR, format, ++ gcvSURF_0_DEGREE, width, height); ++ ++ gcmONERROR(gcoSURF_Unlock(surface, (gctPOINTER *)&va)); ++OnError: ++ galONERROR(status); ++ return status; ++} ++ ++static gceSTATUS ++gal2d_clear(struct weston_output *base) ++{ ++ struct gal2d_renderer *gr = get_renderer(base->compositor); ++ struct gal2d_output_state *go = get_output_state(base); ++ gceSTATUS status = gcvSTATUS_OK; ++ ++ gctINT stride = 0; ++ gctUINT width = 0, height = 0; ++ gcsRECT dstRect = {0}; ++ gcmONERROR(gcoSURF_GetAlignedSize(go->renderSurf[go->activebuffer], ++ &width, &height, &stride)); ++ dstRect.right = width; ++ dstRect.bottom = height; ++ gcmONERROR(gco2D_SetSource(gr->gcoEngine2d, &dstRect)); ++ gcmONERROR(gco2D_SetClipping(gr->gcoEngine2d, &dstRect)); ++ gcmONERROR(gco2D_Clear(gr->gcoEngine2d, 1, &dstRect, 0xff0000ff, 0xCC, 0xCC, go->format)); ++ gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvTRUE)); ++ ++OnError: ++ galONERROR(status); ++ ++ return status; ++} ++ ++static gcoSURF getSurfaceFromShm(struct weston_surface *es, struct weston_buffer *buffer) ++{ ++ struct gal2d_renderer *gr = get_renderer(es->compositor); ++ ++ gcoSURF surface = 0; ++ gceSURF_FORMAT format; ++ gcePOOL pool = gcvPOOL_DEFAULT; ++ ++ if (wl_shm_buffer_get_format(buffer->shm_buffer) == WL_SHM_FORMAT_XRGB8888) ++ format = gcvSURF_X8R8G8B8; ++ else ++ format = gcvSURF_A8R8G8B8; ++ ++ if(buffer->width == ((buffer->width + 0x7) & ~0x7)) ++ { ++ pool = gcvPOOL_USER; ++ } ++ ++ gcmVERIFY_OK(gcoSURF_Construct(gr->gcoHal, ++ (gctUINT) buffer->width, ++ (gctUINT) buffer->height, ++ 1, gcvSURF_BITMAP, ++ format, pool, &surface)); ++ ++ if(pool == gcvPOOL_USER) ++ { ++ gcmVERIFY_OK(gcoSURF_MapUserSurface(surface, 1, ++ (gctPOINTER)wl_shm_buffer_get_data(buffer->shm_buffer), gcvINVALID_ADDRESS)); ++ } ++ ++ return surface; ++} ++ ++static int ++gal2dBindBuffer(struct weston_surface* es) ++{ ++ struct gal2d_surface_state *gs = get_surface_state(es); ++ gceSTATUS status = gcvSTATUS_OK; ++ gcoSURF surface = gs->gco_Surface; ++ struct weston_buffer *buffer = gs->buffer_ref.buffer; ++ gcePOOL pool = gcvPOOL_DEFAULT; ++ ++ gcmVERIFY_OK(gcoSURF_QueryVidMemNode(surface, gcvNULL, ++ &pool, gcvNULL)); ++ ++ if(pool != gcvPOOL_USER) ++ { ++ gctUINT alignedWidth; ++ gctPOINTER logical = (gctPOINTER)wl_shm_buffer_get_data(buffer->shm_buffer); ++ gctPOINTER va =0; ++ ++ ++ gcmVERIFY_OK(gcoSURF_GetAlignedSize(surface, &alignedWidth, gcvNULL, gcvNULL)); ++ gcmVERIFY_OK(gcoSURF_Lock(surface, gcvNULL, (gctPOINTER *)&va)); ++ ++ if(alignedWidth == (unsigned int)buffer->width) ++ { ++ int size = wl_shm_buffer_get_stride(buffer->shm_buffer)*buffer->height; ++ memcpy(va, logical, size); ++ } ++ else ++ { ++ int i, j; ++ for (i = 0; i < buffer->height; i++) ++ { ++ for (j = 0; j < buffer->width; j++) ++ { ++ gctUINT dstOff = i * alignedWidth + j; ++ gctUINT srcOff = (i * buffer->width + j); ++ ++ memcpy(va + dstOff * 4, logical + srcOff * 4, 4); ++ } ++ } ++ } ++ gcmVERIFY_OK(gcoSURF_Unlock(surface, (gctPOINTER)va)); ++ } ++ ++ return status; ++} ++ ++static void ++gal2d_flip_surface(struct weston_output *output) ++{ ++ struct gal2d_output_state *go = get_output_state(output); ++ ++ if(go->nNumBuffers > 1) ++ { ++ gctUINT Offset; ++ gctINT X; ++ gctINT Y; ++ ++ gcmVERIFY_OK(gcoOS_GetDisplayBackbuffer(go->display, gcvNULL, ++ gcvNULL, gcvNULL, &Offset, &X, &Y)); ++ ++ gcmVERIFY_OK(gcoOS_SetDisplayVirtual(go->display, gcvNULL, ++ Offset, X, Y)); ++ } ++} ++ ++static void *gal2d_output_worker(void *arg) ++{ ++ struct weston_output *output = (struct weston_output *)arg; ++ struct gal2d_output_state *go = get_output_state(output); ++ ++ while(1) ++ { ++ if(gcoOS_WaitSignal(gcvNULL, go->signal, gcvINFINITE) == gcvSTATUS_OK ) ++ { ++ gal2d_flip_surface(output); ++ gcoOS_Signal(gcvNULL,go->busySignal, gcvTRUE); ++ } ++ pthread_mutex_lock(&go->workerMutex); ++ if(go->exitWorker == 1) ++ { ++ pthread_mutex_unlock(&go->workerMutex); ++ break; ++ } ++ pthread_mutex_unlock(&go->workerMutex); ++ } ++ return 0; ++} ++ ++static int ++update_surface(struct weston_output *output) ++{ ++ struct gal2d_renderer *gr = get_renderer(output->compositor); ++ struct gal2d_output_state *go = get_output_state(output); ++ gceSTATUS status = gcvSTATUS_OK; ++ ++ if(go->nNumBuffers == 1) ++ { ++ if(!go->directBlit && go->offscreenSurface) ++ { ++ make_current(gr, go->renderSurf[go->activebuffer]); ++ ++ gctUINT srcWidth = 0; ++ gctUINT srcHeight = 0; ++ gceSURF_FORMAT srcFormat;; ++ gcsRECT dstRect = {0}; ++ gcoSURF srcSurface = go->offscreenSurface; ++ gctUINT32 srcPhyAddr[3]; ++ gctUINT32 srcStride[3]; ++ ++ gctPOINTER va =0; ++ ++ gcmONERROR(gcoSURF_GetAlignedSize(srcSurface, &srcWidth, &srcHeight, (gctINT *)&srcStride[0])); ++ gcmONERROR(gcoSURF_GetFormat(srcSurface, gcvNULL, &srcFormat)); ++ ++ gcmONERROR(gcoSURF_Lock(srcSurface, srcPhyAddr, (gctPOINTER *)&va)); ++ gcmONERROR(gco2D_SetCurrentSourceIndex(gr->gcoEngine2d, 0U)); ++ ++ gco2D_SetGenericSource(gr->gcoEngine2d, srcPhyAddr, 1, ++ srcStride, 1, ++ gcvLINEAR, srcFormat, gcvSURF_0_DEGREE, ++ srcWidth, srcHeight); ++ ++ dstRect.left = 0; ++ dstRect.top = 0; ++ dstRect.right = srcWidth; ++ dstRect.bottom = srcHeight; ++ ++ gcmONERROR(gco2D_SetSource(gr->gcoEngine2d, &dstRect)); ++ gcmONERROR(gco2D_SetClipping(gr->gcoEngine2d, &dstRect)); ++ gcmONERROR(gco2D_Blit(gr->gcoEngine2d, 1, &dstRect, 0xCC, 0xCC, go->format)); ++ gcmONERROR(gcoSURF_Unlock(srcSurface, (gctPOINTER *)&va)); ++ } ++ gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvFALSE)); ++ } ++ else if(go->nNumBuffers > 1) ++ { ++ gcoHAL_ScheduleEvent(gr->gcoHal, &go->iface); ++ gcmVERIFY_OK(gcoHAL_Commit(gr->gcoHal, gcvFALSE)); ++ } ++OnError: ++ galONERROR(status); ++ return status; ++ } ++ ++static int ++is_view_visible(struct weston_view *view) ++{ ++ /* Return false, if surface is guaranteed to be totally obscured. */ ++ int ret; ++ pixman_region32_t unocc; ++ ++ pixman_region32_init(&unocc); ++ pixman_region32_subtract(&unocc, &view->transform.boundingbox, ++ &view->clip); ++ ret = pixman_region32_not_empty(&unocc); ++ pixman_region32_fini(&unocc); ++ ++ return ret; ++} ++ ++static int ++use_output(struct weston_output *output) ++{ ++ struct weston_compositor *compositor = output->compositor; ++ struct weston_view *view; ++ struct gal2d_output_state *go = get_output_state(output); ++ struct gal2d_renderer *gr = get_renderer(output->compositor); ++ gceSTATUS status = gcvSTATUS_OK; ++ ++ gcoSURF surface; ++ int visibleViews=0; ++ int fullscreenViews=0; ++ ++ surface = go->renderSurf[go->activebuffer]; ++ if(go->nNumBuffers == 1) ++ { ++ wl_list_for_each_reverse(view, &compositor->view_list, link) ++ if (view->plane == &compositor->primary_plane && is_view_visible(view)) ++ { ++ visibleViews++; ++ if(view->surface->width == go->width && view->surface->height == go->height) ++ { ++ pixman_box32_t *bb_rects; ++ int nbb=0; ++ bb_rects = pixman_region32_rectangles(&view->transform.boundingbox, &nbb); ++ if(nbb == 1) ++ if(bb_rects[0].x1 == 0 && bb_rects[0].y1 ==0) ++ fullscreenViews++; ++ } ++ } ++ ++ go->directBlit = ((visibleViews == 1) || (fullscreenViews > 1)); ++ ++ if(!go->directBlit) ++ { ++ surface = go->offscreenSurface; ++ } ++ } ++ make_current(gr, surface); ++ return status; ++} ++ ++static int ++gal2d_renderer_read_pixels(struct weston_output *output, ++ pixman_format_code_t format, void *pixels, ++ uint32_t x, uint32_t y, ++ uint32_t width, uint32_t height) ++{ ++ return 0; ++} ++ ++static int gal2d_int_from_double(double d) ++{ ++ return wl_fixed_to_int(wl_fixed_from_double(d)); ++} ++ ++static void ++repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2d_output_state *go, pixman_region32_t *region, ++ pixman_region32_t *surf_region){ ++ ++ struct gal2d_renderer *gr = get_renderer(ev->surface->compositor); ++ struct gal2d_surface_state *gs = get_surface_state(ev->surface); ++ ++ pixman_box32_t *rects, *surf_rects, *bb_rects; ++ int i, j, nrects, nsurf, nbb=0; ++ gceSTATUS status = gcvSTATUS_OK; ++ gcoSURF srcSurface = gs->gco_Surface; ++ gcsRECT srcRect = {0}; ++ gcsRECT dstrect = {0}; ++ gctUINT32 horFactor, verFactor; ++ int useStretch =1; ++ int useFilterBlit = 0; ++ gctUINT srcWidth = 0; ++ gctUINT srcHeight = 0; ++ gctUINT32 srcStride[3]; ++ gceSURF_FORMAT srcFormat;; ++ gctUINT32 srcPhyAddr[3]; ++ gctUINT32 dstPhyAddr[3]; ++ gctUINT dstWidth = 0; ++ gctUINT dstHeight = 0; ++ gctUINT32 dstStrides[3]; ++ gcoSURF dstsurface; ++ int geoWidth = ev->surface->width; ++ int geoheight = ev->surface->height; ++ gceTILING tiling; ++ ++ bb_rects = pixman_region32_rectangles(&ev->transform.boundingbox, &nbb); ++ ++ if(!srcSurface || nbb <= 0) ++ goto OnError; ++ rects = pixman_region32_rectangles(region, &nrects); ++ surf_rects = pixman_region32_rectangles(surf_region, &nsurf); ++ ++ gcmVERIFY_OK(gcoSURF_GetAlignedSize(srcSurface, &srcWidth, &srcHeight, (gctINT *)&srcStride[0])); ++ ++ gcmVERIFY_OK(gcoSURF_GetFormat(srcSurface, gcvNULL, &srcFormat)); ++ ++ if(galIsYUVFormat(srcFormat) == gcvSTATUS_TRUE) ++ { ++ useFilterBlit = 1; ++ } ++ ++ gcmVERIFY_OK(gcoSURF_Lock(srcSurface, &srcPhyAddr[0], gcvNULL)); ++ ++ gcmVERIFY_OK(gcoSURF_Unlock(srcSurface, gcvNULL)); ++ ++ srcRect.left = ev->geometry.x < 0.0 ? gal2d_int_from_double(fabsf(ev->geometry.x)) : 0; ++ srcRect.top = 0; /*es->geometry.y < 0.0 ? gal2d_int_from_double(fabsf(es->geometry.y)) : 0;*/ ++ srcRect.right = ev->surface->width; ++ srcRect.bottom = ev->surface->height; ++ ++ if(useFilterBlit) ++ { ++ dstsurface = go->nNumBuffers > 1 ? ++ go->renderSurf[go->activebuffer] : ++ go->offscreenSurface; ++ gcmVERIFY_OK(gcoSURF_GetAlignedSize(dstsurface, &dstWidth, &dstHeight, (gctINT *)&dstStrides)); ++ gcmVERIFY_OK(gcoSURF_Lock(dstsurface, &dstPhyAddr[0], gcvNULL)); ++ gcmVERIFY_OK(gcoSURF_Unlock(dstsurface, gcvNULL)); ++ } ++ else ++ { ++ gcoSURF_GetTiling(srcSurface, &tiling); ++ if (gcoHAL_IsFeatureAvailable(gr->gcoHal, gcvFEATURE_2D_TILING) != gcvTRUE && (tiling > gcvLINEAR)) ++ { ++ weston_log("Tiling not supported \n"); ++ status = gcvSTATUS_NOT_SUPPORTED; ++ gcmONERROR(status); ++ } ++ gco2D_SetGenericSource(gr->gcoEngine2d, srcPhyAddr, 1, ++ srcStride, 1, ++ tiling, srcFormat, gcvSURF_0_DEGREE, ++ srcWidth, srcHeight); ++ /* Setup mirror. */ ++ gcmONERROR(gco2D_SetBitBlitMirror(gr->gcoEngine2d, gcvFALSE, gcvFALSE)); ++ gcmONERROR(gco2D_SetROP(gr->gcoEngine2d, 0xCC, 0xCC)); ++ } ++ ++ for (i = 0; i < nrects; i++) ++ { ++ pixman_box32_t *rect = &rects[i]; ++ gctFLOAT min_x, max_x, min_y, max_y; ++ ++ dstrect.left = (bb_rects[0].x1 < 0) ? rect->x1 : bb_rects[0].x1; ++ dstrect.top = (bb_rects[0].y1 < 0) ? rect->y1 : bb_rects[0].y1; ++ dstrect.right = bb_rects[0].x2; ++ dstrect.bottom = bb_rects[0].y2; ++ ++ if(dstrect.right < 0 || dstrect.bottom < 0) ++ { ++ break; ++ } ++ ++ for (j = 0; j < nsurf; j++) ++ { ++ pixman_box32_t *surf_rect = &surf_rects[j]; ++ gctFLOAT ex[8], ey[8]; /* edge points in screen space */ ++ int n; ++ gcsRECT clipRect = {0}; ++ int m=0; ++ n = calculate_edges(ev, rect, surf_rect, ex, ey); ++ if (n < 3) ++ continue; ++ ++ min_x = max_x = ex[0]; ++ min_y = max_y = ey[0]; ++ for (m = 1; m < n; m++) ++ { ++ min_x = min(min_x, ex[m]); ++ max_x = max(max_x, ex[m]); ++ min_y = min(min_y, ey[m]); ++ max_y = max(max_y, ey[m]); ++ } ++ ++ clipRect.left = gal2d_int_from_double(min_x); ++ clipRect.top = gal2d_int_from_double(min_y); ++ clipRect.right = gal2d_int_from_double(max_x); ++ clipRect.bottom = gal2d_int_from_double(max_y); ++ ++ if(output->x > 0) ++ { ++ dstrect.left = dstrect.left - output->x; ++ dstrect.right = dstrect.right - output->x; ++ clipRect.left = clipRect.left - output->x; ++ clipRect.right = clipRect.right - output->x; ++ } ++ ++ dstrect.left = (dstrect.left < 0) ? 0 : dstrect.left; ++ ++ status = gco2D_SetClipping(gr->gcoEngine2d, &clipRect); ++ if(status < 0) ++ { ++ weston_log("Error in gco2D_SetClipping %s\n", __func__); ++ goto OnError; ++ } ++ ++ if(useFilterBlit) ++ { ++ gctINT srcStrideNum; ++ gctINT srcAddressNum; ++ gcmVERIFY_OK(galQueryUVStride(srcFormat, srcStride[0], ++ &srcStride[1], &srcStride[2])); ++ ++ switch (srcFormat) ++ { ++ case gcvSURF_YUY2: ++ case gcvSURF_UYVY: ++ srcStrideNum = srcAddressNum = 1; ++ break; ++ ++ case gcvSURF_I420: ++ case gcvSURF_YV12: ++ srcStrideNum = srcAddressNum = 3; ++ break; ++ ++ case gcvSURF_NV16: ++ case gcvSURF_NV12: ++ case gcvSURF_NV61: ++ case gcvSURF_NV21: ++ srcStrideNum = srcAddressNum = 2; ++ break; ++ ++ default: ++ gcmONERROR(gcvSTATUS_NOT_SUPPORTED); ++ } ++ gco2D_FilterBlitEx2(gr->gcoEngine2d, ++ srcPhyAddr, srcAddressNum, ++ srcStride, srcStrideNum, ++ gcvLINEAR, srcFormat, gcvSURF_0_DEGREE, ++ geoWidth, geoheight, &srcRect, ++ dstPhyAddr, 1, ++ dstStrides, 1, ++ gcvLINEAR, go->format, gcvSURF_0_DEGREE, ++ dstWidth, dstHeight, ++ &dstrect, gcvNULL); ++ } ++ else ++ { ++ if(useStretch) ++ gcmVERIFY_OK(galGetStretchFactors(&srcRect, &dstrect, &horFactor, &verFactor)); ++ ++ if(verFactor == 65536 && horFactor == 65536) ++ { ++ gcmVERIFY_OK(gco2D_Blit(gr->gcoEngine2d, 1, &dstrect, ++ 0xCC, 0xCC, go->format)); ++ } ++ else ++ { ++ /* Program the stretch factors. */ ++ gcmVERIFY_OK(gco2D_SetStretchFactors(gr->gcoEngine2d, horFactor, verFactor)); ++ ++ gcmVERIFY_OK(gco2D_StretchBlit(gr->gcoEngine2d, 1, &dstrect, ++ 0xCC, 0xCC, go->format)); ++ } ++ } ++ ++ if(status < 0) ++ { ++ printf("cr l=%d r=%d t=%d b=%d w=%d h=%d\n", ++ clipRect.left, clipRect.right, clipRect.top ,clipRect.bottom, ++ clipRect.right - clipRect.left, clipRect.bottom -clipRect.top); ++ printf("dr l=%d r=%d t=%d b=%d w=%d h=%d\n", ++ dstrect.left, dstrect.right, dstrect.top ,dstrect.bottom, ++ dstrect.right - dstrect.left, dstrect.bottom -dstrect.top); ++ printf("horFactor=%d, verFactor=%d\n",horFactor, verFactor); ++ ++ goto OnError; ++ } ++ } ++ } ++ ++OnError: ++ galONERROR(status); ++} ++ ++static void ++draw_view(struct weston_view *ev, struct weston_output *output, ++ pixman_region32_t *damage) /* in global coordinates */ ++{ ++ struct weston_compositor *ec = ev->surface->compositor; ++ struct gal2d_output_state *go = get_output_state(output); ++ /* repaint bounding region in global coordinates: */ ++ pixman_region32_t repaint; ++ /* non-opaque region in surface coordinates: */ ++ pixman_region32_t surface_blend; ++ pixman_region32_t *buffer_damage; ++ ++ pixman_region32_init(&repaint); ++ pixman_region32_intersect(&repaint, ++ &ev->transform.boundingbox, damage); ++ pixman_region32_subtract(&repaint, &repaint, &ev->clip); ++ ++ if (!pixman_region32_not_empty(&repaint)) ++ goto out; ++ ++ buffer_damage = &go->buffer_damage[go->current_buffer]; ++ pixman_region32_subtract(buffer_damage, buffer_damage, &repaint); ++ ++ /* blended region is whole surface minus opaque region: */ ++ pixman_region32_init_rect(&surface_blend, 0, 0, ++ ev->surface->width, ev->surface->height); ++ pixman_region32_subtract(&surface_blend, &surface_blend, &ev->surface->opaque); ++ ++ struct gal2d_renderer *gr = get_renderer(ec); ++ gco2D_SetCurrentSourceIndex(gr->gcoEngine2d, 0U); ++ ++ if (pixman_region32_not_empty(&ev->surface->opaque)) { ++ repaint_region(ev, output, go, &repaint, &ev->surface->opaque); ++ } ++ ++ if (pixman_region32_not_empty(&surface_blend)) { ++ gco2D_EnableAlphaBlend(gr->gcoEngine2d, ++ ev->alpha * 0xFF, ev->alpha * 0xFF, ++ gcvSURF_PIXEL_ALPHA_STRAIGHT, gcvSURF_PIXEL_ALPHA_STRAIGHT, ++ gcvSURF_GLOBAL_ALPHA_SCALE, gcvSURF_GLOBAL_ALPHA_SCALE, ++ gcvSURF_BLEND_STRAIGHT, gcvSURF_BLEND_INVERSED, ++ gcvSURF_COLOR_STRAIGHT, gcvSURF_COLOR_STRAIGHT); ++ ++ repaint_region(ev, output, go, &repaint, &surface_blend); ++ } ++ ++ gco2D_DisableAlphaBlend(gr->gcoEngine2d); ++ pixman_region32_fini(&surface_blend); ++ ++out: ++ pixman_region32_fini(&repaint); ++ ++} ++ ++static void ++repaint_views(struct weston_output *output, pixman_region32_t *damage) ++{ ++ struct weston_compositor *compositor = output->compositor; ++ struct weston_view *view; ++ struct gal2d_output_state *go = get_output_state(output); ++ ++ if(go->nNumBuffers > 1) ++ { ++ /*500ms is more than enough to process a frame */ ++ gcoOS_WaitSignal(gcvNULL, go->busySignal, 500); ++ } ++ go->activebuffer = (go->activebuffer+1) % go->nNumBuffers; ++ ++ wl_list_for_each_reverse(view, &compositor->view_list, link) ++ if (view->plane == &compositor->primary_plane) ++ draw_view(view, output, damage); ++} ++ ++static void ++gal2d_renderer_repaint_output(struct weston_output *output, ++ pixman_region32_t *output_damage) ++{ ++ struct gal2d_output_state *go = get_output_state(output); ++ gctUINT32 i; ++ ++ if (use_output(output) < 0) ++ return; ++ ++ for (i = 0; i < 2; i++) ++ pixman_region32_union(&go->buffer_damage[i], ++ &go->buffer_damage[i], ++ output_damage); ++ ++ pixman_region32_union(output_damage, output_damage, ++ &go->buffer_damage[go->current_buffer]); ++ ++ repaint_views(output, output_damage); ++ ++ pixman_region32_copy(&output->previous_damage, output_damage); ++ wl_signal_emit(&output->frame_signal, output); ++ ++ update_surface(output); ++ ++ go->current_buffer ^= 1; ++} ++ ++static void ++gal2d_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer) ++{ ++ gcsWL_VIV_BUFFER *vivBuffer = wl_resource_get_user_data(buffer->resource); ++ gcoSURF srcSurf = vivBuffer->surface; ++ gceSTATUS status = gcvSTATUS_OK; ++ struct gal2d_surface_state *gs = get_surface_state(es); ++ ++ if(gs->gco_Surface != gcvNULL) ++ { ++ gcmONERROR(gcoSURF_Destroy(gs->gco_Surface)); ++ } ++ ++ gs->gco_Surface = srcSurf; ++ gcoSURF_ReferenceSurface(srcSurf); ++ buffer->width = vivBuffer->width; ++ buffer->height = vivBuffer->height; ++ ++ OnError: ++ galONERROR(status); ++} ++ ++static void ++gal2d_renderer_flush_damage(struct weston_surface *surface) ++{ ++ struct gal2d_surface_state *gs = get_surface_state(surface); ++ struct weston_buffer *buffer = gs->buffer_ref.buffer; ++ struct weston_view *view; ++ int texture_used; ++ pixman_region32_union(&gs->texture_damage, ++ &gs->texture_damage, &surface->damage); ++ ++ if (!buffer) ++ return; ++ ++ texture_used = 0; ++ wl_list_for_each(view, &surface->views, surface_link) { ++ if (view->plane == &surface->compositor->primary_plane) { ++ texture_used = 1; ++ break; ++ } ++ } ++ if (!texture_used) ++ return; ++ ++ if (!pixman_region32_not_empty(&gs->texture_damage)) ++ goto done; ++ ++ if(wl_shm_buffer_get(buffer->resource)) ++ { ++ if(gs->gco_Surface==NULL) ++ { ++ gs->gco_Surface = getSurfaceFromShm(surface, buffer); ++ } ++ gal2dBindBuffer(surface); ++ } ++ else ++ gal2d_renderer_attach_egl(surface, buffer); ++ ++done: ++ pixman_region32_fini(&gs->texture_damage); ++ pixman_region32_init(&gs->texture_damage); ++ ++ weston_buffer_reference(&gs->buffer_ref, NULL); ++} ++ ++static void ++gal2d_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) ++{ ++ struct gal2d_surface_state *gs = get_surface_state(es); ++ struct wl_shm_buffer *shm_buffer; ++ weston_buffer_reference(&gs->buffer_ref, buffer); ++ ++ if(buffer==NULL) ++ return; ++ ++ shm_buffer = wl_shm_buffer_get(buffer->resource); ++ ++ if(shm_buffer) ++ { ++ buffer->width = wl_shm_buffer_get_width(shm_buffer); ++ buffer->height = wl_shm_buffer_get_height(shm_buffer); ++ buffer->shm_buffer = shm_buffer; ++ ++ if(gs->gco_Surface) ++ { ++ gcoSURF_Destroy(gs->gco_Surface); ++ gs->gco_Surface = getSurfaceFromShm(es, buffer); ++ } ++ } ++ else ++ gal2d_renderer_attach_egl(es, buffer); ++} ++ ++static void ++surface_state_destroy(struct gal2d_surface_state *gs, struct gal2d_renderer *gr) ++{ ++ if(gs->gco_Surface) ++ { ++ gcoSURF_Destroy(gs->gco_Surface); ++ } ++ wl_list_remove(&gs->surface_destroy_listener.link); ++ wl_list_remove(&gs->renderer_destroy_listener.link); ++ if(gs->surface) ++ gs->surface->renderer_state = NULL; ++ ++ weston_buffer_reference(&gs->buffer_ref, NULL); ++ free(gs); ++} ++ ++static void ++surface_state_handle_surface_destroy(struct wl_listener *listener, void *data) ++{ ++ struct gal2d_surface_state *gs; ++ struct gal2d_renderer *gr; ++ ++ gs = container_of(listener, struct gal2d_surface_state, ++ surface_destroy_listener); ++ ++ gr = get_renderer(gs->surface->compositor); ++ surface_state_destroy(gs, gr); ++} ++ ++static void ++surface_state_handle_renderer_destroy(struct wl_listener *listener, void *data) ++{ ++ struct gal2d_surface_state *gs; ++ struct gal2d_renderer *gr; ++ ++ gr = data; ++ ++ gs = container_of(listener, struct gal2d_surface_state, ++ renderer_destroy_listener); ++ ++ surface_state_destroy(gs, gr); ++} ++ ++ ++static int ++gal2d_renderer_create_surface(struct weston_surface *surface) ++{ ++ struct gal2d_surface_state *gs; ++ struct gal2d_renderer *gr = get_renderer(surface->compositor); ++ ++ gs = zalloc(sizeof *gs); ++ if (gs == NULL) ++ return -1; ++ ++ /* A buffer is never attached to solid color surfaces, yet ++ * they still go through texcoord computations. Do not divide ++ * by zero there. ++ */ ++ gs->pitch = 1; ++ ++ gs->surface = surface; ++ ++ pixman_region32_init(&gs->texture_damage); ++ surface->renderer_state = gs; ++ ++ gs->surface_destroy_listener.notify = ++ surface_state_handle_surface_destroy; ++ wl_signal_add(&surface->destroy_signal, ++ &gs->surface_destroy_listener); ++ ++ gs->renderer_destroy_listener.notify = ++ surface_state_handle_renderer_destroy; ++ wl_signal_add(&gr->destroy_signal, ++ &gs->renderer_destroy_listener); ++ ++ if (surface->buffer_ref.buffer) { ++ gal2d_renderer_attach(surface, surface->buffer_ref.buffer); ++ gal2d_renderer_flush_damage(surface); ++ } ++ ++ return 0; ++} ++ ++static void ++gal2d_renderer_surface_set_color(struct weston_surface *surface, ++ float red, float green, float blue, float alpha) ++{ ++ struct gal2d_surface_state *gs = get_surface_state(surface); ++ ++ gs->color[0] = red; ++ gs->color[1] = green; ++ gs->color[2] = blue; ++ gs->color[3] = alpha; ++} ++ ++ ++static void ++gal2d_renderer_output_destroy(struct weston_output *output) ++{ ++ struct gal2d_output_state *go = get_output_state(output); ++ gctUINT32 i; ++ ++ for (i = 0; i < 2; i++) ++ { ++ pixman_region32_fini(&go->buffer_damage[i]); ++ } ++ if(go->nNumBuffers <= 1 ) ++ { ++ if(go->offscreenSurface) ++ gcmVERIFY_OK(gcoSURF_Destroy(go->offscreenSurface)); ++ } ++ else ++ { ++ gcoOS_Signal(gcvNULL,go->signal, gcvTRUE); ++ pthread_mutex_lock(&go->workerMutex); ++ go->exitWorker = 1; ++ pthread_mutex_unlock(&go->workerMutex); ++ pthread_join(go->workerId, NULL); ++ } ++ ++ for(i=0; i < go->nNumBuffers; i++) ++ { ++ gcmVERIFY_OK(gcoSURF_Destroy(go->renderSurf[i])); ++ } ++ free(go->renderSurf); ++ go->renderSurf = gcvNULL; ++ ++ free(go); ++} ++ ++static void ++gal2d_renderer_destroy(struct weston_compositor *ec) ++{ ++ struct gal2d_renderer *gr = get_renderer(ec); ++ ++ wl_signal_emit(&gr->destroy_signal, gr); ++ free(ec->renderer); ++ ec->renderer = NULL; ++} ++ ++ ++static int ++gal2d_renderer_create(struct weston_compositor *ec) ++{ ++ struct gal2d_renderer *gr; ++ gceSTATUS status = gcvSTATUS_OK; ++ gr = malloc(sizeof *gr); ++ if (gr == NULL) ++ return -1; ++ ++ gr->base.read_pixels = gal2d_renderer_read_pixels; ++ gr->base.repaint_output = gal2d_renderer_repaint_output; ++ gr->base.flush_damage = gal2d_renderer_flush_damage; ++ gr->base.attach = gal2d_renderer_attach; ++ gr->base.surface_set_color = gal2d_renderer_surface_set_color; ++ gr->base.destroy = gal2d_renderer_destroy; ++ ++ /* Construct the gcoOS object. */ ++ gcmONERROR(gcoOS_Construct(gcvNULL, &gr->gcos)); ++ ++ /* Construct the gcoHAL object. */ ++ gcmONERROR(gcoHAL_Construct(gcvNULL, gr->gcos, &gr->gcoHal)); ++ gcmONERROR(gcoHAL_Get2DEngine(gr->gcoHal, &gr->gcoEngine2d)); ++ gcmONERROR(gcoHAL_SetHardwareType(gr->gcoHal, gcvHARDWARE_2D)); ++ ++ ec->renderer = &gr->base; ++ wl_signal_init(&gr->destroy_signal); ++OnError: ++ galONERROR(status); ++ ++ /* Return the status. */ ++ return status; ++ ++} ++ ++static int ++gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType display, ++ NativeWindowType window) ++ ++ { ++ struct gal2d_renderer *gr = get_renderer(output->compositor); ++ struct gal2d_output_state *go; ++ halDISPLAY_INFO info; ++ gctUINT32 backOffset = 0; ++ gceSTATUS status = gcvSTATUS_OK; ++ gctUINT32 i; ++ ++ go = zalloc(sizeof *go); ++ if (go == NULL) ++ return -1; ++ ++ output->renderer_state = go; ++ go->display = display; ++ gcmONERROR(gcoOS_InitLocalDisplayInfo(go->display, &gr->localInfo)); ++ ++ /* Get display information. */ ++ gcmONERROR(gcoOS_GetDisplayInfoEx2( ++ go->display, gcvNULL, gr->localInfo, ++ sizeof(info), &info)); ++ go->nNumBuffers = info.multiBuffer; ++ ++ weston_log("Number of buffers=%d\n",go->nNumBuffers); ++ ++ gcmONERROR(gal2d_getSurfaceFormat(info, &go->format)); ++ backOffset = (gctUINT32)(info.stride * info.height ); ++ ++ go->activebuffer = 0; ++ ++ go->renderSurf = malloc(sizeof(gcoSURF) * go->nNumBuffers); ++ gcoOS_GetDisplayVirtual(go->display, &go->width, &go->height); ++ gcoOS_SetSwapInterval(go->display, 1); ++ ++ /*Needed only for multi Buffer */ ++ if(go->nNumBuffers > 1) ++ { ++ gcmVERIFY_OK(gcoOS_CreateSignal(gcvNULL, gcvFALSE, ++ &go->signal)); ++ gcmVERIFY_OK(gcoOS_CreateSignal(gcvNULL, gcvFALSE, ++ &go->busySignal)); ++ ++ go->iface.command = gcvHAL_SIGNAL; ++ go->iface.u.Signal.signal = gcmPTR_TO_UINT64(go->signal); ++ go->iface.u.Signal.auxSignal = 0; ++ go->iface.u.Signal.process = gcmPTR_TO_UINT64(gcoOS_GetCurrentProcessID()); ++ go->iface.u.Signal.fromWhere = gcvKERNEL_PIXEL; ++ ++ go->exitWorker = 0; ++ pthread_create(&go->workerId, NULL, gal2d_output_worker, output); ++ pthread_mutex_init(&go->workerMutex, gcvNULL); ++ } ++ for(i=0; i < go->nNumBuffers; i++) ++ { ++ gcmONERROR(gcoSURF_Construct(gr->gcoHal, info.width, info.height, 1, ++ gcvSURF_BITMAP, go->format, gcvPOOL_USER, &go->renderSurf[i])); ++ ++ gcoSURF_MapUserSurface(go->renderSurf[i], 0,info.logical + (i * backOffset), ++ info.physical + (i * backOffset)); ++ ++ //Clear surfaces ++ make_current(gr, go->renderSurf[go->activebuffer]); ++ gal2d_clear(output); ++ gal2d_flip_surface(output); ++ } ++ if(go->nNumBuffers <= 1) ++ go->activebuffer = 0; ++ else ++ go->activebuffer = 1; ++ ++ if(go->nNumBuffers <= 1 ) ++ { ++ gcmVERIFY_OK(gcoSURF_Construct(gr->gcoHal, ++ (gctUINT) info.width, ++ (gctUINT) info.height, ++ 1, ++ gcvSURF_BITMAP, ++ go->format, ++ gcvPOOL_DEFAULT, ++ &go->offscreenSurface)); ++ make_current(gr, go->offscreenSurface); ++ gal2d_clear(output); ++ } ++ else ++ { ++ gcoOS_Signal(gcvNULL,go->busySignal, gcvTRUE); ++ } ++ ++ for (i = 0; i < 2; i++) ++ pixman_region32_init(&go->buffer_damage[i]); ++OnError: ++ galONERROR(status); ++ /* Return the status. */ ++ return status; ++ } ++ ++ WL_EXPORT struct gal2d_renderer_interface gal2d_renderer_interface = { ++ .create = gal2d_renderer_create, ++ .output_create = gal2d_renderer_output_create, ++ .output_destroy = gal2d_renderer_output_destroy, ++}; +diff --git a/src/gal2d-renderer.h b/src/gal2d-renderer.h +new file mode 100644 +index 0000000..279358d +--- /dev/null ++++ b/src/gal2d-renderer.h +@@ -0,0 +1,50 @@ ++/* ++ * Copyright (c) 2015 Freescale Semiconductor, Inc. ++ * Copyright © 2013 Vasily Khoruzhick ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++#ifndef __gal_2d_renderer_h_ ++#define __gal_2d_renderer_h_ ++ ++#include "compositor.h" ++#ifdef ENABLE_EGL ++#include ++#else ++#include ++typedef HALNativeDisplayType NativeDisplayType; ++typedef HALNativeWindowType NativeWindowType; ++#endif ++ ++ ++struct gal2d_renderer_interface { ++ ++ int (*create)(struct weston_compositor *ec); ++ ++ int (*output_create)(struct weston_output *output, ++ NativeDisplayType display, ++ NativeWindowType window); ++ ++ void (*output_destroy)(struct weston_output *output); ++}; ++ ++#endif +-- +2.5.1 + diff --git a/recipes-graphics/wayland/weston/0006-MGS-1236-imx6qp-imx6dl-First-frame-distored-when-som.patch b/recipes-graphics/wayland/weston/0006-MGS-1236-imx6qp-imx6dl-First-frame-distored-when-som.patch new file mode 100644 index 00000000..bed6f0c8 --- /dev/null +++ b/recipes-graphics/wayland/weston/0006-MGS-1236-imx6qp-imx6dl-First-frame-distored-when-som.patch @@ -0,0 +1,106 @@ +From 2bd1096ac342e251980c639543c0fad2f7173e82 Mon Sep 17 00:00:00 2001 +From: Prabhu Sundararaj +Date: Wed, 9 Dec 2015 18:20:35 -0600 +Subject: [PATCH] MGS-1236 : [imx6qp/imx6dl] First frame distored when some + wayland apps run continuously using g2d + +gco2D_SetSource was missing when using the blit operations and +hence causing the issue. + +If the weston started without weston.ini, animations will be disabled, +for xwayland the weston.ini need to be included and hence the error +was shown. + +Also removing util functions reusing from libGAL.so + +Date: Dec 10, 2015 +Signed-off-by: Prabhu Sundararaj +--- + src/gal2d-renderer.c | 57 ++++++---------------------------------------------- + 1 file changed, 6 insertions(+), 51 deletions(-) + +diff --git a/src/gal2d-renderer.c b/src/gal2d-renderer.c +index 6e7d640..dbec2d0 100644 +--- a/src/gal2d-renderer.c ++++ b/src/gal2d-renderer.c +@@ -186,56 +186,6 @@ get_output_state(struct weston_output *output) + return (struct gal2d_output_state *)output->renderer_state; + } + +-static gctUINT32 +-galGetStretchFactor(gctINT32 SrcSize, gctINT32 DestSize) +-{ +- gctUINT stretchFactor; +- if ( (SrcSize > 0) && (DestSize > 1) ) +- { +- stretchFactor = ((SrcSize - 1) << 16) / (DestSize - 1); +- } +- else +- { +- stretchFactor = 0; +- } +- return stretchFactor; +-} +- +-static gceSTATUS +-galGetStretchFactors( +- IN gcsRECT_PTR SrcRect, +- IN gcsRECT_PTR DestRect, +- OUT gctUINT32 * HorFactor, +- OUT gctUINT32 * VerFactor +- ) +-{ +- if (HorFactor != gcvNULL) +- { +- gctINT32 src, dest; +- +- /* Compute width of rectangles. */ +- gcmVERIFY_OK(gcsRECT_Width(SrcRect, &src)); +- gcmVERIFY_OK(gcsRECT_Width(DestRect, &dest)); +- +- /* Compute and return horizontal stretch factor. */ +- *HorFactor = galGetStretchFactor(src, dest); +- } +- +- if (VerFactor != gcvNULL) +- { +- gctINT32 src, dest; +- +- /* Compute height of rectangles. */ +- gcmVERIFY_OK(gcsRECT_Height(SrcRect, &src)); +- gcmVERIFY_OK(gcsRECT_Height(DestRect, &dest)); +- +- /* Compute and return vertical stretch factor. */ +- *VerFactor = galGetStretchFactor(src, dest); +- } +- /* Success. */ +- return gcvSTATUS_OK; +-} +- + static gceSTATUS + gal2d_getSurfaceFormat(halDISPLAY_INFO info, gceSURF_FORMAT * Format) + { +@@ -725,6 +675,7 @@ repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2 + srcStride, 1, + tiling, srcFormat, gcvSURF_0_DEGREE, + srcWidth, srcHeight); ++ gcmVERIFY_OK(gco2D_SetSource(gr->gcoEngine2d, &srcRect)); + /* Setup mirror. */ + gcmONERROR(gco2D_SetBitBlitMirror(gr->gcoEngine2d, gcvFALSE, gcvFALSE)); + gcmONERROR(gco2D_SetROP(gr->gcoEngine2d, 0xCC, 0xCC)); +@@ -830,7 +781,11 @@ repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2 + } + else + { +- gcmVERIFY_OK(galGetStretchFactors(&srcRect, &dstrect, &horFactor, &verFactor)); ++ gcmVERIFY_OK(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.right - srcRect.left, ++ dstrect.right - dstrect.left, &horFactor)); ++ ++ gcmONERROR(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.bottom - srcRect.top, ++ dstrect.bottom - dstrect.top, &verFactor)); + + if(verFactor == 65536 && horFactor == 65536) + { +-- +2.6.2 + diff --git a/recipes-graphics/wayland/weston/0007-MGS-1236-1-imx6qp-imx6dl-First-frame-distored-when-s.patch b/recipes-graphics/wayland/weston/0007-MGS-1236-1-imx6qp-imx6dl-First-frame-distored-when-s.patch new file mode 100644 index 00000000..1c094c4d --- /dev/null +++ b/recipes-graphics/wayland/weston/0007-MGS-1236-1-imx6qp-imx6dl-First-frame-distored-when-s.patch @@ -0,0 +1,51 @@ +From b33d44b736b7b7ae4db31dc32ff9441c753219fb Mon Sep 17 00:00:00 2001 +From: Prabhu Sundararaj +Date: Mon, 28 Dec 2015 22:15:05 -0600 +Subject: [PATCH] MGS-1236-1 : [imx6qp/imx6dl] First frame distored when some + wayland apps run continuously using g2d + +Remove residual galGetStretchFactors functions. the function is not needed +any more + +Date: Dec 28, 2015 +Signed-off-by: Prabhu Sundararaj +--- + src/gal2d-renderer.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/src/gal2d-renderer.c b/src/gal2d-renderer.c +index dbec2d0..2ecc8ac 100644 +--- a/src/gal2d-renderer.c ++++ b/src/gal2d-renderer.c +@@ -781,11 +781,11 @@ repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2 + } + else + { +- gcmVERIFY_OK(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.right - srcRect.left, +- dstrect.right - dstrect.left, &horFactor)); ++ gcmVERIFY_OK(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.right - srcRect.left, ++ dstrect.right - dstrect.left, &horFactor)); + +- gcmONERROR(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.bottom - srcRect.top, +- dstrect.bottom - dstrect.top, &verFactor)); ++ gcmONERROR(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.bottom - srcRect.top, ++ dstrect.bottom - dstrect.top, &verFactor)); + + if(verFactor == 65536 && horFactor == 65536) + { +@@ -799,7 +799,11 @@ repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2 + srcRect.right = srcRect.right < dstWidth ? srcRect.right : dstWidth; + srcRect.bottom = srcRect.bottom < dstHeight ? srcRect.bottom : dstHeight; + +- gcmVERIFY_OK(galGetStretchFactors(&srcRect, &dstrect, &horFactor, &verFactor)); ++ gcmVERIFY_OK(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.right - srcRect.left, ++ dstrect.right - dstrect.left, &horFactor)); ++ ++ gcmONERROR(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.bottom - srcRect.top, ++ dstrect.bottom - dstrect.top, &verFactor)); + /* Program the stretch factors. */ + gcmVERIFY_OK(gco2D_SetStretchFactors(gr->gcoEngine2d, horFactor, verFactor)); + +-- +2.6.2 + diff --git a/recipes-graphics/wayland/weston_%.bbappend b/recipes-graphics/wayland/weston_%.bbappend index 6c8ba6d0..fae42867 100644 --- a/recipes-graphics/wayland/weston_%.bbappend +++ b/recipes-graphics/wayland/weston_%.bbappend @@ -1,10 +1,12 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" SRC_URI_append_mx6 = " \ - file://0001-MGS-840-Add-i.MX6-support-for-weston.patch \ + file://0002-MGS-1111-Add-GPU-VIV-suport-for-wayland-and-weston-1.patch \ file://0004-MGS-1235-Fix-setenv-and-clear-environments.patch \ - file://0005-MGS-1252-Fix-for-Qt5_CinematicExperience-will-meet-s.patch" - + file://0005-MGS-1252-Fix-for-Qt5_CinematicExperience-will-meet-s.patch \ + file://0006-MGS-1236-imx6qp-imx6dl-First-frame-distored-when-som.patch \ + file://0007-MGS-1236-1-imx6qp-imx6dl-First-frame-distored-when-s.patch \ + " PACKAGECONFIG_append_mx6q = " cairo-glesv2" PACKAGECONFIG_append_mx6dl = " cairo-glesv2" PACKAGECONFIG_append_mx6sx = " cairo-glesv2" -- cgit v1.2.3-54-g00ecf