From 49aefc25c6c63c634090e6b923e0fd89871ebf00 Mon Sep 17 00:00:00 2001 From: Lauren Post Date: Wed, 4 Jun 2014 17:23:24 -0500 Subject: weston: Upgrade patches to 1.5 with GPU integration This rework the patches for them to apply against the Weston 1.5 release. Change-Id: I99b08011b8e76ac3f4a955e5f48e6f0093326cad Signed-off-by: Lauren Post Signed-off-by: Otavio Salvador --- .../0001-Add-support-for-Vivante-FBDEV-EGL.patch | 69 - ...01-ENGR00314805-1-Add-Vivante-EGL-support.patch | 74 + ...-ENGR00314805-2-Add-Vivante-GAL2D-support.patch | 1500 +++++++++++++++++++ ...-weston-Add-Vivante-2D-compositor-support.patch | 1513 -------------------- recipes-graphics/wayland/weston_%.bbappend | 7 +- 5 files changed, 1578 insertions(+), 1585 deletions(-) delete mode 100644 recipes-graphics/wayland/weston/0001-Add-support-for-Vivante-FBDEV-EGL.patch create mode 100644 recipes-graphics/wayland/weston/0001-ENGR00314805-1-Add-Vivante-EGL-support.patch create mode 100644 recipes-graphics/wayland/weston/0002-ENGR00314805-2-Add-Vivante-GAL2D-support.patch delete mode 100644 recipes-graphics/wayland/weston/0002-weston-Add-Vivante-2D-compositor-support.patch (limited to 'recipes-graphics') diff --git a/recipes-graphics/wayland/weston/0001-Add-support-for-Vivante-FBDEV-EGL.patch b/recipes-graphics/wayland/weston/0001-Add-support-for-Vivante-FBDEV-EGL.patch deleted file mode 100644 index 6c8dfe9..0000000 --- a/recipes-graphics/wayland/weston/0001-Add-support-for-Vivante-FBDEV-EGL.patch +++ /dev/null @@ -1,69 +0,0 @@ -From bc8f870072b134ffc9b8047a53835b7b6f714d5d Mon Sep 17 00:00:00 2001 -From: Prabhu Sundararaj -Date: Tue, 11 Mar 2014 17:35:52 -0500 -Subject: [PATCH] Add support for Vivante FBDEV EGL - -Upstream-Status: Pending - -Signed-off-by: Prabhu Sundararaj ---- - src/compositor-fbdev.c | 20 +++++++++++++++++--- - 1 file changed, 17 insertions(+), 3 deletions(-) - -diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c -index 0d96269..ada0019 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 { -@@ -626,9 +630,13 @@ fbdev_output_create(struct fbdev_compositor *compositor, - if (pixman_renderer_output_create(&output->base) < 0) - 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) < 0) { -+ (EGLNativeWindowType)output->window) < 0) { - weston_log("gl_renderer_output_create failed.\n"); - goto out_shadow_surface; - } -@@ -920,8 +928,14 @@ fbdev_compositor_create(struct wl_display *display, int *argc, char *argv[], - weston_log("could not load gl renderer\n"); - goto out_launcher; - } -+ -+ 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, EGL_DEFAULT_DISPLAY, -+ if (gl_renderer->create(&compositor->base, compositor->display, - gl_renderer->opaque_attribs, - NULL) < 0) { - weston_log("gl_renderer_create failed.\n"); --- -1.8.1.2 - 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 new file mode 100644 index 0000000..e946fe4 --- /dev/null +++ b/recipes-graphics/wayland/weston/0001-ENGR00314805-1-Add-Vivante-EGL-support.patch @@ -0,0 +1,74 @@ +From 0d24f9872fc5bbbb07ae55f1107ba0f5060fca8a Mon Sep 17 00:00:00 2001 +From: Yong Gan +Date: Thu, 22 May 2014 15:25:42 +0800 +Subject: [PATCH 1/3] ENGR00314805-1 Add Vivante EGL support + +Add Vivante EGL compositor support. + +Upstream-Status: Pending + +[DATE]05-22-2014 +Signed-off-by Yong Gan +--- + 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"); +-- +1.7.9.5 + 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 new file mode 100644 index 0000000..58b5966 --- /dev/null +++ b/recipes-graphics/wayland/weston/0002-ENGR00314805-2-Add-Vivante-GAL2D-support.patch @@ -0,0 +1,1500 @@ +From 2a24c62ef00d1b08974bd8f07e277695ac2911fa Mon Sep 17 00:00:00 2001 +From: Yong Gan +Date: Thu, 22 May 2014 15:26:31 +0800 +Subject: [PATCH 2/3] ENGR00314805-2 Add Vivante GAL2D support + +Add Vivante GAL2D compositor support. + +Upstream-Status: Pending + +[DATE]05-22-2014 +Signed-off-by Yong Gan +--- + 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 343adc6..2bccfe9 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -162,6 +162,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 +-- +1.7.9.5 + diff --git a/recipes-graphics/wayland/weston/0002-weston-Add-Vivante-2D-compositor-support.patch b/recipes-graphics/wayland/weston/0002-weston-Add-Vivante-2D-compositor-support.patch deleted file mode 100644 index f60a208..0000000 --- a/recipes-graphics/wayland/weston/0002-weston-Add-Vivante-2D-compositor-support.patch +++ /dev/null @@ -1,1513 +0,0 @@ -From c5fa88cb08477384430d2ab1123319c9d5dfb31c Mon Sep 17 00:00:00 2001 -From: Prabhu Sundararaj -Date: Mon, 24 Mar 2014 07:30:25 -0500 -Subject: [PATCH 2/2] weston : Add Vivante 2D compositor support - -Upstream-Status: Pending - -Signed-off-by: Prabhu Sundararaj ---- - src/Makefile.am | 14 + - src/compositor-fbdev.c | 111 ++++- - src/gal2d-renderer.c | 1186 ++++++++++++++++++++++++++++++++++++++++++++++++ - src/gal2d-renderer.h | 43 ++ - 4 files changed, 1340 insertions(+), 14 deletions(-) - create mode 100644 src/gal2d-renderer.c - create mode 100644 src/gal2d-renderer.h - -diff --git a/src/Makefile.am b/src/Makefile.am -index 446639c..ef6abd6 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -112,6 +112,7 @@ module_LTLIBRARIES = \ - $(cms_static) \ - $(cms_colord) \ - $(gl_renderer) \ -+ $(gal2d_renderer) \ - $(x11_backend) \ - $(drm_backend) \ - $(wayland_backend) \ -@@ -138,6 +139,19 @@ gl_renderer_la_SOURCES = \ - gl-renderer.c \ - vertex-clipping.c \ - vertex-clipping.h -+ -+gal2d_renderer = 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 = \ -+ gal2d-renderer.h \ -+ gal2d-renderer.c \ -+ vertex-clipping.c \ -+ vertex-clipping.h - endif - - if ENABLE_X11_COMPOSITOR -diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c -index 72939b4..28f1fca 100644 ---- a/src/compositor-fbdev.c -+++ b/src/compositor-fbdev.c -@@ -44,6 +44,7 @@ - #include "pixman-renderer.h" - #include "udev-seat.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; - NativeDisplayType 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,14 +634,40 @@ 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 { - 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)output->window) < 0) { -+ (NativeWindowType)output->window) < 0) { - weston_log("gl_renderer_output_create failed.\n"); - goto out_shadow_surface; - } -@@ -695,7 +726,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); - } - -@@ -758,7 +793,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; - } -@@ -911,7 +946,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, -@@ -921,7 +959,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) { -@@ -942,9 +1023,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); - -@@ -977,13 +1058,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..be7af3c ---- /dev/null -+++ b/src/gal2d-renderer.c -@@ -0,0 +1,1186 @@ -+/* -+ * 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; -+ -+ 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..ebffec1 ---- /dev/null -+++ b/src/gal2d-renderer.h -@@ -0,0 +1,43 @@ -+/* -+ * 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); -+}; -+ -+struct gal2d_renderer_interface gal2d_renderer_interface; -+ -+#endif --- -1.9.0 - diff --git a/recipes-graphics/wayland/weston_%.bbappend b/recipes-graphics/wayland/weston_%.bbappend index 0576b37..51af104 100644 --- a/recipes-graphics/wayland/weston_%.bbappend +++ b/recipes-graphics/wayland/weston_%.bbappend @@ -1,7 +1,7 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" -SRC_URI += "file://0001-Add-support-for-Vivante-FBDEV-EGL.patch \ - file://0002-weston-Add-Vivante-2D-compositor-support.patch " +SRC_URI += "file://0001-ENGR00314805-1-Add-Vivante-EGL-support.patch \ + file://0002-ENGR00314805-2-Add-Vivante-GAL2D-support.patch" PACKAGECONFIG_mx6 = "fbdev egl cairo-glesv2" @@ -17,5 +17,6 @@ EXTRA_OEMAKE_append_mx6 = " \ FB_COMPOSITOR_CFLAGS="-DLINUX=1 -DEGL_API_FB -DEGL_API_WL" \ FB_COMPOSITOR_LIBS="-lGLESv2 -lEGL -lwayland-server -lxkbcommon" \ SIMPLE_EGL_CLIENT_CFLAGS="-DLINUX -DEGL_API_FB -DEGL_API_WL" \ - CLIENT_CFLAGS="-DLINUX -DEGL_API_FB -DEGL_API_WL" \ + EGL_TESTS_CFLAGS="-DLINUX -DEGL_API_FB -DEGL_API_WL" \ + CLIENT_CFLAGS="-I ${STAGING_INCDIR}/cairo -I ${STAGING_INCDIR}/pixman-1 -DLINUX -DEGL_API_FB -DEGL_API_WL" \ " -- cgit v1.2.3-54-g00ecf