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.1/Makefile.am =================================================================== --- weston-1.11.1.orig/Makefile.am 2017-01-14 08:59:52.293865810 -0600 +++ weston-1.11.1/Makefile.am 2017-01-14 09:08:38.000000000 -0600 @@ -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.1/src/compositor-fbdev.c =================================================================== --- weston-1.11.1.orig/src/compositor-fbdev.c 2017-01-14 08:59:52.473866702 -0600 +++ weston-1.11.1/src/compositor-fbdev.c 2017-01-14 09:19:12.000000000 -0600 @@ -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; @@ -922,13 +896,8 @@ * udev, rather than passing a device node in as a parameter. */ config->tty = 0; /* default to current tty */ config->device = "/dev/fb0"; /* default frame buffer */ -#ifdef ENABLE_EGL - config->use_gl = 1; - config->use_gal2d = 0; -#else config->use_gl = 0; - config->use_gal2d = 1; -#endif + config->use_g2d = 0; config->output_transform = WL_OUTPUT_TRANSFORM_NORMAL; } Index: weston-1.11.1/src/g2d-renderer.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ weston-1.11.1/src/g2d-renderer.c 2017-01-14 09:08:38.000000000 -0600 @@ -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.1/src/g2d-renderer.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ weston-1.11.1/src/g2d-renderer.h 2017-01-14 09:08:38.000000000 -0600 @@ -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.1/src/gal2d-renderer.c =================================================================== --- weston-1.11.1.orig/src/gal2d-renderer.c 2017-01-14 08:59:52.753868091 -0600 +++ /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.1/src/gal2d-renderer.h =================================================================== --- weston-1.11.1.orig/src/gal2d-renderer.h 2017-01-14 08:59:52.297865829 -0600 +++ /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.1/src/main.c =================================================================== --- weston-1.11.1.orig/src/main.c 2017-01-14 08:59:52.297865829 -0600 +++ weston-1.11.1/src/main.c 2017-01-14 09:08:38.000000000 -0600 @@ -287,10 +287,10 @@ " --device=DEVICE\tThe framebuffer device to use\n" #if defined ENABLE_EGL " --use-gl=1\t\tUse the GL renderer (default is 1)\n" - " --use-gal2d=1\t\tUse the GAL2D renderer (default is 0)\n\n"); + " --use-g2d=1\t\tUse the G2D renderer (default is 0)\n\n"); #else " --use-gl=1\t\tUse the GL renderer (default is 0)\n" - " --use-gal2d=1\t\tUse the GAL2D renderer (default is 1)\n\n"); + " --use-g2d=1\t\tUse the G2D renderer (default is 1)\n\n"); #endif #endif @@ -875,7 +875,7 @@ { WESTON_OPTION_INTEGER, "tty", 0, &config.tty }, { WESTON_OPTION_STRING, "device", 0, &config.device }, { WESTON_OPTION_INTEGER, "use-gl", 0, &config.use_gl }, - { WESTON_OPTION_INTEGER, "use-gal2d", 0, &config.use_gal2d }, + { WESTON_OPTION_INTEGER, "use-g2d", 0, &config.use_g2d }, }; parse_options(fbdev_options, ARRAY_LENGTH(fbdev_options), argc, argv); Index: weston-1.11.1/src/compositor-fbdev.h =================================================================== --- weston-1.11.1.orig/src/compositor-fbdev.h 2017-01-14 08:59:52.297865829 -0600 +++ weston-1.11.1/src/compositor-fbdev.h 2017-01-14 08:59:52.841868527 -0600 @@ -40,7 +40,8 @@ int tty; char *device; int use_gl; - int use_gal2d; + int use_g2d; + int clone_mode; uint32_t output_transform; };