Esempio n. 1
0
void
MoonWindowGtk::PaintToDrawable (GdkDrawable *drawable, GdkVisual *visual, GdkEventExpose *event, int off_x, int off_y, bool transparent, bool clear_transparent)
{
// 	LOG_UI ("Surface::PaintToDrawable (%p, %p, (%d,%d %d,%d), %d, %d, %d, %d)\n",
// 		drawable, visual, event->area.x, event->area.y, event->area.width, event->area.height,
// 		off_x, off_y, transparent, clear_transparent);
	
	SetCurrentDeployment ();

#if 0
#if TIME_REDRAW
	STARTTIMER (expose, "redraw");
#endif
	if (cache_size_multiplier == -1)
		cache_size_multiplier = gdk_drawable_get_depth (drawable) / 8 + 1;
#endif
	int width, height;
	gdk_drawable_get_size (drawable, &width, &height);
	Context *ctx;
	GdkRectangle area = event->area;
	MoonSurface *src;
	Rect r = Rect (area.x, area.y, area.width, area.height);

	if (!native)
		native = CreateCairoSurface (drawable, visual, true, width, height);
	cairo_xlib_surface_set_drawable (native,
					 gdk_x11_drawable_get_xid (drawable),
					 width, height);
	cairo_surface_set_device_offset (native, off_x, off_y);

	Region *region = new Region ();
	int count = 0;
	GdkRectangle *rects;
	gdk_region_get_rectangles (event->region, &rects, &count);
	while (count--) {
		GdkRectangle c = rects[count];
		region->Union (Rect (c.x, c.y, c.width, c.height));
	}

#ifdef USE_GALLIUM
	if (gctx) {
		ctx = gctx;
	}
	else {
		struct pipe_resource pt, *texture;
		GalliumSurface       *target;

		memset (&pt, 0, sizeof (pt));
		pt.target = PIPE_TEXTURE_2D;
		pt.format = PIPE_FORMAT_B8G8R8A8_UNORM;
		pt.width0 = width;
		pt.height0 = height;
		pt.depth0 = 1;
		pt.last_level = 0;
		pt.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_TRANSFER_WRITE |
			PIPE_BIND_TRANSFER_READ;

		g_assert (screen);

		texture = (*screen->resource_create) (screen, &pt);

		target = new GalliumSurface (texture);
		pipe_resource_reference (&texture, NULL);
		ctx = new GalliumContext (target);
		target->unref ();

		if (gctxn < CONTEXT_CACHE_SIZE) {
			gctxn++;
			gctx = ctx;
		}
	}
#else
	CairoSurface *target = new CairoSurface (1, 1);
	ctx = new CairoContext (target);
	target->unref ();
#endif

	ctx->Push (Context::Group (r));
	/* if we are redirecting to an image surface clear that first */
	surface->Paint (ctx, region, transparent, true);

	r = ctx->Pop (&src);
	if (!r.IsEmpty ()) {
		cairo_surface_t *image = src->Cairo ();
		cairo_t         *cr = cairo_create (native);

		cairo_surface_flush (image);

		cairo_set_source_surface (cr, image, r.x, r.y);
		cairo_set_operator (cr, clear_transparent ? CAIRO_OPERATOR_SOURCE : CAIRO_OPERATOR_OVER);

		region->Draw (cr);
		cairo_fill (cr);

		cairo_destroy (cr);
		cairo_surface_destroy (image);
		src->unref ();
	}

#ifdef USE_GALLIUM
	if (ctx != gctx)
#endif
		delete ctx;

	delete region;

#if TIME_REDRAW
	ENDTIMER (expose, "redraw");
#endif

}
Esempio n. 2
0
/**
 * @fn	   void PaintToDrawable (GdkVisual *visual, cairo_t *cr_t, GtkAllocation &allocation, bool transparent, bool clear_transparent);
 * @brief   Paints to moonlight window drawable and sets transparency to display the video
 *		   and sends the video-rect event  to uniplayer
 * @param   visual			GdkVisual
 * @param   cr_t       		cairo_t
 * @param   allocation   	GtkAllocation
 * @param   transparent			bool
 * @param   clear_transparent	bool
 * @return  void
 */
void
MoonWindowGtk::PaintToDrawable (GdkVisual *visual, cairo_t *cr_t, GtkAllocation &allocation, bool transparent, bool clear_transparent)
{
	SetCurrentDeployment ();

#if 0
#if TIME_REDRAW
	STARTTIMER (expose, "redraw");
#endif
	if (cache_size_multiplier == -1)
	{
		cache_size_multiplier = gdk_drawable_get_depth (drawable) / 8 + 1;
	}
#endif

	Context *ctx;

	cairo_rectangle_int_t area;
	area.x = allocation.x;
	area.y = allocation.y;
	area.width = allocation.width;
	area.height = allocation.height;

	MoonSurface *src;
	Rect r = Rect (area.x, area.y, area.width, area.height);

	Region *region = new Region ();
	int count = 0;

	cairo_region_t *t_region  = cairo_region_create_rectangle(&area);
	count = cairo_region_num_rectangles (t_region);
	cairo_rectangle_int_t rects[count];
	
	for(int i=0;i<count;i++)
	{
		cairo_region_get_rectangle (t_region, i, &rects[i]);
	}

	while (count--)
	{
		cairo_rectangle_int_t c = rects[count];
		region->Union (Rect (c.x, c.y, c.width, c.height));
	}

#ifdef USE_GALLIUM
	if (gctx)
	{
			ctx = gctx;
	}
	else
	{
		struct pipe_resource pt, *texture;
		GalliumSurface       *target;

		memset (&pt, 0, sizeof (pt));
		pt.target = PIPE_TEXTURE_2D;
		pt.format = PIPE_FORMAT_B8G8R8A8_UNORM;
		pt.width0 = width;
		pt.height0 = height;
		pt.depth0 = 1;
		pt.last_level = 0;
		pt.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_TRANSFER_WRITE |
				PIPE_BIND_TRANSFER_READ;

		g_assert (screen);

		texture = (*screen->resource_create) (screen, &pt);

		target = new GalliumSurface (texture);
		pipe_resource_reference (&texture, NULL);
		ctx = new GalliumContext (target);
		target->unref ();

		if (gctxn < CONTEXT_CACHE_SIZE)
		{
			gctxn++;
			gctx = ctx;
		}
	}
#else
    CairoSurface *target = new CairoSurface (1, 1);
	ctx = new CairoContext (target);
	target->unref ();
#endif
	ctx->Push (Context::Group (r));
	surface->Paint (ctx, region, transparent, true);

	r = ctx->Pop (&src);
	if (!r.IsEmpty ())
	{
		cairo_surface_t *image = (cairo_surface_t*) src->Cairo ();
	
			cairo_surface_flush (image);
			cairo_set_source_surface (cr_t, image, r.x, r.y); 
			cairo_set_operator (cr_t, clear_transparent ? CAIRO_OPERATOR_SOURCE : CAIRO_OPERATOR_OVER);
		region->Draw (cr_t);
		cairo_fill (cr_t);

		cairo_surface_destroy (image);
		src->unref ();
	}


#ifdef USE_GALLIUM
    if (ctx != gctx)
#endif
	    delete ctx;

        delete region;

#if TIME_REDRAW
        ENDTIMER (expose, "redraw");
#endif
}