From e141909e97556aa9a3028f06543751643a35cc58 Mon Sep 17 00:00:00 2001 From: Tom Hochstein Date: Fri, 7 Oct 2016 17:36:55 -0500 Subject: [PATCH] weston: Re-implement renderer using G2D Change i.MX renderer from gal2d to g2d API. Signed-off-by: Tom Hochstein Signed-off-by: Otavio Salvador --- ...-implement-weston-2d-renderer-with-p.patch | 2869 +++++++++++++++++ ...Re-implement-weston-2d-renderer-with.patch | 36 + ...D-compositor-build-failed-in-slevk-b.patch | 106 + recipes-graphics/wayland/weston_%.bbappend | 3 + 4 files changed, 3014 insertions(+) create mode 100644 recipes-graphics/wayland/weston/0009-MGS-1284-xwld-Re-implement-weston-2d-renderer-with-p.patch create mode 100644 recipes-graphics/wayland/weston/0010-MGS-1284-1-xwld-Re-implement-weston-2d-renderer-with.patch create mode 100644 recipes-graphics/wayland/weston/0011-MGS-1724-xwld-G2D-compositor-build-failed-in-slevk-b.patch diff --git a/recipes-graphics/wayland/weston/0009-MGS-1284-xwld-Re-implement-weston-2d-renderer-with-p.patch b/recipes-graphics/wayland/weston/0009-MGS-1284-xwld-Re-implement-weston-2d-renderer-with-p.patch new file mode 100644 index 00000000..0afbd4b6 --- /dev/null +++ b/recipes-graphics/wayland/weston/0009-MGS-1284-xwld-Re-implement-weston-2d-renderer-with-p.patch @@ -0,0 +1,2869 @@ +From 7bcbb14a149d0955176855e8ab6289cf68d099e5 Mon Sep 17 00:00:00 2001 +From: "yong.gan" +Date: Fri, 11 Mar 2016 10:55:48 +0800 +Subject: [PATCH 1/3] MGS-1284: xwld: Re-implement weston 2d renderer with + porting g2d API + +Use G2D API to replace Gal2D API. +Fix the errors in multi display mode. +Use the standard FB API to operate the frame buffer. + +Date: Feb 22, 2016 +Upstream Status: Inappropriate [i.MX specific] + +Signed-off-by: Yong Gan +--- + Makefile.am | 16 +- + src/compositor-fbdev.c | 74 +-- + src/g2d-renderer.c | 1175 +++++++++++++++++++++++++++++++++++++++++++ + src/g2d-renderer.h | 48 ++ + src/gal2d-renderer.c | 1307 ------------------------------------------------ + src/gal2d-renderer.h | 50 -- + 6 files changed, 1255 insertions(+), 1415 deletions(-) + create mode 100644 src/g2d-renderer.c + create mode 100644 src/g2d-renderer.h + delete mode 100644 src/gal2d-renderer.c + delete mode 100644 src/gal2d-renderer.h + +Index: weston-1.11.0/Makefile.am +=================================================================== +--- weston-1.11.0.orig/Makefile.am 2016-10-06 14:26:20.254564856 -0500 ++++ weston-1.11.0/Makefile.am 2016-10-06 14:28:47.000000000 -0500 +@@ -247,16 +247,16 @@ + src/vertex-clipping.h \ + shared/helpers.h + endif +-module_LTLIBRARIES += gal2d-renderer.la +-gal2d_renderer_la_LDFLAGS = -module -avoid-version +-gal2d_renderer_la_LIBADD = $(COMPOSITOR_LIBS) $(EGL_LIBS) +-gal2d_renderer_la_CFLAGS = \ ++module_LTLIBRARIES += g2d-renderer.la ++g2d_renderer_la_LDFLAGS = -module -avoid-version ++g2d_renderer_la_LIBADD = $(COMPOSITOR_LIBS) $(EGL_LIBS) -lg2d ++g2d_renderer_la_CFLAGS = \ + $(COMPOSITOR_CFLAGS) \ + $(EGL_CFLAGS) \ +- $(GCC_CFLAGS) +-gal2d_renderer_la_SOURCES = \ +- src/gal2d-renderer.h \ +- src/gal2d-renderer.c \ ++ $(GCC_CFLAGS) -DHAVE_G2D ++g2d_renderer_la_SOURCES = \ ++ src/g2d-renderer.h \ ++ src/g2d-renderer.c \ + src/vertex-clipping.c \ + src/vertex-clipping.h + +Index: weston-1.11.0/src/compositor-fbdev.c +=================================================================== +--- weston-1.11.0.orig/src/compositor-fbdev.c 2016-10-06 14:26:20.418565670 -0500 ++++ weston-1.11.0/src/compositor-fbdev.c 2016-10-06 14:28:47.000000000 -0500 +@@ -50,7 +50,7 @@ + #include "libinput-seat.h" + #include "gl-renderer.h" + #include "presentation-time-server-protocol.h" +-#include "gal2d-renderer.h" ++#include "g2d-renderer.h" + + struct fbdev_backend { + struct weston_backend base; +@@ -60,7 +60,7 @@ + struct udev *udev; + struct udev_input input; + int use_pixman; +- int use_gal2d; ++ int use_g2d; + uint32_t output_transform; + struct wl_listener session_listener; + NativeDisplayType display; +@@ -102,7 +102,7 @@ + }; + + struct gl_renderer_interface *gl_renderer; +-struct gal2d_renderer_interface *gal2d_renderer; ++struct g2d_renderer_interface *g2d_renderer; + + static const char default_seat[] = "seat0"; + +@@ -519,36 +519,10 @@ + if (backend->use_pixman) { + if (pixman_renderer_output_create(&output->base) < 0) + goto out_hw_surface; +- } else if(backend->use_gal2d) { +- +- char* fbenv = getenv("FB_FRAMEBUFFER_0"); +- setenv("FB_FRAMEBUFFER_0", device, 1); +- output->display = fbGetDisplay(backend->compositor->wl_display); +- if (output->display == NULL) { +- fprintf(stderr, "failed to get display\n"); +- return 0; +- } +- +- output->window = fbCreateWindow(output->display, -1, -1, 0, 0); +- if (output->window == NULL) { +- fprintf(stderr, "failed to create window\n"); +- return 0; +- } +- /* restore the previous value*/ +- if(fbenv != NULL) +- { +- setenv("FB_FRAMEBUFFER_0", fbenv, 1); +- } +- else +- { +- unsetenv("FB_FRAMEBUFFER_0"); +- } +- +- +- if (gal2d_renderer->output_create(&output->base, +- output->display, +- (NativeWindowType)output->window) < 0) { +- weston_log("gal_renderer_output_create failed.\n"); ++ } else if(backend->use_g2d) { ++ if (g2d_renderer->output_create(&output->base, ++ backend->compositor->wl_display, device) < 0) { ++ weston_log("g2d_renderer_output_create failed.\n"); + goto out_hw_surface; + } + +@@ -607,8 +581,8 @@ + if (backend->use_pixman) { + if (base->renderer_state != NULL) + pixman_renderer_output_destroy(base); +- } else if (backend->use_gal2d) { +- gal2d_renderer->output_destroy(base); ++ } else if (backend->use_g2d) { ++ g2d_renderer->output_destroy(base); + } else { + gl_renderer->output_destroy(base); + } +@@ -820,8 +794,8 @@ + backend->base.restore = fbdev_restore; + + backend->prev_state = WESTON_COMPOSITOR_ACTIVE; +- backend->use_pixman = !(param->use_gl || param->use_gal2d); +- backend->use_gal2d = param->use_gal2d; ++ backend->use_pixman = !(param->use_gl || param->use_g2d); ++ backend->use_g2d = param->use_g2d; + backend->output_transform = param->output_transform; + + weston_setup_vt_switch_bindings(compositor); +@@ -830,21 +804,21 @@ + if (pixman_renderer_init(compositor) < 0) + goto out_launcher; + } +- else if (backend->use_gal2d) { ++ else if (backend->use_g2d) { + 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"); ++ g2d_renderer = weston_load_module("g2d-renderer.so", ++ "g2d_renderer_interface"); ++ if (!g2d_renderer) { ++ weston_log("could not load g2d renderer\n"); + goto out_launcher; + } + +- if (gal2d_renderer->create(backend->compositor) < 0) { +- weston_log("gal2d_renderer_create failed.\n"); ++ if (g2d_renderer->create(backend->compositor) < 0) { ++ weston_log("g2d_renderer_create failed.\n"); + goto out_launcher; + } + +@@ -893,7 +867,7 @@ + goto out_launcher; + } + } +- if(!backend->use_gal2d) ++ if(!backend->use_g2d) + if (fbdev_output_create(backend, 0, 0, param->device) < 0) + goto out_launcher; + +@@ -924,10 +898,10 @@ + config->device = "/dev/fb0"; /* default frame buffer */ + #ifdef ENABLE_EGL + config->use_gl = 1; +- config->use_gal2d = 0; ++ config->use_g2d = 0; + #else + config->use_gl = 0; +- config->use_gal2d = 1; ++ config->use_g2d = 1; + #endif + config->output_transform = WL_OUTPUT_TRANSFORM_NORMAL; + } +Index: weston-1.11.0/src/g2d-renderer.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ weston-1.11.0/src/g2d-renderer.c 2016-10-06 14:28:47.000000000 -0500 +@@ -0,0 +1,1175 @@ ++/* ++ * Copyright (c) 2016 Freescale Semiconductor, Inc. ++ * Copyright © 2012 Intel Corporation ++ * Copyright © 2015 Collabora, Ltd. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "compositor.h" ++#include "g2d-renderer.h" ++#include "vertex-clipping.h" ++#include "shared/helpers.h" ++#include "HAL/gc_hal_eglplatform.h" ++#include "g2dExt.h" ++ ++#define BUFFER_DAMAGE_COUNT 2 ++ ++typedef struct _g2dRECT ++{ ++ int left; ++ int top; ++ int right; ++ int bottom; ++} g2dRECT; ++ ++struct fb_screeninfo { ++ struct fb_var_screeninfo varinfo; ++ struct fb_fix_screeninfo fixinfo; ++ unsigned int x_resolution; ++ unsigned int y_resolution; ++ size_t buffer_length; /* length of frame buffer memory in bytes */ ++ size_t physical; ++ enum g2d_format pixel_format; /* frame buffer pixel format */ ++}; ++ ++struct g2d_output_state { ++ int current_buffer; ++ pixman_region32_t buffer_damage[BUFFER_DAMAGE_COUNT]; ++ struct g2d_surfaceEx *renderSurf; ++ int nNumBuffers; ++ int activebuffer; ++ struct g2d_surfaceEx offscreenSurface; ++ struct g2d_buf *offscreen_buf; ++ struct fb_screeninfo fb_info; ++ int directBlit; ++ int width; ++ int height; ++ int fb_fd; ++}; ++ ++struct g2d_surface_state { ++ float color[4]; ++ struct weston_buffer_reference buffer_ref; ++ int pitch; /* in pixels */ ++ int attached; ++ pixman_region32_t texture_damage; ++ struct g2d_surfaceEx g2d_surface; ++ struct g2d_buf *shm_buf; ++ int shm_buf_length; ++ int bpp; ++ ++ struct weston_surface *surface; ++ struct wl_listener surface_destroy_listener; ++ struct wl_listener renderer_destroy_listener; ++}; ++ ++struct g2d_renderer { ++ struct weston_renderer base; ++ struct wl_signal destroy_signal; ++ struct wl_global *viv_global; ++ void *handle; ++}; ++ ++static int ++g2d_renderer_create_surface(struct weston_surface *surface); ++ ++static inline struct g2d_surface_state * ++get_surface_state(struct weston_surface *surface) ++{ ++ if (!surface->renderer_state) ++ g2d_renderer_create_surface(surface); ++ return (struct g2d_surface_state *)surface->renderer_state; ++} ++ ++static inline struct g2d_renderer * ++get_renderer(struct weston_compositor *ec) ++{ ++ return (struct g2d_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 g2d_output_state * ++get_output_state(struct weston_output *output) ++{ ++ return (struct g2d_output_state *)output->renderer_state; ++} ++ ++static void ++g2d_getG2dTiling(IN gceTILING tiling, enum g2d_tiling* g2dTiling) ++{ ++ switch(tiling) ++ { ++ case gcvLINEAR: ++ *g2dTiling = G2D_LINEAR; ++ break; ++ case gcvTILED: ++ *g2dTiling = G2D_TILED; ++ break; ++ case gcvSUPERTILED: ++ *g2dTiling = G2D_SUPERTILED; ++ break; ++ default: ++ weston_log("Error in function %s\n", __func__); ++ break; ++ } ++} ++ ++static void ++g2d_getG2dFormat(IN gceSURF_FORMAT Format, enum g2d_format* g2dFormat) ++{ ++ switch(Format) ++ { ++ case gcvSURF_R5G6B5: ++ *g2dFormat = G2D_RGB565; ++ break; ++ case gcvSURF_A8B8G8R8: ++ *g2dFormat = G2D_RGBA8888; ++ break; ++ case gcvSURF_X8B8G8R8: ++ *g2dFormat = G2D_RGBA8888; ++ break; ++ case gcvSURF_A8R8G8B8: ++ *g2dFormat = G2D_BGRA8888; ++ break; ++ case gcvSURF_X8R8G8B8: ++ *g2dFormat = G2D_BGRX8888; ++ break; ++ case gcvSURF_B5G6R5: ++ *g2dFormat = G2D_BGR565; ++ break; ++ case gcvSURF_B8G8R8A8: ++ *g2dFormat = G2D_ARGB8888; ++ break; ++ case gcvSURF_R8G8B8A8: ++ *g2dFormat = G2D_ABGR8888; ++ break; ++ case gcvSURF_B8G8R8X8: ++ *g2dFormat = G2D_XRGB8888; ++ break; ++ case gcvSURF_R8G8B8X8: ++ *g2dFormat = G2D_XBGR8888; ++ break; ++ case gcvSURF_NV12: ++ *g2dFormat = G2D_NV12; ++ break; ++ case gcvSURF_NV21: ++ *g2dFormat = G2D_NV21; ++ break; ++ case gcvSURF_I420: ++ *g2dFormat = G2D_I420; ++ break; ++ case gcvSURF_YV12: ++ *g2dFormat = G2D_YV12; ++ break; ++ case gcvSURF_YUY2: ++ *g2dFormat = G2D_YUYV; ++ break; ++ case gcvSURF_YVYU: ++ *g2dFormat = G2D_YVYU; ++ break; ++ case gcvSURF_UYVY: ++ *g2dFormat = G2D_UYVY; ++ break; ++ case gcvSURF_VYUY: ++ *g2dFormat = G2D_VYUY; ++ break; ++ case gcvSURF_NV16: ++ *g2dFormat = G2D_NV16; ++ break; ++ case gcvSURF_NV61: ++ *g2dFormat = G2D_NV61; ++ break; ++ default: ++ weston_log("Error in function %s, Format not supported\n", __func__); ++ break; ++ } ++} ++ ++static void printG2dSurfaceInfo(struct g2d_surfaceEx* g2dSurface) ++{ ++ weston_log("physicAddr = %d left = %d right = %d top=%d bottom=%d stride= %d tiling = %d, format=%d \n", ++ g2dSurface->base.planes[0], ++ g2dSurface->base.left, ++ g2dSurface->base.right, ++ g2dSurface->base.top, ++ g2dSurface->base.bottom, ++ g2dSurface->base.stride, ++ g2dSurface->tiling, ++ g2dSurface->base.format); ++} ++ ++static void ++get_g2dSurface(gcsWL_VIV_BUFFER *buffer, struct g2d_surfaceEx *g2dSurface) ++{ ++ if(buffer->width < 0 || buffer->height < 0) ++ { ++ weston_log("invalid EGL buffer in function %s\n", __func__); ++ return; ++ } ++ int width = buffer->alignedWidth; ++ int height = buffer->alignedHeight; ++ g2d_getG2dFormat(buffer->format, &g2dSurface->base.format); ++ g2d_getG2dTiling(buffer->tiling, &g2dSurface->tiling); ++ g2dSurface->base.planes[0] = buffer->physical[0]; ++ g2dSurface->base.planes[1] = buffer->physical[1]; ++ g2dSurface->base.planes[2] = buffer->physical[2]; ++ g2dSurface->base.left = 0; ++ g2dSurface->base.top = 0; ++ g2dSurface->base.right = buffer->width; ++ g2dSurface->base.bottom = buffer->height; ++ g2dSurface->base.stride = width; ++ g2dSurface->base.width = width; ++ g2dSurface->base.height = height; ++ g2dSurface->base.rot = G2D_ROTATION_0; ++} ++ ++static void ++g2d_SetSurfaceRect(struct g2d_surfaceEx* g2dSurface, g2dRECT* rect) ++{ ++ if(g2dSurface && rect) ++ { ++ g2dSurface->base.left = rect->left; ++ g2dSurface->base.top = rect->top; ++ g2dSurface->base.right = rect->right; ++ g2dSurface->base.bottom = rect->bottom; ++ } ++} ++ ++static int ++g2d_blitSurface(void *handle, struct g2d_surfaceEx * srcG2dSurface, struct g2d_surfaceEx *dstG2dSurface, ++ g2dRECT *srcRect, g2dRECT *dstRect) ++{ ++ g2d_SetSurfaceRect(srcG2dSurface, srcRect); ++ g2d_SetSurfaceRect(dstG2dSurface, dstRect); ++ srcG2dSurface->base.blendfunc = G2D_ONE; ++ dstG2dSurface->base.blendfunc = G2D_ONE_MINUS_SRC_ALPHA; ++ ++ if(g2d_blitEx(handle, srcG2dSurface, dstG2dSurface)) ++ { ++ printG2dSurfaceInfo(srcG2dSurface); ++ printG2dSurfaceInfo(dstG2dSurface); ++ return -1; ++ } ++ return 0; ++} ++ ++static void ++g2d_flip_surface(struct weston_output *output) ++{ ++ struct g2d_output_state *go = get_output_state(output); ++ go->fb_info.varinfo.yoffset = go->activebuffer * go->fb_info.y_resolution; ++ ++ if(ioctl(go->fb_fd, FBIOPAN_DISPLAY, &(go->fb_info.varinfo)) < 0) ++ { ++ weston_log("FBIOPAN_DISPLAY Failed\n"); ++ } ++ go->activebuffer = (go->activebuffer + 1) % go->nNumBuffers; ++} ++ ++static void ++copy_to_framebuffer(struct weston_output *output) ++{ ++ struct g2d_renderer *gr = get_renderer(output->compositor); ++ struct g2d_output_state *go = get_output_state(output); ++ if(!go->directBlit && go->nNumBuffers == 1) ++ { ++ g2dRECT srcRect = {0, 0, go->offscreenSurface.base.width, go->offscreenSurface.base.height}; ++ g2dRECT dstrect = srcRect; ++ g2dRECT clipRect = srcRect; ++ g2d_set_clipping(gr->handle, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); ++ g2d_blitSurface(gr->handle, &go->offscreenSurface, ++ &go->renderSurf[go->activebuffer], &srcRect, &dstrect); ++ } ++ ++ g2d_finish(gr->handle); ++ ++ if(go->nNumBuffers > 1) ++ { ++ g2d_flip_surface(output); ++ } ++} ++ ++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 void ++use_output(struct weston_output *output) ++{ ++ struct weston_compositor *compositor = output->compositor; ++ struct weston_view *view; ++ struct g2d_output_state *go = get_output_state(output); ++ int visibleViews=0; ++ int fullscreenViews=0; ++ ++ 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)); ++ } ++} ++ ++static int ++g2d_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 g2d_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 g2d_output_state *go, pixman_region32_t *region, ++ pixman_region32_t *surf_region){ ++ ++ struct g2d_renderer *gr = get_renderer(ev->surface->compositor); ++ struct g2d_surface_state *gs = get_surface_state(ev->surface); ++ ++ pixman_box32_t *rects, *surf_rects, *bb_rects; ++ int i, j, nrects, nsurf, nbb=0; ++ g2dRECT srcRect = {0}; ++ g2dRECT dstrect = {0}; ++ g2dRECT clipRect = {0}; ++ int dstWidth = 0; ++ int dstHeight = 0; ++ struct g2d_surfaceEx *dstsurface; ++ ++ bb_rects = pixman_region32_rectangles(&ev->transform.boundingbox, &nbb); ++ ++ if(!gs->attached || nbb <= 0) ++ { ++ return; ++ } ++ ++ rects = pixman_region32_rectangles(region, &nrects); ++ surf_rects = pixman_region32_rectangles(surf_region, &nsurf); ++ srcRect.left = ev->geometry.x < 0.0 ? g2d_int_from_double(fabsf(ev->geometry.x)) : 0; ++ srcRect.top = ev->geometry.y < 0.0 ? g2d_int_from_double(fabsf(ev->geometry.y)) : 0; ++ srcRect.right = ev->surface->width; ++ srcRect.bottom = ev->surface->height; ++ if(go->nNumBuffers > 1 || go->directBlit) ++ { ++ dstsurface = &go->renderSurf[go->activebuffer]; ++ } ++ else ++ { ++ dstsurface = &go->offscreenSurface; ++ } ++ dstWidth = dstsurface->base.width; ++ dstHeight = dstsurface->base.height; ++ 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; ++ /*Multi display support*/ ++ if(output->x > 0) ++ { ++ dstrect.left = dstrect.left - output->x; ++ dstrect.right = dstrect.right - output->x; ++ } ++ if(dstrect.left < 0) ++ { ++ srcRect.left -= dstrect.left; ++ dstrect.left = 0; ++ if(srcRect.left > ev->surface->width) ++ break; ++ } ++ if(dstrect.right > dstWidth) ++ { ++ dstrect.right = dstWidth; ++ srcRect.right = srcRect.left + dstrect.right - dstrect.left; ++ if(srcRect.right > ev->surface->width) ++ break; ++ } ++ if(dstrect.bottom > dstHeight) ++ { ++ dstrect.bottom = dstHeight; ++ srcRect.bottom = srcRect.top + dstrect.bottom - dstrect.top; ++ if(srcRect.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; ++ 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 = g2d_int_from_double(min_x); ++ clipRect.top = g2d_int_from_double(min_y); ++ clipRect.right = g2d_int_from_double(max_x); ++ clipRect.bottom = g2d_int_from_double(max_y); ++ ++ if(output->x > 0) ++ { ++ clipRect.left = clipRect.left - output->x; ++ clipRect.right = clipRect.right - output->x; ++ } ++ g2d_set_clipping(gr->handle, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); ++ g2d_blitSurface(gr->handle, &gs->g2d_surface, dstsurface, &srcRect, &dstrect); ++ } ++ } ++} ++ ++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 g2d_output_state *go = get_output_state(output); ++ struct g2d_surface_state *gs = get_surface_state(ev->surface); ++ /* 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 g2d_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)) { ++ g2d_enable(gr->handle,G2D_BLEND); ++ if (ev->alpha < 1.0) ++ { ++ g2d_enable(gr->handle, G2D_GLOBAL_ALPHA); ++ gs->g2d_surface.base.global_alpha = ev->alpha * 0xFF; ++ } ++ repaint_region(ev, output, go, &repaint, &surface_blend); ++ g2d_disable(gr->handle, G2D_GLOBAL_ALPHA); ++ g2d_disable(gr->handle, G2D_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 ++g2d_renderer_repaint_output(struct weston_output *output, ++ pixman_region32_t *output_damage) ++{ ++ struct g2d_output_state *go = get_output_state(output); ++ int i; ++ ++ use_output(output); ++ 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); ++ copy_to_framebuffer(output); ++ go->current_buffer ^= 1; ++} ++ ++static void ++g2d_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer) ++{ ++ gcsWL_VIV_BUFFER *vivBuffer = wl_resource_get_user_data(buffer->resource); ++ struct g2d_surface_state *gs = get_surface_state(es); ++ buffer->width = vivBuffer->width; ++ buffer->height = vivBuffer->height; ++ get_g2dSurface(vivBuffer, &gs->g2d_surface); ++} ++ ++static void ++g2d_renderer_flush_damage(struct weston_surface *surface) ++{ ++ struct g2d_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)) ++ { ++ uint8_t *src = wl_shm_buffer_get_data(buffer->shm_buffer); ++ uint8_t *dst = gs->shm_buf->buf_vaddr; ++ int bpp = gs->bpp; ++ wl_shm_buffer_begin_access(buffer->shm_buffer); ++ if(gs->shm_buf) ++ { ++ int alignedWidth = (buffer->width + 15) & ~15; ++ if(alignedWidth == buffer->width) ++ { ++ int size = wl_shm_buffer_get_stride(buffer->shm_buffer)*buffer->height; ++ memcpy(dst, src, size); ++ } ++ else ++ { ++ int i, j; ++ for (i = 0; i < buffer->height; i++) ++ { ++ for (j = 0; j < buffer->width; j++) ++ { ++ int dstOff = i * alignedWidth + j; ++ int srcOff = (i * buffer->width + j); ++ memcpy(dst + dstOff * bpp, src + srcOff * bpp, bpp); ++ } ++ } ++ } ++ g2d_cache_op(gs->shm_buf, G2D_CACHE_CLEAN); ++ } ++ else ++ { ++ weston_log("Error: This shm buffer was not attached\n"); ++ } ++ wl_shm_buffer_end_access(buffer->shm_buffer); ++ } ++ else ++ { ++ g2d_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 ++g2d_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer, ++ struct wl_shm_buffer *shm_buffer) ++{ ++ struct g2d_surface_state *gs = get_surface_state(es); ++ int stride = 0; ++ int buffer_length = 0; ++ int alloc_new_buff = 1; ++ int alignedWidth = 0; ++ enum g2d_format g2dFormat = 0; ++ buffer->shm_buffer = shm_buffer; ++ buffer->width = wl_shm_buffer_get_width(shm_buffer); ++ buffer->height = wl_shm_buffer_get_height(shm_buffer); ++ alignedWidth = (buffer->width + 15) & ~15; ++ stride = wl_shm_buffer_get_stride(shm_buffer); ++ buffer_length = stride * buffer->height; ++ ++ switch (wl_shm_buffer_get_format(shm_buffer)) { ++ case WL_SHM_FORMAT_XRGB8888: ++ g2dFormat = G2D_XRGB8888; ++ gs->bpp = 4; ++ break; ++ case WL_SHM_FORMAT_ARGB8888: ++ g2dFormat = G2D_ARGB8888; ++ gs->bpp = 4; ++ break; ++ case WL_SHM_FORMAT_RGB565: ++ g2dFormat = G2D_RGB565; ++ gs->bpp = 2; ++ break; ++ default: ++ weston_log("warning: unknown shm buffer format: %08x\n", ++ wl_shm_buffer_get_format(shm_buffer)); ++ return; ++ } ++ ++ buffer_length = alignedWidth * buffer->height * gs->bpp; ++ ++ /* Only allocate a new g2d buff if it is larger than existing one.*/ ++ gs->shm_buf_length = buffer_length; ++ if(gs->shm_buf && gs->shm_buf->buf_size > buffer_length) ++ { ++ alloc_new_buff = 0; ++ } ++ ++ if(alloc_new_buff) ++ { ++ if(gs->shm_buf) ++ g2d_free(gs->shm_buf); ++ gs->shm_buf = g2d_alloc(buffer_length, 1); ++ gs->g2d_surface.base.planes[0] = gs->shm_buf->buf_paddr; ++ } ++ gs->g2d_surface.base.left = 0; ++ gs->g2d_surface.base.top = 0; ++ gs->g2d_surface.base.right = buffer->width; ++ gs->g2d_surface.base.bottom = buffer->height; ++ gs->g2d_surface.base.stride = alignedWidth; ++ gs->g2d_surface.base.width = buffer->width; ++ gs->g2d_surface.base.height = buffer->height; ++ gs->g2d_surface.base.rot = G2D_ROTATION_0; ++ gs->g2d_surface.base.clrcolor = 0xFF400000; ++ gs->g2d_surface.tiling = G2D_LINEAR; ++ gs->g2d_surface.base.format = g2dFormat; ++} ++ ++static void ++g2d_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) ++{ ++ struct g2d_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) ++ { ++ g2d_renderer_attach_shm(es, buffer, shm_buffer); ++ } ++ else ++ { ++ g2d_renderer_attach_egl(es, buffer); ++ } ++ gs->attached = 1; ++} ++ ++static void ++surface_state_destroy(struct g2d_surface_state *gs, struct g2d_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; ++ ++ if(gs->shm_buf) ++ { ++ g2d_free(gs->shm_buf); ++ gs->shm_buf = NULL; ++ } ++ ++ weston_buffer_reference(&gs->buffer_ref, NULL); ++ free(gs); ++} ++ ++static void ++surface_state_handle_surface_destroy(struct wl_listener *listener, void *data) ++{ ++ struct g2d_surface_state *gs; ++ struct g2d_renderer *gr; ++ ++ gs = container_of(listener, struct g2d_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 g2d_surface_state *gs; ++ struct g2d_renderer *gr; ++ ++ gr = data; ++ ++ gs = container_of(listener, struct g2d_surface_state, ++ renderer_destroy_listener); ++ ++ surface_state_destroy(gs, gr); ++} ++ ++ ++static int ++g2d_renderer_create_surface(struct weston_surface *surface) ++{ ++ struct g2d_surface_state *gs; ++ struct g2d_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) { ++ g2d_renderer_attach(surface, surface->buffer_ref.buffer); ++ g2d_renderer_flush_damage(surface); ++ } ++ ++ return 0; ++} ++ ++static void ++g2d_renderer_surface_set_color(struct weston_surface *surface, ++ float red, float green, float blue, float alpha) ++{ ++ struct g2d_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 ++g2d_renderer_output_destroy(struct weston_output *output) ++{ ++ struct g2d_output_state *go = get_output_state(output); ++ gctUINT32 i; ++ ++ for (i = 0; i < 2; i++) ++ { ++ pixman_region32_fini(&go->buffer_damage[i]); ++ } ++ ++ if(go->offscreen_buf) ++ { ++ g2d_free(go->offscreen_buf); ++ go->offscreen_buf = NULL; ++ } ++ ++ if(go->fb_fd) ++ { ++ close(go->fb_fd); ++ go->fb_fd = 0; ++ } ++ ++ if(go->renderSurf) ++ { ++ free(go->renderSurf); ++ go->renderSurf = NULL; ++ } ++ ++ free(go); ++} ++ ++static void ++g2d_renderer_destroy(struct weston_compositor *ec) ++{ ++ struct g2d_renderer *gr = get_renderer(ec); ++ ++ wl_signal_emit(&gr->destroy_signal, gr); ++ wl_global_destroy(gr->viv_global); ++ g2d_close(gr->handle); ++ free(ec->renderer); ++ ec->renderer = NULL; ++} ++ ++static int ++g2d_renderer_create(struct weston_compositor *ec) ++{ ++ struct g2d_renderer *gr; ++ gr = malloc(sizeof *gr); ++ if (gr == NULL) ++ return -1; ++ ++ gr->base.read_pixels = g2d_renderer_read_pixels; ++ gr->base.repaint_output = g2d_renderer_repaint_output; ++ gr->base.flush_damage = g2d_renderer_flush_damage; ++ gr->base.attach = g2d_renderer_attach; ++ gr->base.surface_set_color = g2d_renderer_surface_set_color; ++ gr->base.destroy = g2d_renderer_destroy; ++ ++ if(g2d_open(&gr->handle)) ++ { ++ weston_log("g2d_open fail.\n"); ++ return -1; ++ } ++ ec->renderer = &gr->base; ++ wl_signal_init(&gr->destroy_signal); ++ return 0; ++} ++ ++static int ++calculate_g2d_format(struct fb_var_screeninfo *varinfo, enum g2d_format *g2dFormat) ++{ ++ /* Get the color format. */ ++ switch (varinfo->green.length) ++ { ++ case 6: ++ *g2dFormat= G2D_RGB565; ++ break; ++ ++ case 8: ++ if (varinfo->blue.offset == 0) ++ { ++ *g2dFormat = (varinfo->transp.length == 0) ? G2D_BGRX8888 : G2D_BGRA8888; ++ } ++ else ++ { ++ *g2dFormat = (varinfo->transp.length == 0) ? G2D_RGBX8888 : G2D_RGBA8888; ++ } ++ break; ++ ++ default: ++ *g2dFormat = -1; ++ break; ++ } ++ return 0; ++} ++ ++static int ++get_G2dSurface_from_screeninfo(struct fb_screeninfo *info, struct g2d_surfaceEx* g2dSurface) ++{ ++ if(info && g2dSurface) ++ { ++ g2dSurface->base.planes[0] = info->physical; ++ g2dSurface->base.left = 0; ++ g2dSurface->base.top = 0; ++ g2dSurface->base.right = info->x_resolution; ++ g2dSurface->base.bottom = info->y_resolution; ++ g2dSurface->base.stride = info->x_resolution; ++ g2dSurface->base.width = info->x_resolution; ++ g2dSurface->base.height = info->y_resolution; ++ g2dSurface->base.format = info->pixel_format; ++ g2dSurface->base.rot = G2D_ROTATION_0; ++ g2dSurface->base.clrcolor = 0xFF400000; ++ g2dSurface->tiling = G2D_LINEAR; ++ return 0; ++ } ++ return -1; ++} ++ ++static int ++fb_query_screen_info(struct g2d_output_state *output, int fd, ++ struct fb_screeninfo *info) ++{ ++ struct g2d_output_state *go = output; ++ struct fb_var_screeninfo *varinfo = &info->varinfo; ++ struct fb_fix_screeninfo *fixinfo = &info->fixinfo; ++ ++ /* Probe the device for screen information. */ ++ if (ioctl(fd, FBIOGET_VSCREENINFO, varinfo) < 0) { ++ return -1; ++ } ++ ++ if(go->nNumBuffers > 1){ ++ varinfo->yres_virtual = varinfo->yres * go->nNumBuffers; ++ if (ioctl(fd, FBIOPUT_VSCREENINFO, varinfo) < 0) ++ return -1; ++ } ++ ++ if (ioctl(fd, FBIOGET_FSCREENINFO, fixinfo) < 0 || ++ ioctl(fd, FBIOGET_VSCREENINFO, varinfo) < 0){ ++ return -1; ++ } ++ /* Store the pertinent data. */ ++ info->x_resolution = varinfo->xres; ++ info->y_resolution = varinfo->yres; ++ info->physical = fixinfo->smem_start; ++ info->buffer_length = fixinfo->smem_len; ++ calculate_g2d_format(varinfo, &info->pixel_format); ++ ++ if (info->pixel_format < 0) { ++ weston_log("Frame buffer uses an unsupported format.\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int ++fb_frame_buffer_open(struct g2d_output_state *output, const char *fb_dev, ++ struct fb_screeninfo *screen_info) ++{ ++ /* Open the frame buffer device. */ ++ output->fb_fd = open(fb_dev, O_RDWR | O_CLOEXEC); ++ if (output->fb_fd < 0) { ++ weston_log("Failed to open frame buffer device%s \n", fb_dev); ++ return -1; ++ } ++ ++ /* Grab the screen info. */ ++ if (fb_query_screen_info(output, output->fb_fd, screen_info) < 0) { ++ weston_log("Failed to get frame buffer info \n"); ++ ++ close(output->fb_fd); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int ++g2d_renderer_output_create(struct weston_output *output, struct wl_display *wl_display, const char *device) ++ ++ { ++ struct g2d_renderer *gr = get_renderer(output->compositor); ++ struct g2d_output_state *go; ++ int i = 0; ++ int offset = 0; ++ char *p = NULL; ++ go = zalloc(sizeof *go); ++ if (go == NULL) ++ return -1; ++ ++ output->renderer_state = go; ++ gr->viv_global = gcoOS_WaylandCreateVivGlobal(wl_display); ++ ++ p = getenv("FB_MULTI_BUFFER"); ++ if (p == gcvNULL) ++ { ++ go->nNumBuffers = 1; ++ } ++ else ++ { ++ go->nNumBuffers = atoi(p); ++ if (go->nNumBuffers < 1) ++ { ++ go->nNumBuffers = 1; ++ } ++ else if(go->nNumBuffers >= 2) ++ { ++ go->nNumBuffers = 2; ++ go->activebuffer = 1; ++ } ++ } ++ weston_log("FB_MULTI_BUFFER = %d\n", go->nNumBuffers); ++ ++ if(fb_frame_buffer_open(go, device, &go->fb_info) < 0) ++ { ++ weston_log("Open frame buffer failed.\n"); ++ return -1; ++ } ++ ++ go->renderSurf = zalloc(sizeof(struct g2d_surfaceEx) * go->nNumBuffers); ++ offset = go->fb_info.buffer_length/go->nNumBuffers; ++ for(i = 0; i < go->nNumBuffers; i++) ++ { ++ get_G2dSurface_from_screeninfo(&go->fb_info, &go->renderSurf[i]); ++ go->renderSurf[i].base.planes[0] = go->fb_info.physical ++ + (offset * i); ++ g2d_clear(gr->handle, &go->renderSurf[i].base); ++ } ++ ++ if(go->nNumBuffers == 1) ++ { ++ go->offscreenSurface = (go->renderSurf[go->activebuffer]); ++ go->offscreen_buf = g2d_alloc(go->fb_info.buffer_length, 0); ++ go->offscreenSurface.base.planes[0] = go->offscreen_buf->buf_paddr; ++ g2d_clear(gr->handle, &go->offscreenSurface.base); ++ } ++ ++ g2d_finish(gr->handle); ++ for (i = 0; i < 2; i++) ++ pixman_region32_init(&go->buffer_damage[i]); ++ return 0; ++ } ++ ++ WL_EXPORT struct g2d_renderer_interface g2d_renderer_interface = { ++ .create = g2d_renderer_create, ++ .output_create = g2d_renderer_output_create, ++ .output_destroy = g2d_renderer_output_destroy, ++}; +Index: weston-1.11.0/src/g2d-renderer.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ weston-1.11.0/src/g2d-renderer.h 2016-10-06 14:28:47.000000000 -0500 +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (c) 2015 Freescale Semiconductor, Inc. ++ * Copyright © 2013 Vasily Khoruzhick ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++#ifndef __g2d_renderer_h_ ++#define __g2d_renderer_h_ ++ ++#include "compositor.h" ++#ifdef ENABLE_EGL ++#include ++#else ++#include ++#endif ++ ++ ++struct g2d_renderer_interface { ++ ++ int (*create)(struct weston_compositor *ec); ++ ++ int (*output_create)(struct weston_output *output, ++ struct wl_display *wl_display, ++ const char *device); ++ ++ void (*output_destroy)(struct weston_output *output); ++}; ++ ++#endif +Index: weston-1.11.0/src/gal2d-renderer.c +=================================================================== +--- weston-1.11.0.orig/src/gal2d-renderer.c 2016-10-06 14:26:20.678566959 -0500 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1307 +0,0 @@ +-/* +- * Copyright (c) 2015 Freescale Semiconductor, Inc. +- * Copyright © 2012 Intel Corporation +- * Copyright © 2015 Collabora, Ltd. +- * +- * Permission is hereby granted, free of charge, to any person obtaining +- * a copy of this software and associated documentation files (the +- * "Software"), to deal in the Software without restriction, including +- * without limitation the rights to use, copy, modify, merge, publish, +- * distribute, sublicense, and/or sell copies of the Software, and to +- * permit persons to whom the Software is furnished to do so, subject to +- * the following conditions: +- * +- * The above copyright notice and this permission notice (including the +- * next paragraph) shall be included in all copies or substantial +- * portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +- * SOFTWARE. +- */ +- +-#define _GNU_SOURCE +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "compositor.h" +-#include "gal2d-renderer.h" +-#include "vertex-clipping.h" +-#include "shared/helpers.h" +-#include "HAL/gc_hal.h" +-#include "HAL/gc_hal_raster.h" +-#include "HAL/gc_hal_eglplatform.h" +- +-#define galONERROR(x) if(status < 0) printf("Error in function %s\n", __func__); +- +-struct gal2d_output_state { +- +- int current_buffer; +- pixman_region32_t buffer_damage[2]; +- NativeDisplayType display; +- gcoSURF* renderSurf; +- gctUINT32 nNumBuffers; +- int activebuffer; +- gcoSURF offscreenSurface; +- gceSURF_FORMAT format; +- pthread_mutex_t workerMutex; +- pthread_t workerId; +- gctUINT32 exitWorker; +- gctSIGNAL signal; +- gctSIGNAL busySignal; +- gcsHAL_INTERFACE iface; +- int directBlit; +- gctINT width; +- gctINT height; +-}; +- +-struct gal2d_surface_state { +- float color[4]; +- struct weston_buffer_reference buffer_ref; +- int pitch; /* in pixels */ +- pixman_region32_t texture_damage; +- gcoSURF gco_Surface; +- +- struct weston_surface *surface; +- struct wl_listener surface_destroy_listener; +- struct wl_listener renderer_destroy_listener; +-}; +- +-struct gal2d_renderer { +- struct weston_renderer base; +- struct wl_signal destroy_signal; +- gcoOS gcos; +- gcoHAL gcoHal; +- gco2D gcoEngine2d; +- gctPOINTER localInfo; +-}; +- +-static int +-gal2d_renderer_create_surface(struct weston_surface *surface); +- +-static inline struct gal2d_surface_state * +-get_surface_state(struct weston_surface *surface) +-{ +- if (!surface->renderer_state) +- gal2d_renderer_create_surface(surface); +- return (struct gal2d_surface_state *)surface->renderer_state; +-} +- +-static inline struct gal2d_renderer * +-get_renderer(struct weston_compositor *ec) +-{ +- return (struct gal2d_renderer *)ec->renderer; +-} +- +- +- +-#define max(a, b) (((a) > (b)) ? (a) : (b)) +-#define min(a, b) (((a) > (b)) ? (b) : (a)) +-/* +- * Compute the boundary vertices of the intersection of the global coordinate +- * aligned rectangle 'rect', and an arbitrary quadrilateral produced from +- * 'surf_rect' when transformed from surface coordinates into global coordinates. +- * The vertices are written to 'ex' and 'ey', and the return value is the +- * number of vertices. Vertices are produced in clockwise winding order. +- * Guarantees to produce either zero vertices, or 3-8 vertices with non-zero +- * polygon area. +- */ +-static int +-calculate_edges(struct weston_view *ev, pixman_box32_t *rect, +- pixman_box32_t *surf_rect, float *ex, float *ey) +-{ +- +- struct clip_context ctx; +- int i, n; +- float min_x, max_x, min_y, max_y; +- struct polygon8 surf = { +- { surf_rect->x1, surf_rect->x2, surf_rect->x2, surf_rect->x1 }, +- { surf_rect->y1, surf_rect->y1, surf_rect->y2, surf_rect->y2 }, +- 4 +- }; +- +- ctx.clip.x1 = rect->x1; +- ctx.clip.y1 = rect->y1; +- ctx.clip.x2 = rect->x2; +- ctx.clip.y2 = rect->y2; +- +- /* transform surface to screen space: */ +- for (i = 0; i < surf.n; i++) +- weston_view_to_global_float(ev, surf.x[i], surf.y[i], +- &surf.x[i], &surf.y[i]); +- +- /* find bounding box: */ +- min_x = max_x = surf.x[0]; +- min_y = max_y = surf.y[0]; +- +- for (i = 1; i < surf.n; i++) { +- min_x = min(min_x, surf.x[i]); +- max_x = max(max_x, surf.x[i]); +- min_y = min(min_y, surf.y[i]); +- max_y = max(max_y, surf.y[i]); +- } +- +- /* First, simple bounding box check to discard early transformed +- * surface rects that do not intersect with the clip region: +- */ +- if ((min_x >= ctx.clip.x2) || (max_x <= ctx.clip.x1) || +- (min_y >= ctx.clip.y2) || (max_y <= ctx.clip.y1)) +- return 0; +- +- /* Simple case, bounding box edges are parallel to surface edges, +- * there will be only four edges. We just need to clip the surface +- * vertices to the clip rect bounds: +- */ +- if (!ev->transform.enabled) +- return clip_simple(&ctx, &surf, ex, ey); +- +- /* Transformed case: use a general polygon clipping algorithm to +- * clip the surface rectangle with each side of 'rect'. +- * The algorithm is Sutherland-Hodgman, as explained in +- * http://www.codeguru.com/cpp/misc/misc/graphics/article.php/c8965/Polygon-Clipping.htm +- * but without looking at any of that code. +- */ +- n = clip_transformed(&ctx, &surf, ex, ey); +- +- if (n < 3) +- return 0; +- +- return n; +-} +- +- +-static inline struct gal2d_output_state * +-get_output_state(struct weston_output *output) +-{ +- return (struct gal2d_output_state *)output->renderer_state; +-} +- +-static 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 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; +- +- 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)); +- +- if(galIsYUVFormat(srcFormat) == gcvSTATUS_TRUE) +- { +- useFilterBlit = 1; +- } +- 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); +- gcmVERIFY_OK(gco2D_SetSource(gr->gcoEngine2d, &srcRect)); +- /* 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 || dstrect.left > dstWidth || dstrect.top > dstHeight) +- { +- 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 +- { +- gcmVERIFY_OK(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.right - srcRect.left, +- dstrect.right - dstrect.left, &horFactor)); +- +- gcmONERROR(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.bottom - srcRect.top, +- dstrect.bottom - dstrect.top, &verFactor)); +- +- if(verFactor == 65536 && horFactor == 65536) +- { +- gcmVERIFY_OK(gco2D_Blit(gr->gcoEngine2d, 1, &dstrect, +- 0xCC, 0xCC, go->format)); +- } +- else +- { +- dstrect.right = dstrect.right < dstWidth ? dstrect.right : dstWidth; +- dstrect.bottom = dstrect.bottom < dstHeight ? dstrect.bottom : dstHeight; +- srcRect.right = srcRect.right < dstWidth ? srcRect.right : dstWidth; +- srcRect.bottom = srcRect.bottom < dstHeight ? srcRect.bottom : dstHeight; +- +- gcmVERIFY_OK(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.right - srcRect.left, +- dstrect.right - dstrect.left, &horFactor)); +- +- gcmONERROR(gco2D_CalcStretchFactor(gr->gcoEngine2d, srcRect.bottom - srcRect.top, +- dstrect.bottom - dstrect.top, &verFactor)); +- /* Program the stretch factors. */ +- gcmVERIFY_OK(gco2D_SetStretchFactors(gr->gcoEngine2d, horFactor, verFactor)); +- +- 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, +-}; +Index: weston-1.11.0/src/gal2d-renderer.h +=================================================================== +--- weston-1.11.0.orig/src/gal2d-renderer.h 2016-10-06 14:26:20.254564856 -0500 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,50 +0,0 @@ +-/* +- * Copyright (c) 2015 Freescale Semiconductor, Inc. +- * Copyright © 2013 Vasily Khoruzhick +- * +- * Permission is hereby granted, free of charge, to any person obtaining +- * a copy of this software and associated documentation files (the +- * "Software"), to deal in the Software without restriction, including +- * without limitation the rights to use, copy, modify, merge, publish, +- * distribute, sublicense, and/or sell copies of the Software, and to +- * permit persons to whom the Software is furnished to do so, subject to +- * the following conditions: +- * +- * The above copyright notice and this permission notice (including the +- * next paragraph) shall be included in all copies or substantial +- * portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +- * SOFTWARE. +- */ +-#ifndef __gal_2d_renderer_h_ +-#define __gal_2d_renderer_h_ +- +-#include "compositor.h" +-#ifdef ENABLE_EGL +-#include +-#else +-#include +-typedef HALNativeDisplayType NativeDisplayType; +-typedef HALNativeWindowType NativeWindowType; +-#endif +- +- +-struct gal2d_renderer_interface { +- +- int (*create)(struct weston_compositor *ec); +- +- int (*output_create)(struct weston_output *output, +- NativeDisplayType display, +- NativeWindowType window); +- +- void (*output_destroy)(struct weston_output *output); +-}; +- +-#endif +Index: weston-1.11.0/src/main.c +=================================================================== +--- weston-1.11.0.orig/src/main.c 2016-10-06 14:26:20.258564876 -0500 ++++ weston-1.11.0/src/main.c 2016-10-06 14:28:47.000000000 -0500 +@@ -287,10 +287,10 @@ + " --device=DEVICE\tThe framebuffer device to use\n" + #if defined ENABLE_EGL + " --no-use-gl\t\tDo not use the GL renderer\n" +- " --use-gal2d\t\tUse the GAL2D renderer\n\n"); ++ " --use-g2d\t\tUse the G2D renderer\n\n"); + #else + " --use-gl\t\tUse the GL renderer\n" +- " --no-use-gal2d\t\tDo not use the GAL2D renderer\n\n"); ++ " --no-use-g2d\t\tDo not use the G2D renderer\n\n"); + #endif + #endif + +@@ -871,11 +871,11 @@ + char *s = NULL; + int ret = 0; + #ifdef ENABLE_EGL +- /* GL rendering is default, so user options are --no-use-gl and --use-gal2d */ ++ /* GL rendering is default, so user options are --no-use-gl and --use-g2d */ + int no_use_gl = 0; + #else +- /* GAL2D rendering is default, so user options are --use-gl and --no-use-gal2d */ +- int no_use_gal2d = 0; ++ /* G2D rendering is default, so user options are --use-gl and --no-use-g2d */ ++ int no_use_g2d = 0; + #endif + + const struct weston_option fbdev_options[] = { +@@ -883,10 +883,10 @@ + { WESTON_OPTION_STRING, "device", 0, &config.device }, + #ifdef ENABLE_EGL + { WESTON_OPTION_BOOLEAN, "no-use-gl", 0, &no_use_gl }, +- { WESTON_OPTION_BOOLEAN, "use-gal2d", 0, &config.use_gal2d }, ++ { WESTON_OPTION_BOOLEAN, "use-g2d", 0, &config.use_g2d }, + #else + { WESTON_OPTION_BOOLEAN, "use-gl", 0, &config.use_gl }, +- { WESTON_OPTION_BOOLEAN, "no-use-gal2d", 0, &no_use_gal2d }, ++ { WESTON_OPTION_BOOLEAN, "no-use-g2d", 0, &no_use_g2d }, + #endif + }; + +@@ -897,7 +897,7 @@ + #ifdef ENABLE_EGL + config.use_gl = !no_use_gl; + #else +- config.use_gal2d = !no_use_gal2d; ++ config.use_g2d = !no_use_g2d; + #endif + section = weston_config_get_section(wc, "output", "name", "fbdev"); + weston_config_section_get_string(section, "transform", &s, "normal"); +Index: weston-1.11.0/src/compositor-fbdev.h +=================================================================== +--- weston-1.11.0.orig/src/compositor-fbdev.h 2016-10-06 14:26:20.258564876 -0500 ++++ weston-1.11.0/src/compositor-fbdev.h 2016-10-06 14:34:09.000000000 -0500 +@@ -40,7 +40,8 @@ + int tty; + char *device; + int use_gl; +- int use_gal2d; ++ int use_g2d; ++ int clone_mode; + + uint32_t output_transform; + }; diff --git a/recipes-graphics/wayland/weston/0010-MGS-1284-1-xwld-Re-implement-weston-2d-renderer-with.patch b/recipes-graphics/wayland/weston/0010-MGS-1284-1-xwld-Re-implement-weston-2d-renderer-with.patch new file mode 100644 index 00000000..96181aba --- /dev/null +++ b/recipes-graphics/wayland/weston/0010-MGS-1284-1-xwld-Re-implement-weston-2d-renderer-with.patch @@ -0,0 +1,36 @@ +From 9a19dd911fc79fa828b03fce8cdb16c6cfcb25cb Mon Sep 17 00:00:00 2001 +From: "yong.gan" +Date: Tue, 22 Mar 2016 10:15:31 +0800 +Subject: [PATCH 2/3] MGS-1284-1: xwld: Re-implement weston 2d renderer with + porting g2d API + +Add gpu address to the buffer physical address, fix the mess in sx board. + +Date: Feb 22, 2016 +Upstream Status: Inappropriate [i.MX specific] + +Signed-off-by: Yong Gan +--- + src/g2d-renderer.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/g2d-renderer.c b/src/g2d-renderer.c +index 756c8f0..19c93a0 100644 +--- a/src/g2d-renderer.c ++++ b/src/g2d-renderer.c +@@ -317,9 +317,9 @@ get_g2dSurface(gcsWL_VIV_BUFFER *buffer, struct g2d_surfaceEx *g2dSurface) + int height = buffer->alignedHeight; + g2d_getG2dFormat(buffer->format, &g2dSurface->base.format); + g2d_getG2dTiling(buffer->tiling, &g2dSurface->tiling); +- g2dSurface->base.planes[0] = buffer->physical[0]; +- g2dSurface->base.planes[1] = buffer->physical[1]; +- g2dSurface->base.planes[2] = buffer->physical[2]; ++ g2dSurface->base.planes[0] = buffer->physical[0] + buffer->gpuBaseAddr; ++ g2dSurface->base.planes[1] = buffer->physical[1] + buffer->gpuBaseAddr; ++ g2dSurface->base.planes[2] = buffer->physical[2] + buffer->gpuBaseAddr; + g2dSurface->base.left = 0; + g2dSurface->base.top = 0; + g2dSurface->base.right = buffer->width; +-- +1.9.1 + diff --git a/recipes-graphics/wayland/weston/0011-MGS-1724-xwld-G2D-compositor-build-failed-in-slevk-b.patch b/recipes-graphics/wayland/weston/0011-MGS-1724-xwld-G2D-compositor-build-failed-in-slevk-b.patch new file mode 100644 index 00000000..f7bee2fe --- /dev/null +++ b/recipes-graphics/wayland/weston/0011-MGS-1724-xwld-G2D-compositor-build-failed-in-slevk-b.patch @@ -0,0 +1,106 @@ +From b67a6184ed3b6d728894eba37a554a302c1b0312 Mon Sep 17 00:00:00 2001 +From: "yong.gan" +Date: Sat, 2 Apr 2016 09:33:56 +0800 +Subject: [PATCH 3/3] MGS-1724: xwld: G2D compositor build failed in slevk + board + +Add macro ENABLE_EGL to make sure the EGL was not built in slevk board. +Modify the wrong format for the shm buffer. + +Upstream Status: Inappropriate [i.MX specific] + +Signed-off-by: Yong Gan +--- + src/compositor-fbdev.c | 11 ++++++++++- + src/g2d-renderer.c | 4 ++-- + 2 files changed, 12 insertions(+), 3 deletions(-) + +Index: weston-1.11.0/src/compositor-fbdev.c +=================================================================== +--- weston-1.11.0.orig/src/compositor-fbdev.c 2016-10-06 13:11:53.376414804 -0500 ++++ weston-1.11.0/src/compositor-fbdev.c 2016-10-06 13:19:16.000000000 -0500 +@@ -63,7 +63,9 @@ + int use_g2d; + uint32_t output_transform; + struct wl_listener session_listener; ++#ifdef ENABLE_EGL + NativeDisplayType display; ++#endif + }; + + struct fbdev_screeninfo { +@@ -96,9 +98,10 @@ + /* pixman details. */ + pixman_image_t *hw_surface; + uint8_t depth; +- ++#ifdef ENABLE_EGL + NativeDisplayType display; + NativeWindowType window; ++#endif + }; + + struct gl_renderer_interface *gl_renderer; +@@ -450,10 +453,12 @@ + strerror(errno)); + + output->fb = NULL; ++#ifdef ENABLE_EGL + if(output->window) + fbDestroyWindow(output->window); + if(output->display) + fbDestroyDisplay(output->display); ++#endif + } + + static void fbdev_output_destroy(struct weston_output *base); +@@ -527,6 +532,7 @@ + } + + } else { ++#ifdef ENABLE_EGL + setenv("HYBRIS_EGLPLATFORM", "wayland", 1); + output->window = fbCreateWindow(backend->display, -1, -1, 0, 0); + if (output->window == NULL) { +@@ -540,6 +546,7 @@ + weston_log("gl_renderer_output_create failed.\n"); + goto out_hw_surface; + } ++#endif + } + + loop = wl_display_get_event_loop(backend->compositor->wl_display); +@@ -847,6 +854,7 @@ + } + } + else { ++#ifdef ENABLE_EGL + gl_renderer = weston_load_module("gl-renderer.so", + "gl_renderer_interface"); + if (!gl_renderer) { +@@ -866,6 +874,7 @@ + weston_log("gl_renderer_create failed.\n"); + goto out_launcher; + } ++#endif + } + if(!backend->use_g2d) + if (fbdev_output_create(backend, 0, 0, param->device) < 0) +Index: weston-1.11.0/src/g2d-renderer.c +=================================================================== +--- weston-1.11.0.orig/src/g2d-renderer.c 2016-10-06 13:11:53.376414804 -0500 ++++ weston-1.11.0/src/g2d-renderer.c 2016-10-06 13:11:53.372414784 -0500 +@@ -756,11 +756,11 @@ + + switch (wl_shm_buffer_get_format(shm_buffer)) { + case WL_SHM_FORMAT_XRGB8888: +- g2dFormat = G2D_XRGB8888; ++ g2dFormat = G2D_BGRX8888; + gs->bpp = 4; + break; + case WL_SHM_FORMAT_ARGB8888: +- g2dFormat = G2D_ARGB8888; ++ g2dFormat = G2D_BGRA8888; + gs->bpp = 4; + break; + case WL_SHM_FORMAT_RGB565: diff --git a/recipes-graphics/wayland/weston_%.bbappend b/recipes-graphics/wayland/weston_%.bbappend index 270adfa6..bb2e51a6 100644 --- a/recipes-graphics/wayland/weston_%.bbappend +++ b/recipes-graphics/wayland/weston_%.bbappend @@ -7,6 +7,9 @@ SRC_URI_append_imxgpu2d = " \ file://0005-MGS-1252-Fix-for-Qt5_CinematicExperience-will-meet-s.patch \ file://0006-MGS-1236-imx6qp-imx6dl-First-frame-distored-when-som.patch \ file://0007-MGS-1236-1-imx6qp-imx6dl-First-frame-distored-when-s.patch \ + file://0009-MGS-1284-xwld-Re-implement-weston-2d-renderer-with-p.patch \ + file://0010-MGS-1284-1-xwld-Re-implement-weston-2d-renderer-with.patch \ + file://0011-MGS-1724-xwld-G2D-compositor-build-failed-in-slevk-b.patch \ " PACKAGECONFIG_IMX_TO_APPEND = "" -- 2.40.1