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 }
void WriteableBitmap::Render (UIElement *element, Transform *transform) { MoonSurface *src; Context *ctx; if (!element) return; cairo_surface_t *surface = GetImageSurface (); if (!surface) return; Rect bounds (0, 0, GetPixelWidth (), GetPixelHeight ()); #ifdef USE_GALLIUM struct pipe_resource pt, *texture; GalliumSurface *target; struct pipe_screen *screen = swrast_screen_create (null_sw_create ()); memset (&pt, 0, sizeof (pt)); pt.target = PIPE_TEXTURE_2D; pt.format = PIPE_FORMAT_B8G8R8A8_UNORM; pt.width0 = 1; pt.height0 = 1; pt.depth0 = 1; pt.last_level = 0; pt.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_TRANSFER_WRITE | PIPE_BIND_TRANSFER_READ; texture = (*screen->resource_create) (screen, &pt); target = new GalliumSurface (texture); pipe_resource_reference (&texture, NULL); ctx = new GalliumContext (target); target->unref (); #else CairoSurface *target; target = new CairoSurface (1, 1); ctx = new CairoContext (target); target->unref (); #endif ctx->Push (Context::Group (bounds)); cairo_matrix_t xform; cairo_matrix_init_identity (&xform); if (transform) transform->GetTransform (&xform); FrameworkElement *fe = (FrameworkElement *)element; if (fe->GetFlowDirection () == FlowDirectionRightToLeft) { cairo_matrix_translate (&xform, fe->GetActualWidth (), 0.0); cairo_matrix_scale (&xform, -1, 1); } element->Paint (ctx, bounds, &xform); bounds = ctx->Pop (&src); if (!bounds.IsEmpty ()) { cairo_surface_t *image = src->Cairo (); cairo_t *cr = cairo_create (surface); cairo_set_source_surface (cr, image, 0, 0); cairo_paint (cr); cairo_destroy (cr); cairo_surface_destroy (image); src->unref (); } delete ctx; #ifdef USE_GALLIUM screen->destroy (screen); #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 }