From e01d3dd98d1b596e75d25f94dd89c7d41223011d Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Thu, 9 Aug 2007 10:55:10 +0200 Subject: [PATCH] Support clipping region in PutImage. * hw/kdrive/ephyr/ephyrhostvideo.c,h: (ephyrHostXVPutImage): make this support clipping region. The clipping region is propagated to host using XSetClipRectangles. This changes the API of ephyrHostXVPutImage. * hw/kdrive/ephyr/ephyrvideo.c: (ephyrPutImage): propagate the clipping region to the new ephyrHostXVPutImage() entry point. --- hw/kdrive/ephyr/ephyrhostvideo.c | 43 +++++++++++++++++++++++++------- hw/kdrive/ephyr/ephyrhostvideo.h | 8 +++++- hw/kdrive/ephyr/ephyrvideo.c | 26 +++---------------- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/hw/kdrive/ephyr/ephyrhostvideo.c b/hw/kdrive/ephyr/ephyrhostvideo.c index b1b926a45..85fc7bd8e 100644 --- a/hw/kdrive/ephyr/ephyrhostvideo.c +++ b/hw/kdrive/ephyr/ephyrhostvideo.c @@ -757,17 +757,21 @@ ephyrHostXVPutImage (int a_port_id, int a_src_h, int a_image_width, int a_image_height, - unsigned char *a_buf) + unsigned char *a_buf, + EphyrHostBox *a_clip_rects, + int a_clip_rect_nums ) { Bool is_ok=TRUE ; XvImage *xv_image=NULL ; GC gc=0 ; XGCValues gc_values; Display *dpy = hostx_get_display () ; + XRectangle *rects=NULL ; + int res = 0 ; EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ; - EPHYR_LOG ("enter\n") ; + EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ; gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values); if (!gc) { @@ -782,16 +786,32 @@ ephyrHostXVPutImage (int a_port_id, goto out ; } xv_image->data = (char*)a_buf ; - XvPutImage (dpy, a_port_id, hostx_get_window (), - gc, xv_image, - a_src_x, a_src_y, a_src_w, a_src_h, - a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; - XFlush (dpy) ; + if (a_clip_rect_nums) { + int i=0 ; + rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ; + for (i=0; i < a_clip_rect_nums; i++) { + rects[i].x = a_clip_rects[i].x1 ; + rects[i].y = a_clip_rects[i].y1 ; + rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1; + rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1; + EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n", + rects[i].x, rects[i].y, + rects[i].width, rects[i].height) ; + } + XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ; + /*this always returns 1*/ + } + res = XvPutImage (dpy, a_port_id, hostx_get_window (), + gc, xv_image, + a_src_x, a_src_y, a_src_w, a_src_h, + a_drw_x, a_drw_y, a_drw_w, a_drw_h) ; + if (res != Success) { + EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ; + goto out ; + } is_ok = TRUE ; out: - - EPHYR_LOG ("leave\n") ; if (xv_image) { XFree (xv_image) ; xv_image = NULL ; @@ -800,6 +820,11 @@ out: XFreeGC (dpy, gc) ; gc = NULL ; } + if (rects) { + free (rects) ; + rects = NULL ; + } + EPHYR_LOG ("leave\n") ; return is_ok ; } diff --git a/hw/kdrive/ephyr/ephyrhostvideo.h b/hw/kdrive/ephyr/ephyrhostvideo.h index 9c97c6a96..661792bab 100644 --- a/hw/kdrive/ephyr/ephyrhostvideo.h +++ b/hw/kdrive/ephyr/ephyrhostvideo.h @@ -84,6 +84,10 @@ typedef struct _EphyrHostImageFormat { int scanline_order; /* XvTopToBottom, XvBottomToTop */ } EphyrHostImageFormat ; +typedef struct { + unsigned short x1, y1, x2, y2 ; +} EphyrHostBox ; + void ephyrHostXVInit (void) ; void ephyrHostFree (void *a_pointer) ; @@ -197,7 +201,9 @@ Bool ephyrHostXVPutImage (int a_port_id, int a_src_h, int a_image_width, int a_image_height, - unsigned char *a_buf) ; + unsigned char *a_buf, + EphyrHostBox *a_clip_rects, + int a_clip_rect_nums) ; /* * Putvideo/PutStill/GetVideo diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c index 90c7535da..e2f00c8a1 100644 --- a/hw/kdrive/ephyr/ephyrvideo.c +++ b/hw/kdrive/ephyr/ephyrvideo.c @@ -613,7 +613,6 @@ ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this, goto out ; num_registered_adaptors = KdXVListGenericAdaptors (screen, ®istered_adaptors); - EPHYR_LOG ("") ; num_adaptors = num_registered_adaptors + a_this->num_adaptors ; adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ; @@ -824,36 +823,19 @@ ephyrPutImage (KdScreenInfo *a_info, pointer a_port_priv) { EphyrPortPriv *port_priv = a_port_priv ; - BoxRec clipped_area, dst_box ; int result=BadImplementation ; - int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ; EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ; EPHYR_LOG ("enter\n") ; - dst_box.x1 = a_drw_x ; - dst_box.x2 = a_drw_x + a_drw_w; - dst_box.y1 = a_drw_y ; - dst_box.y2 = a_drw_y + a_drw_h; - - if (!DoSimpleClip (&dst_box, - REGION_EXTENTS (pScreen->pScreen, a_clipping_region), - &clipped_area)) { - EPHYR_LOG_ERROR ("failed to simple clip\n") ; - goto out ; - } - - drw_x = clipped_area.x1 ; - drw_y = clipped_area.y1 ; - drw_w = clipped_area.x2 - clipped_area.x1 ; - drw_h = clipped_area.y2 - clipped_area.y1 ; - if (!ephyrHostXVPutImage (port_priv->port_number, a_id, - drw_x, drw_y, drw_w, drw_h, + a_drw_x, a_drw_y, a_drw_w, a_drw_h, a_src_x, a_src_y, a_src_w, a_src_h, - a_width, a_height, a_buf)) { + a_width, a_height, a_buf, + (EphyrHostBox*)REGION_RECTS (a_clipping_region), + REGION_NUM_RECTS (a_clipping_region))) { EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ; goto out ; }