[meta-freescale] [meta-fsl-arm][PATCH 2/6] weston: Re-implement renderer using G2D

Tom Hochstein tom.hochstein at nxp.com
Fri Oct 7 15:36:55 PDT 2016


Change i.MX renderer from gal2d to g2d API.

Signed-off-by: Tom Hochstein <tom.hochstein at nxp.com>
---
 ...ld-Re-implement-weston-2d-renderer-with-p.patch | 2869 ++++++++++++++++++++
 ...xwld-Re-implement-weston-2d-renderer-with.patch |   36 +
 ...ld-G2D-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 0000000..0afbd4b
--- /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" <yong.gan at nxp.com>
+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 <yong.gan at freescale.com>
+---
+ 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 <stdlib.h>
++#include <string.h>
++#include <ctype.h>
++#include <float.h>
++#include <assert.h>
++#include <pthread.h>
++#include <linux/fb.h>
++#include <sys/ioctl.h>
++#include <fcntl.h>
++#include <unistd.h>
++
++#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 <anarsoul at gmail.com>
++ *
++ * 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 <EGL/egl.h>
++#else
++#include <HAL/gc_hal_eglplatform.h>
++#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 <stdlib.h>
+-#include <string.h>
+-#include <ctype.h>
+-#include <float.h>
+-#include <assert.h>
+-#include <pthread.h>
+-
+-#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 <anarsoul at gmail.com>
+- *
+- * 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 <EGL/egl.h>
+-#else
+-#include <HAL/gc_hal_eglplatform.h>
+-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 0000000..96181ab
--- /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" <yong.gan at nxp.com>
+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 <yong.gan at freescale.com>
+---
+ 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 0000000..f7bee2f
--- /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" <yong.gan at nxp.com>
+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 <yong.gan at nxp.com>
+---
+ 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 0ccf7a3..815936c 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 = ""
-- 
1.9.1



More information about the meta-freescale mailing list