void WriteableBitmap::Render (UIElement *element, Transform *transform) { CairoSurface *target; if (!element) return; cairo_surface_t *surface = GetSurface (NULL); if (!surface) { Invalidate (); // it could still be NULL (e.g. directly inheriting UIElement) surface = GetSurface (NULL); if (!surface) return; } target = new CairoSurface (surface); Rect bounds (0, 0, GetPixelWidth (), GetPixelHeight ()); cairo_matrix_t xform; cairo_matrix_init_identity (&xform); if (transform) transform->GetTransform (&xform); element->Paint (target, bounds, &xform); target->unref (); cairo_surface_flush (surface); }
int main (int argc, char **argv) { Context *ctx; CairoSurface *target; MoonSurface *surface; cairo_surface_t *dst, *src; TransformEffect *effect; Matrix3D *matrix; DoubleCollection *values; int stride = width * 4; Rect bounds = Rect (0, 0, width, height); gpointer data; bool status = true; int count = 1; if (argc < 2) { printf ("usage: %s MATRIX [COUNT]\n", argv[0]); return 1; } gtk_init (&argc, &argv); runtime_init_desktop (); values = DoubleCollection::FromStr (argv[1]); if (!values) { printf ("usage: %s MATRIX [COUNT]\n", argv[0]); return 1; } if (values->GetCount () != 16) { printf ("usage: %s MATRIX [COUNT]\n", argv[0]); values->unref (); return 1; } data = g_malloc0 (height * stride); dst = cairo_image_surface_create_for_data ((unsigned char *) data, CAIRO_FORMAT_ARGB32, width, height, stride); target = new CairoSurface (dst); cairo_surface_destroy (dst); ctx = new CairoContext (target); target->unref (); src = cairo_surface_create_similar (dst, CAIRO_CONTENT_COLOR_ALPHA, width, height); surface = new CairoSurface (src); cairo_surface_destroy (src); effect = new TransformEffect (); matrix = new Matrix3D (); matrix->SetM11 (values->GetValueAt (0)->AsDouble ()); matrix->SetM12 (values->GetValueAt (1)->AsDouble ()); matrix->SetM13 (values->GetValueAt (2)->AsDouble ()); matrix->SetM14 (values->GetValueAt (3)->AsDouble ()); matrix->SetM21 (values->GetValueAt (4)->AsDouble ()); matrix->SetM22 (values->GetValueAt (5)->AsDouble ()); matrix->SetM23 (values->GetValueAt (6)->AsDouble ()); matrix->SetM24 (values->GetValueAt (7)->AsDouble ()); matrix->SetM31 (values->GetValueAt (8)->AsDouble ()); matrix->SetM32 (values->GetValueAt (9)->AsDouble ()); matrix->SetM33 (values->GetValueAt (10)->AsDouble ()); matrix->SetM34 (values->GetValueAt (11)->AsDouble ()); matrix->SetOffsetX (values->GetValueAt (12)->AsDouble ()); matrix->SetOffsetY (values->GetValueAt (13)->AsDouble ()); matrix->SetOffsetZ (values->GetValueAt (14)->AsDouble ()); matrix->SetM44 (values->GetValueAt (15)->AsDouble ()); values->unref (); if (argc > 2) { count = atoi (argv[2]); if (count > 1) { signal (SIGALRM, projection_alarm_handler); alarm (5); } } while (status && count-- > 0) { status = effect->Render (ctx, surface, (double *) matrix->GetMatrixValues (), 0, 0, width, height); frames++; } matrix->unref (); surface->unref (); delete ctx; g_free (data); runtime_shutdown (); return status != true; }
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 }
/** * @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 }