From 825cb4f8cdb7ba62f7872d05ff121786c27e49ea Mon Sep 17 00:00:00 2001 From: Lauren Post Date: Wed, 8 Jul 2015 09:12:12 -0500 Subject: weston: Update i.MX6 Vivante GPU to support Wayland 1.8 Update the support patches for Weston 1.8. The support patches are consolidated in a single patch. Signed-off-by: Lauren Post Signed-off-by: Otavio Salvador --- ...01-ENGR00314805-1-Add-Vivante-EGL-support.patch | 77 - ...0001-MGS-840-Add-i.MX6-support-for-weston.patch | 1709 ++++++++++++++++++++ ...-ENGR00314805-2-Add-Vivante-GAL2D-support.patch | 1503 ----------------- ...7-Distorted-line-and-shadow-if-use-2d-com.patch | 258 --- ...20243-Enable-GAL2D-compositor-in-SoloLite.patch | 39 - ...0-Change-GAL2D-compositor-to-be-default-i.patch | 38 - ...-for-wrong-FPS-throttling-when-multibuffe.patch | 247 --- ...ton-Performance-Optimisation-for-single-b.patch | 183 --- recipes-graphics/wayland/weston_%.bbappend | 10 +- 9 files changed, 1710 insertions(+), 2354 deletions(-) delete mode 100644 recipes-graphics/wayland/weston/0001-ENGR00314805-1-Add-Vivante-EGL-support.patch create mode 100644 recipes-graphics/wayland/weston/0001-MGS-840-Add-i.MX6-support-for-weston.patch delete mode 100644 recipes-graphics/wayland/weston/0002-ENGR00314805-2-Add-Vivante-GAL2D-support.patch delete mode 100644 recipes-graphics/wayland/weston/0003-ENGR00319247-Distorted-line-and-shadow-if-use-2d-com.patch delete mode 100644 recipes-graphics/wayland/weston/0004-ENGR00320243-Enable-GAL2D-compositor-in-SoloLite.patch delete mode 100644 recipes-graphics/wayland/weston/0005-ENGR00321030-Change-GAL2D-compositor-to-be-default-i.patch delete mode 100644 recipes-graphics/wayland/weston/0006-MGS-389-Fix-for-wrong-FPS-throttling-when-multibuffe.patch delete mode 100644 recipes-graphics/wayland/weston/0007-MGS-391-Weston-Performance-Optimisation-for-single-b.patch diff --git a/recipes-graphics/wayland/weston/0001-ENGR00314805-1-Add-Vivante-EGL-support.patch b/recipes-graphics/wayland/weston/0001-ENGR00314805-1-Add-Vivante-EGL-support.patch deleted file mode 100644 index a0fcdef..0000000 --- a/recipes-graphics/wayland/weston/0001-ENGR00314805-1-Add-Vivante-EGL-support.patch +++ /dev/null @@ -1,77 +0,0 @@ -From eb738e87f131f60c89e641e619dc8b1ccc88a30b Mon Sep 17 00:00:00 2001 -From: Yong Gan -Date: Thu, 22 May 2014 15:25:42 +0800 -Subject: [PATCH] ENGR00314805-1 Add Vivante EGL support -Organization: O.S. Systems Software LTDA. - -Add Vivante EGL compositor support. - -Upstream-Status: Pending - -[DATE]05-22-2014 -Signed-off-by Yong Gan - -Signed-off-by: Otavio Salvador ---- - src/compositor-fbdev.c | 23 +++++++++++++++++++---- - 1 file changed, 19 insertions(+), 4 deletions(-) - -diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c -index e703e0e..3db1d17 100644 ---- a/src/compositor-fbdev.c -+++ b/src/compositor-fbdev.c -@@ -53,6 +53,7 @@ struct fbdev_compositor { - struct udev_input input; - int use_pixman; - struct wl_listener session_listener; -+ EGLNativeDisplayType display; - }; - - struct fbdev_screeninfo { -@@ -87,6 +88,9 @@ struct fbdev_output { - pixman_image_t *shadow_surface; - void *shadow_buf; - uint8_t depth; -+ -+ EGLNativeDisplayType display; -+ EGLNativeWindowType window; - }; - - struct fbdev_parameters { -@@ -627,10 +631,15 @@ fbdev_output_create(struct fbdev_compositor *compositor, - 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, -- gl_renderer->opaque_attribs, -- NULL) < 0) { -+ (EGLNativeWindowType)output->window, -+ gl_renderer->opaque_attribs, -+ NULL) < 0) { - weston_log("gl_renderer_output_create failed.\n"); - goto out_shadow_surface; - } -@@ -923,7 +932,13 @@ fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[], - goto out_launcher; - } - -- if (gl_renderer->create(&compositor->base, 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, compositor->display, - gl_renderer->opaque_attribs, - NULL) < 0) { - weston_log("gl_renderer_create failed.\n"); --- -2.1.4 - diff --git a/recipes-graphics/wayland/weston/0001-MGS-840-Add-i.MX6-support-for-weston.patch b/recipes-graphics/wayland/weston/0001-MGS-840-Add-i.MX6-support-for-weston.patch new file mode 100644 index 0000000..80505bd --- /dev/null +++ b/recipes-graphics/wayland/weston/0001-MGS-840-Add-i.MX6-support-for-weston.patch @@ -0,0 +1,1709 @@ +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-ENGR00314805-2-Add-Vivante-GAL2D-support.patch b/recipes-graphics/wayland/weston/0002-ENGR00314805-2-Add-Vivante-GAL2D-support.patch deleted file mode 100644 index 1cfca7b..0000000 --- a/recipes-graphics/wayland/weston/0002-ENGR00314805-2-Add-Vivante-GAL2D-support.patch +++ /dev/null @@ -1,1503 +0,0 @@ -From 8a887ec821a53f18a7530b77f08ec823ce757937 Mon Sep 17 00:00:00 2001 -From: Yong Gan -Date: Thu, 22 May 2014 15:26:31 +0800 -Subject: [PATCH] ENGR00314805-2 Add Vivante GAL2D support -Organization: O.S. Systems Software LTDA. - -Add Vivante GAL2D compositor support. - -Upstream-Status: Pending - -[DATE]05-22-2014 -Signed-off-by Yong Gan - -Signed-off-by: Otavio Salvador ---- - Makefile.am | 13 + - src/compositor-fbdev.c | 110 ++++- - src/gal2d-renderer.c | 1187 ++++++++++++++++++++++++++++++++++++++++++++++++ - src/gal2d-renderer.h | 41 ++ - 4 files changed, 1337 insertions(+), 14 deletions(-) - create mode 100644 src/gal2d-renderer.c - create mode 100644 src/gal2d-renderer.h - -diff --git a/Makefile.am b/Makefile.am -index 0c08acb..29834c3 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -165,6 +165,19 @@ gl_renderer_la_SOURCES = \ - src/gl-renderer.c \ - src/vertex-clipping.c \ - src/vertex-clipping.h -+ -+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 - endif - - if ENABLE_X11_COMPOSITOR -diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c -index 3db1d17..a3d32e5 100644 ---- a/src/compositor-fbdev.c -+++ b/src/compositor-fbdev.c -@@ -44,6 +44,7 @@ - #include "pixman-renderer.h" - #include "udev-input.h" - #include "gl-renderer.h" -+#include "gal2d-renderer.h" - - struct fbdev_compositor { - struct weston_compositor base; -@@ -52,6 +53,7 @@ struct fbdev_compositor { - struct udev *udev; - struct udev_input input; - int use_pixman; -+ int use_gal2d; - struct wl_listener session_listener; - EGLNativeDisplayType display; - }; -@@ -97,9 +99,11 @@ 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"; - -@@ -502,7 +506,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; - pixman_transform_t transform; -@@ -512,7 +516,8 @@ fbdev_output_create(struct fbdev_compositor *compositor, - unsigned int bytes_per_pixel; - struct wl_event_loop *loop; - -- weston_log("Creating fbdev output.\n"); -+ -+ weston_log("Creating fbdev output. %s x=%d y=%d\n", device, x, y); - - output = calloc(1, sizeof *output); - if (!output) -@@ -559,7 +564,7 @@ fbdev_output_create(struct fbdev_compositor *compositor, - output->base.model = output->fb_info.id; - - 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, - WL_OUTPUT_TRANSFORM_NORMAL, - 1); -@@ -629,8 +634,33 @@ fbdev_output_create(struct fbdev_compositor *compositor, - if (compositor->use_pixman) { - if (pixman_renderer_output_create(&output->base) < 0) - goto out_shadow_surface; -- } else { -- setenv("HYBRIS_EGLPLATFORM", "wayland", 1); -+ } -+ 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 { - output->window = fbCreateWindow(compositor->display, -1, -1, 0, 0); - if (output->window == NULL) { - fprintf(stderr, "failed to create window\n"); -@@ -698,7 +728,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); - } - -@@ -761,7 +795,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; - } -@@ -914,7 +948,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, -@@ -924,7 +961,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) { -@@ -945,9 +1025,9 @@ fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[], - 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); - -@@ -980,13 +1060,15 @@ 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 */ -- .use_gl = 0, -+ .use_gl = 1, -+ .use_gal2d = 0, - }; - - 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..c651573 ---- /dev/null -+++ b/src/gal2d-renderer.c -@@ -0,0 +1,1187 @@ -+/* -+ * Copyright (c) 2014 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 "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]; -+ EGLNativeDisplayType display; -+ gcoSURF* renderSurf; -+ gctUINT32 nNumBuffers; -+ int activebuffer; -+ gcoSURF offscreenSurface; -+ gceSURF_FORMAT format; -+ gcoSURF tempSurf; -+}; -+ -+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; -+ gctPOINTER va =0; -+ -+ if(!surface) -+ goto OnError; -+ -+ -+ gcmONERROR(gcoSURF_GetAlignedSize(surface, &width, &height, &stride)); -+ -+ gcmONERROR(gcoSURF_Lock(surface, &physical, (gctPOINTER *)&va)); -+ -+ gcmONERROR(gco2D_SetTargetEx(gr->gcoEngine2d, physical, stride, -+ 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, gcvFALSE)); -+ -+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; -+ gctUINT64 node = 0; -+ gctUINT bytes; -+ -+ gcmVERIFY_OK(gcoSURF_QueryVidMemNode(surface, &node, -+ &pool, &bytes)); -+ -+ 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_renderer *gr = get_renderer(output->compositor); -+ struct gal2d_output_state *go = get_output_state(output); -+ -+ if(go->nNumBuffers > 1) -+ { -+ gctUINT Offset; -+ gctINT X; -+ gctINT Y; -+ gcmVERIFY_OK(gcoHAL_Commit(gr->gcoHal, gcvTRUE)); -+ -+ gcmVERIFY_OK(gcoOS_GetDisplayBackbuffer(go->display, gcvNULL, -+ gcvNULL, gcvNULL, &Offset, &X, &Y)); -+ -+ gcmVERIFY_OK(gcoOS_SetDisplayVirtual(go->display, gcvNULL, -+ Offset, X, Y)); -+ -+ go->activebuffer = (go->activebuffer+1) % go->nNumBuffers; -+ } -+} -+ -+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->offscreenSurface && go->nNumBuffers == 1) -+ { -+ make_current(gr, go->renderSurf[go->activebuffer]); -+ -+ gctUINT srcWidth = 0; -+ gctUINT srcHeight = 0; -+ gctINT srcStride = 0; -+ gceSURF_FORMAT srcFormat;; -+ gcsRECT dstRect = {0}; -+ gcoSURF srcSurface = go->offscreenSurface; -+ gctUINT32 physical; -+ gctPOINTER va =0; -+ -+ gcmONERROR(gcoSURF_GetAlignedSize(srcSurface, &srcWidth, &srcHeight, &srcStride)); -+ gcmONERROR(gcoSURF_GetFormat(srcSurface, gcvNULL, &srcFormat)); -+ gcmONERROR(gcoSURF_Lock(srcSurface, &physical, (gctPOINTER *)&va)); -+ gcmONERROR(gco2D_SetColorSource(gr->gcoEngine2d, physical, srcStride, srcFormat, -+ gcvFALSE, srcWidth, gcvFALSE, gcvSURF_OPAQUE, 0)); -+ -+ 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)); -+ } -+ -+ gal2d_flip_surface(output); -+ -+OnError: -+ galONERROR(status); -+ return status; -+ } -+ -+static int -+use_output(struct weston_output *output) -+{ -+ struct gal2d_output_state *go = get_output_state(output); -+ struct gal2d_renderer *gr = get_renderer(output->compositor); -+ gceSTATUS status = gcvSTATUS_OK; -+ -+ gcoSURF surface; -+ surface = go->nNumBuffers > 1 ? -+ go->renderSurf[go->activebuffer] : -+ go->offscreenSurface; /*go->renderSurf[0];*/ -+ 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; -+ -+ 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 -+ { -+ gcmVERIFY_OK(gco2D_SetColorSourceEx(gr->gcoEngine2d, srcPhyAddr[0], srcStride[0], srcFormat, -+ gcvFALSE, srcWidth, srcHeight, gcvFALSE, gcvSURF_OPAQUE, 0)); -+ gcmVERIFY_OK(gco2D_SetSource(gr->gcoEngine2d, &srcRect)); -+ } -+ -+ 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; -+ } -+ } -+ status = (gcoHAL_Commit(gr->gcoHal, gcvFALSE)); -+ if(status < 0) -+ { -+ printf("Error in gcoHAL_Commit %s\n", __func__); -+ 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); -+ -+ if (pixman_region32_not_empty(&ev->surface->opaque)) { -+ -+ repaint_region(ev, output, go, &repaint, &ev->surface->opaque); -+ } -+ -+ if (pixman_region32_not_empty(&surface_blend)) { -+ struct gal2d_renderer *gr = get_renderer(ec); -+ -+ gco2D_EnableAlphaBlend(gr->gcoEngine2d, -+ ev->alpha * 0xFF, ev->alpha * 0xFF, -+ gcvSURF_PIXEL_ALPHA_STRAIGHT, gcvSURF_PIXEL_ALPHA_STRAIGHT, -+ gcvSURF_GLOBAL_ALPHA_OFF, gcvSURF_GLOBAL_ALPHA_OFF, -+ gcvSURF_BLEND_ONE, gcvSURF_BLEND_INVERSED, -+ gcvSURF_COLOR_STRAIGHT, gcvSURF_COLOR_STRAIGHT); -+ -+ repaint_region(ev, output, go, &repaint, &surface_blend); -+ } -+ -+ 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; -+ -+ 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_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 -+ { -+ gcsWL_VIV_BUFFER *vivBuffer = (gcsWL_VIV_BUFFER *)buffer; -+ gs->gco_Surface = vivBuffer->surface; -+ } -+ -+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 -+ { -+ gcsWL_VIV_BUFFER *vivBuffer = wl_resource_get_user_data(buffer->resource); -+ gs->gco_Surface = vivBuffer->surface; -+ -+ buffer->width = vivBuffer->width; -+ buffer->height = vivBuffer->height; -+ } -+} -+ -+static void -+surface_state_destroy(struct gal2d_surface_state *gs, struct gal2d_renderer *gr) -+{ -+ 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 = calloc(1, sizeof *gs); -+ if (!gs) -+ 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; -+ -+ if(go->nNumBuffers <= 1 ) -+ { -+ if(go->offscreenSurface) -+ gcmVERIFY_OK(gcoSURF_Destroy(go->offscreenSurface)); -+ } -+ -+ 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, EGLNativeDisplayType display, -+ EGLNativeWindowType window) -+ -+ { -+ struct gal2d_renderer *gr = get_renderer(output->compositor); -+ struct gal2d_output_state *go = calloc(1, sizeof *go); -+ halDISPLAY_INFO info; -+ gctUINT32 backOffset = 0; -+ gctINT width, height; -+ gceSTATUS status = gcvSTATUS_OK; -+ gctUINT32 i; -+ -+ if (!go) -+ 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, &width, &height); -+ 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); -+ gal2d_flip_surface(output); -+ } -+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..3b89f73 ---- /dev/null -+++ b/src/gal2d-renderer.h -@@ -0,0 +1,41 @@ -+/* -+ * Copyright (c) 2014 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" -+#include -+ -+ -+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.1.4 - diff --git a/recipes-graphics/wayland/weston/0003-ENGR00319247-Distorted-line-and-shadow-if-use-2d-com.patch b/recipes-graphics/wayland/weston/0003-ENGR00319247-Distorted-line-and-shadow-if-use-2d-com.patch deleted file mode 100644 index 65554d3..0000000 --- a/recipes-graphics/wayland/weston/0003-ENGR00319247-Distorted-line-and-shadow-if-use-2d-com.patch +++ /dev/null @@ -1,258 +0,0 @@ -From 663f2a362ff384098f4c32f5cc9e7b7b73f2a553 Mon Sep 17 00:00:00 2001 -From: Prabhu Sundararaj -Date: Tue, 24 Jun 2014 15:44:13 -0500 -Subject: [PATCH] ENGR00319247 : Distorted line and shadow if use 2d compositor - to run wayland apps. -Organization: O.S. Systems Software LTDA. - -Fixed blending for shadown and maintained separate surface for damage composite. - -Upstream Status: N/A - -Signed-off-by: Prabhu Sundararaj -Signed-off-by: Otavio Salvador ---- - src/compositor-fbdev.c | 8 ++-- - src/gal2d-renderer.c | 102 +++++++++++++++++++++++++++++++++++-------------- - src/gal2d-renderer.h | 6 +++ - 3 files changed, 83 insertions(+), 33 deletions(-) - -diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c -index a3d32e5..b27d199 100644 ---- a/src/compositor-fbdev.c -+++ b/src/compositor-fbdev.c -@@ -55,7 +55,7 @@ struct fbdev_compositor { - int use_pixman; - int use_gal2d; - struct wl_listener session_listener; -- EGLNativeDisplayType display; -+ NativeDisplayType display; - }; - - struct fbdev_screeninfo { -@@ -91,8 +91,8 @@ struct fbdev_output { - void *shadow_buf; - uint8_t depth; - -- EGLNativeDisplayType display; -- EGLNativeWindowType window; -+ NativeDisplayType display; -+ NativeWindowType window; - }; - - struct fbdev_parameters { -@@ -667,7 +667,7 @@ fbdev_output_create(struct fbdev_compositor *compositor, - return 0; - } - if (gl_renderer->output_create(&output->base, -- (EGLNativeWindowType)output->window, -+ (NativeWindowType)output->window, - gl_renderer->opaque_attribs, - NULL) < 0) { - weston_log("gl_renderer_output_create failed.\n"); -diff --git a/src/gal2d-renderer.c b/src/gal2d-renderer.c -index c651573..fbe39f6 100644 ---- a/src/gal2d-renderer.c -+++ b/src/gal2d-renderer.c -@@ -42,7 +42,7 @@ struct gal2d_output_state { - - int current_buffer; - pixman_region32_t buffer_damage[2]; -- EGLNativeDisplayType display; -+ NativeDisplayType display; - gcoSURF* renderSurf; - gctUINT32 nNumBuffers; - int activebuffer; -@@ -423,11 +423,9 @@ gal2dBindBuffer(struct weston_surface* es) - gcoSURF surface = gs->gco_Surface; - struct weston_buffer *buffer = gs->buffer_ref.buffer; - gcePOOL pool = gcvPOOL_DEFAULT; -- gctUINT64 node = 0; -- gctUINT bytes; -- -- gcmVERIFY_OK(gcoSURF_QueryVidMemNode(surface, &node, -- &pool, &bytes)); -+ -+ gcmVERIFY_OK(gcoSURF_QueryVidMemNode(surface, gcvNULL, -+ &pool, gcvNULL)); - - if(pool != gcvPOOL_USER) - { -@@ -801,24 +799,26 @@ draw_view(struct weston_view *ev, struct weston_output *output, - ev->surface->width, ev->surface->height); - pixman_region32_subtract(&surface_blend, &surface_blend, &ev->surface->opaque); - -+ struct gal2d_renderer *gr = get_renderer(ec); -+ - if (pixman_region32_not_empty(&ev->surface->opaque)) { - - repaint_region(ev, output, go, &repaint, &ev->surface->opaque); - } - - if (pixman_region32_not_empty(&surface_blend)) { -- struct gal2d_renderer *gr = get_renderer(ec); -- -+ - gco2D_EnableAlphaBlend(gr->gcoEngine2d, -- ev->alpha * 0xFF, ev->alpha * 0xFF, -- gcvSURF_PIXEL_ALPHA_STRAIGHT, gcvSURF_PIXEL_ALPHA_STRAIGHT, -- gcvSURF_GLOBAL_ALPHA_OFF, gcvSURF_GLOBAL_ALPHA_OFF, -- gcvSURF_BLEND_ONE, gcvSURF_BLEND_INVERSED, -- gcvSURF_COLOR_STRAIGHT, gcvSURF_COLOR_STRAIGHT); -+ 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: -@@ -866,6 +866,48 @@ gal2d_renderer_repaint_output(struct weston_output *output, - } - - 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); -+ gctUINT width = 0; -+ gctUINT height = 0; -+ gctINT stride = 0; -+ gceSURF_FORMAT format; -+ gcoSURF srcSurf = vivBuffer->surface; -+ gctUINT32 physical; -+ gctPOINTER va =0; -+ gceSTATUS status = gcvSTATUS_OK; -+ struct gal2d_surface_state *gs = get_surface_state(es); -+ -+ if(gs->gco_Surface == gcvNULL) -+ { -+ /** Construct a wrapper. */ -+ gcmONERROR(gcoSURF_ConstructWrapper(gcvNULL, &gs->gco_Surface)); -+ } -+ -+ gcmONERROR(gcoSURF_GetAlignedSize(srcSurf, &width, &height, &stride)); -+ gcmONERROR(gcoSURF_GetFormat(srcSurf, gcvNULL, &format)); -+ gcmONERROR(gcoSURF_Lock(srcSurf, &physical, (gctPOINTER *)&va)); -+ -+ /* Set the buffer. */ -+ gcmONERROR(gcoSURF_SetBuffer(gs->gco_Surface, -+ gcvSURF_BITMAP_NO_VIDMEM, -+ format, -+ stride, -+ (gctPOINTER) va, -+ (gctUINT32) physical)); -+ -+ /* Set the window. */ -+ gcmONERROR(gcoSURF_SetWindow(gs->gco_Surface, 0, 0, width, height)); -+ -+ 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); -@@ -900,10 +942,7 @@ gal2d_renderer_flush_damage(struct weston_surface *surface) - gal2dBindBuffer(surface); - } - else -- { -- gcsWL_VIV_BUFFER *vivBuffer = (gcsWL_VIV_BUFFER *)buffer; -- gs->gco_Surface = vivBuffer->surface; -- } -+ gal2d_renderer_attach_egl(surface, buffer); - - done: - pixman_region32_fini(&gs->texture_damage); -@@ -937,19 +976,17 @@ gal2d_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) - } - } - else -- { -- gcsWL_VIV_BUFFER *vivBuffer = wl_resource_get_user_data(buffer->resource); -- gs->gco_Surface = vivBuffer->surface; -- -- buffer->width = vivBuffer->width; -- buffer->height = vivBuffer->height; -- } -+ gal2d_renderer_attach_egl(es, buffer); - } - - static void - surface_state_destroy(struct gal2d_surface_state *gs, struct gal2d_renderer *gr) - { -- wl_list_remove(&gs->surface_destroy_listener.link); -+ 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; -@@ -1043,8 +1080,12 @@ gal2d_renderer_output_destroy(struct weston_output *output) - { - struct gal2d_output_state *go = get_output_state(output); - gctUINT32 i; -- -- if(go->nNumBuffers <= 1 ) -+ -+ 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)); -@@ -1107,8 +1148,8 @@ OnError: - } - - static int --gal2d_renderer_output_create(struct weston_output *output, EGLNativeDisplayType display, -- EGLNativeWindowType window) -+gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType display, -+ NativeWindowType window) - - { - struct gal2d_renderer *gr = get_renderer(output->compositor); -@@ -1174,6 +1215,9 @@ gal2d_renderer_output_create(struct weston_output *output, EGLNativeDisplayType - gal2d_clear(output); - gal2d_flip_surface(output); - } -+ -+ for (i = 0; i < 2; i++) -+ pixman_region32_init(&go->buffer_damage[i]); - OnError: - galONERROR(status); - /* Return the status. */ -diff --git a/src/gal2d-renderer.h b/src/gal2d-renderer.h -index 3b89f73..1322a7d 100644 ---- a/src/gal2d-renderer.h -+++ b/src/gal2d-renderer.h -@@ -24,7 +24,13 @@ - #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 { --- -2.1.4 - diff --git a/recipes-graphics/wayland/weston/0004-ENGR00320243-Enable-GAL2D-compositor-in-SoloLite.patch b/recipes-graphics/wayland/weston/0004-ENGR00320243-Enable-GAL2D-compositor-in-SoloLite.patch deleted file mode 100644 index cb4ed6b..0000000 --- a/recipes-graphics/wayland/weston/0004-ENGR00320243-Enable-GAL2D-compositor-in-SoloLite.patch +++ /dev/null @@ -1,39 +0,0 @@ -From ca9eb5bdbdfe17654466d84c8baaa1187a8796c6 Mon Sep 17 00:00:00 2001 -From: Yong Gan -Date: Wed, 2 Jul 2014 11:27:26 +0800 -Subject: [PATCH] ENGR00320243 Enable GAL2D compositor in SoloLite -Organization: O.S. Systems Software LTDA. - -Build gal2d-renderer.so when EGL was not enabled. - -Date: Jul 02, 2014 -Signed-off-by Yong Gan - -Signed-off-by: Otavio Salvador ---- - Makefile.am | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.am b/Makefile.am -index 29834c3..e82e970 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -165,6 +165,7 @@ gl_renderer_la_SOURCES = \ - src/gl-renderer.c \ - src/vertex-clipping.c \ - src/vertex-clipping.h -+endif - - module_LTLIBRARIES += gal2d-renderer.la - gal2d_renderer_la_LDFLAGS = -module -avoid-version -@@ -178,7 +179,6 @@ gal2d_renderer_la_SOURCES = \ - src/gal2d-renderer.c \ - src/vertex-clipping.c \ - src/vertex-clipping.h --endif - - if ENABLE_X11_COMPOSITOR - module_LTLIBRARIES += x11-backend.la --- -2.1.4 - diff --git a/recipes-graphics/wayland/weston/0005-ENGR00321030-Change-GAL2D-compositor-to-be-default-i.patch b/recipes-graphics/wayland/weston/0005-ENGR00321030-Change-GAL2D-compositor-to-be-default-i.patch deleted file mode 100644 index 89d6215..0000000 --- a/recipes-graphics/wayland/weston/0005-ENGR00321030-Change-GAL2D-compositor-to-be-default-i.patch +++ /dev/null @@ -1,38 +0,0 @@ -From e58ecd66cea732aab8f6b5274d72868922e92c5f Mon Sep 17 00:00:00 2001 -From: Yong Gan -Date: Fri, 4 Jul 2014 09:57:11 +0800 -Subject: [PATCH] ENGR00321030 Change GAL2D compositor to be default in - SoloLite. -Organization: O.S. Systems Software LTDA. - -Change GAL2D compositor to be default When EGL is not enabled. - -Date: Jul 03, 2014 -Signed-off-by Yong Gan - -Signed-off-by: Otavio Salvador ---- - src/compositor-fbdev.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c -index b27d199..bdc6ec9 100644 ---- a/src/compositor-fbdev.c -+++ b/src/compositor-fbdev.c -@@ -1060,8 +1060,13 @@ 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[] = { --- -2.1.4 - diff --git a/recipes-graphics/wayland/weston/0006-MGS-389-Fix-for-wrong-FPS-throttling-when-multibuffe.patch b/recipes-graphics/wayland/weston/0006-MGS-389-Fix-for-wrong-FPS-throttling-when-multibuffe.patch deleted file mode 100644 index 8201459..0000000 --- a/recipes-graphics/wayland/weston/0006-MGS-389-Fix-for-wrong-FPS-throttling-when-multibuffe.patch +++ /dev/null @@ -1,247 +0,0 @@ -From db720086b85046bd0806484bfe63915870bb4323 Mon Sep 17 00:00:00 2001 -From: Prabhu Sundararaj -Date: Tue, 30 Dec 2014 16:09:29 -0600 -Subject: [PATCH] MGS-389 - Fix for wrong FPS throttling when multibuffer is - set -Organization: O.S. Systems Software LTDA. - -When the FB_MULTI_BUFFER=2 is set, throtling to 30FPS for a 60Hz display -which is suppose to have 60FPS. -Adding worker thread to output the frame in async mode for better -performance. - -Upstream-Status: Pending - -Signed-off-by: Prabhu Sundararaj ---- - src/gal2d-renderer.c | 109 +++++++++++++++++++++++++++++++++++++++------------ - 1 file changed, 83 insertions(+), 26 deletions(-) - -diff --git a/src/gal2d-renderer.c b/src/gal2d-renderer.c -index fbe39f6..4cccaf1 100644 ---- a/src/gal2d-renderer.c -+++ b/src/gal2d-renderer.c -@@ -28,6 +28,8 @@ - #include - #include - #include -+#include -+ - #include "compositor.h" - #include "gal2d-renderer.h" - #include "vertex-clipping.h" -@@ -37,7 +39,6 @@ - - #define galONERROR(x) if(status < 0) printf("Error in function %s\n", __func__); - -- - struct gal2d_output_state { - - int current_buffer; -@@ -48,7 +49,12 @@ struct gal2d_output_state { - int activebuffer; - gcoSURF offscreenSurface; - gceSURF_FORMAT format; -- gcoSURF tempSurf; -+ pthread_mutex_t workerMutex; -+ pthread_t workerId; -+ gctUINT32 exitWorker; -+ gctSIGNAL signal; -+ gctSIGNAL busySignal; -+ gcsHAL_INTERFACE iface; - }; - - struct gal2d_surface_state { -@@ -373,8 +379,7 @@ gal2d_clear(struct weston_output *base) - 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, gcvFALSE)); -+ gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvTRUE)); - - OnError: - galONERROR(status); -@@ -465,7 +470,6 @@ gal2dBindBuffer(struct weston_surface* es) - static void - gal2d_flip_surface(struct weston_output *output) - { -- struct gal2d_renderer *gr = get_renderer(output->compositor); - struct gal2d_output_state *go = get_output_state(output); - - if(go->nNumBuffers > 1) -@@ -473,17 +477,36 @@ gal2d_flip_surface(struct weston_output *output) - gctUINT Offset; - gctINT X; - gctINT Y; -- gcmVERIFY_OK(gcoHAL_Commit(gr->gcoHal, gcvTRUE)); -- -+ - gcmVERIFY_OK(gcoOS_GetDisplayBackbuffer(go->display, gcvNULL, - gcvNULL, gcvNULL, &Offset, &X, &Y)); - - gcmVERIFY_OK(gcoOS_SetDisplayVirtual(go->display, gcvNULL, -- Offset, X, Y)); -- -- go->activebuffer = (go->activebuffer+1) % go->nNumBuffers; -+ 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) -@@ -520,11 +543,13 @@ update_surface(struct weston_output *output) - 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)); -+ gcmONERROR(gcoHAL_Commit(gr->gcoHal, gcvFALSE)); - } -- -- gal2d_flip_surface(output); -- -+ else if(go->nNumBuffers > 1) -+ { -+ gcoHAL_ScheduleEvent(gr->gcoHal, &go->iface); -+ gcmVERIFY_OK(gcoHAL_Commit(gr->gcoHal, gcvFALSE)); -+ } - OnError: - galONERROR(status); - return status; -@@ -746,6 +771,7 @@ repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2 - 0xCC, 0xCC, go->format)); - } - } -+ - if(status < 0) - { - printf("cr l=%d r=%d t=%d b=%d w=%d h=%d\n", -@@ -759,12 +785,6 @@ repaint_region(struct weston_view *ev, struct weston_output *output, struct gal2 - goto OnError; - } - } -- status = (gcoHAL_Commit(gr->gcoHal, gcvFALSE)); -- if(status < 0) -- { -- printf("Error in gcoHAL_Commit %s\n", __func__); -- goto OnError; -- } - } - - OnError: -@@ -831,7 +851,15 @@ 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); -@@ -1090,12 +1118,19 @@ gal2d_renderer_output_destroy(struct weston_output *output) - 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; - -@@ -1182,9 +1217,28 @@ gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType dis - - go->renderSurf = malloc(sizeof(gcoSURF) * go->nNumBuffers); - gcoOS_GetDisplayVirtual(go->display, &width, &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])); - -@@ -1200,7 +1254,7 @@ gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType dis - go->activebuffer = 0; - else - go->activebuffer = 1; -- -+ - if(go->nNumBuffers <= 1 ) - { - gcmVERIFY_OK(gcoSURF_Construct(gr->gcoHal, -@@ -1213,8 +1267,11 @@ gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType dis - &go->offscreenSurface)); - make_current(gr, go->offscreenSurface); - gal2d_clear(output); -- gal2d_flip_surface(output); - } -+ else -+ { -+ gcoOS_Signal(gcvNULL,go->busySignal, gcvTRUE); -+ } - - for (i = 0; i < 2; i++) - pixman_region32_init(&go->buffer_damage[i]); --- -2.1.4 - diff --git a/recipes-graphics/wayland/weston/0007-MGS-391-Weston-Performance-Optimisation-for-single-b.patch b/recipes-graphics/wayland/weston/0007-MGS-391-Weston-Performance-Optimisation-for-single-b.patch deleted file mode 100644 index 295d4e8..0000000 --- a/recipes-graphics/wayland/weston/0007-MGS-391-Weston-Performance-Optimisation-for-single-b.patch +++ /dev/null @@ -1,183 +0,0 @@ -From 399460e202d2b23ffda661499845bcc4d86dc86c Mon Sep 17 00:00:00 2001 -From: Prabhu Sundararaj -Date: Wed, 31 Dec 2014 16:59:16 -0600 -Subject: [PATCH] MGS-391: Weston: Performance Optimisation for single buffer - mode -Organization: O.S. Systems Software LTDA. - -Blit direct to the onscreen whenever compositing is needed which -will help to improve bandwidth utilization - -Upstream-Status: Pending - -Signed-off-by: Prabhu Sundararaj ---- - src/gal2d-renderer.c | 114 ++++++++++++++++++++++++++++++++++++--------------- - 1 file changed, 81 insertions(+), 33 deletions(-) - -diff --git a/src/gal2d-renderer.c b/src/gal2d-renderer.c -index 4cccaf1..e07a2f9 100644 ---- a/src/gal2d-renderer.c -+++ b/src/gal2d-renderer.c -@@ -55,6 +55,9 @@ struct gal2d_output_state { - gctSIGNAL signal; - gctSIGNAL busySignal; - gcsHAL_INTERFACE iface; -+ int directBlit; -+ gctINT width; -+ gctINT height; - }; - - struct gal2d_surface_state { -@@ -515,34 +518,37 @@ update_surface(struct weston_output *output) - struct gal2d_output_state *go = get_output_state(output); - gceSTATUS status = gcvSTATUS_OK; - -- if(go->offscreenSurface && go->nNumBuffers == 1) -+ if(go->nNumBuffers == 1) - { -- make_current(gr, go->renderSurf[go->activebuffer]); -- -- gctUINT srcWidth = 0; -- gctUINT srcHeight = 0; -- gctINT srcStride = 0; -- gceSURF_FORMAT srcFormat;; -- gcsRECT dstRect = {0}; -- gcoSURF srcSurface = go->offscreenSurface; -- gctUINT32 physical; -- gctPOINTER va =0; -- -- gcmONERROR(gcoSURF_GetAlignedSize(srcSurface, &srcWidth, &srcHeight, &srcStride)); -- gcmONERROR(gcoSURF_GetFormat(srcSurface, gcvNULL, &srcFormat)); -- gcmONERROR(gcoSURF_Lock(srcSurface, &physical, (gctPOINTER *)&va)); -- gcmONERROR(gco2D_SetColorSource(gr->gcoEngine2d, physical, srcStride, srcFormat, -- gcvFALSE, srcWidth, gcvFALSE, gcvSURF_OPAQUE, 0)); -- -- 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)); -+ if(!go->directBlit && go->offscreenSurface) -+ { -+ make_current(gr, go->renderSurf[go->activebuffer]); -+ -+ gctUINT srcWidth = 0; -+ gctUINT srcHeight = 0; -+ gctINT srcStride = 0; -+ gceSURF_FORMAT srcFormat;; -+ gcsRECT dstRect = {0}; -+ gcoSURF srcSurface = go->offscreenSurface; -+ gctUINT32 physical; -+ gctPOINTER va =0; -+ -+ gcmONERROR(gcoSURF_GetAlignedSize(srcSurface, &srcWidth, &srcHeight, &srcStride)); -+ gcmONERROR(gcoSURF_GetFormat(srcSurface, gcvNULL, &srcFormat)); -+ gcmONERROR(gcoSURF_Lock(srcSurface, &physical, (gctPOINTER *)&va)); -+ gcmONERROR(gco2D_SetColorSource(gr->gcoEngine2d, physical, srcStride, srcFormat, -+ gcvFALSE, srcWidth, gcvFALSE, gcvSURF_OPAQUE, 0)); -+ -+ 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) -@@ -554,18 +560,61 @@ 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; -- surface = go->nNumBuffers > 1 ? -- go->renderSurf[go->activebuffer] : -- go->offscreenSurface; /*go->renderSurf[0];*/ -+ 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; - } -@@ -1190,8 +1239,7 @@ gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType dis - struct gal2d_renderer *gr = get_renderer(output->compositor); - struct gal2d_output_state *go = calloc(1, sizeof *go); - halDISPLAY_INFO info; -- gctUINT32 backOffset = 0; -- gctINT width, height; -+ gctUINT32 backOffset = 0; - gceSTATUS status = gcvSTATUS_OK; - gctUINT32 i; - -@@ -1216,7 +1264,7 @@ gal2d_renderer_output_create(struct weston_output *output, NativeDisplayType dis - go->activebuffer = 0; - - go->renderSurf = malloc(sizeof(gcoSURF) * go->nNumBuffers); -- gcoOS_GetDisplayVirtual(go->display, &width, &height); -+ gcoOS_GetDisplayVirtual(go->display, &go->width, &go->height); - gcoOS_SetSwapInterval(go->display, 1); - - /*Needed only for multi Buffer */ --- -2.1.4 - diff --git a/recipes-graphics/wayland/weston_%.bbappend b/recipes-graphics/wayland/weston_%.bbappend index f7ad463..a7496da 100644 --- a/recipes-graphics/wayland/weston_%.bbappend +++ b/recipes-graphics/wayland/weston_%.bbappend @@ -1,14 +1,6 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" -SRC_URI_append_mx6 = " \ - file://0001-ENGR00314805-1-Add-Vivante-EGL-support.patch \ - file://0002-ENGR00314805-2-Add-Vivante-GAL2D-support.patch \ - file://0003-ENGR00319247-Distorted-line-and-shadow-if-use-2d-com.patch \ - file://0004-ENGR00320243-Enable-GAL2D-compositor-in-SoloLite.patch \ - file://0005-ENGR00321030-Change-GAL2D-compositor-to-be-default-i.patch \ - file://0006-MGS-389-Fix-for-wrong-FPS-throttling-when-multibuffe.patch \ - file://0007-MGS-391-Weston-Performance-Optimisation-for-single-b.patch \ -" +SRC_URI_append_mx6 = " file://0001-MGS-840-Add-i.MX6-support-for-weston.patch" PACKAGECONFIG_append_mx6q = " cairo-glesv2" PACKAGECONFIG_append_mx6dl = " cairo-glesv2" -- cgit v1.2.3-54-g00ecf