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.
This commit is contained in:
parent
39d3895469
commit
e01d3dd98d
|
@ -757,17 +757,21 @@ ephyrHostXVPutImage (int a_port_id,
|
||||||
int a_src_h,
|
int a_src_h,
|
||||||
int a_image_width,
|
int a_image_width,
|
||||||
int a_image_height,
|
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 ;
|
Bool is_ok=TRUE ;
|
||||||
XvImage *xv_image=NULL ;
|
XvImage *xv_image=NULL ;
|
||||||
GC gc=0 ;
|
GC gc=0 ;
|
||||||
XGCValues gc_values;
|
XGCValues gc_values;
|
||||||
Display *dpy = hostx_get_display () ;
|
Display *dpy = hostx_get_display () ;
|
||||||
|
XRectangle *rects=NULL ;
|
||||||
|
int res = 0 ;
|
||||||
|
|
||||||
EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
|
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);
|
gc = XCreateGC (dpy, hostx_get_window (), 0L, &gc_values);
|
||||||
if (!gc) {
|
if (!gc) {
|
||||||
|
@ -782,16 +786,32 @@ ephyrHostXVPutImage (int a_port_id,
|
||||||
goto out ;
|
goto out ;
|
||||||
}
|
}
|
||||||
xv_image->data = (char*)a_buf ;
|
xv_image->data = (char*)a_buf ;
|
||||||
XvPutImage (dpy, a_port_id, hostx_get_window (),
|
if (a_clip_rect_nums) {
|
||||||
gc, xv_image,
|
int i=0 ;
|
||||||
a_src_x, a_src_y, a_src_w, a_src_h,
|
rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ;
|
||||||
a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
|
for (i=0; i < a_clip_rect_nums; i++) {
|
||||||
XFlush (dpy) ;
|
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 ;
|
is_ok = TRUE ;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
||||||
EPHYR_LOG ("leave\n") ;
|
|
||||||
if (xv_image) {
|
if (xv_image) {
|
||||||
XFree (xv_image) ;
|
XFree (xv_image) ;
|
||||||
xv_image = NULL ;
|
xv_image = NULL ;
|
||||||
|
@ -800,6 +820,11 @@ out:
|
||||||
XFreeGC (dpy, gc) ;
|
XFreeGC (dpy, gc) ;
|
||||||
gc = NULL ;
|
gc = NULL ;
|
||||||
}
|
}
|
||||||
|
if (rects) {
|
||||||
|
free (rects) ;
|
||||||
|
rects = NULL ;
|
||||||
|
}
|
||||||
|
EPHYR_LOG ("leave\n") ;
|
||||||
return is_ok ;
|
return is_ok ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,10 @@ typedef struct _EphyrHostImageFormat {
|
||||||
int scanline_order; /* XvTopToBottom, XvBottomToTop */
|
int scanline_order; /* XvTopToBottom, XvBottomToTop */
|
||||||
} EphyrHostImageFormat ;
|
} EphyrHostImageFormat ;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned short x1, y1, x2, y2 ;
|
||||||
|
} EphyrHostBox ;
|
||||||
|
|
||||||
void ephyrHostXVInit (void) ;
|
void ephyrHostXVInit (void) ;
|
||||||
|
|
||||||
void ephyrHostFree (void *a_pointer) ;
|
void ephyrHostFree (void *a_pointer) ;
|
||||||
|
@ -197,7 +201,9 @@ Bool ephyrHostXVPutImage (int a_port_id,
|
||||||
int a_src_h,
|
int a_src_h,
|
||||||
int a_image_width,
|
int a_image_width,
|
||||||
int a_image_height,
|
int a_image_height,
|
||||||
unsigned char *a_buf) ;
|
unsigned char *a_buf,
|
||||||
|
EphyrHostBox *a_clip_rects,
|
||||||
|
int a_clip_rect_nums) ;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Putvideo/PutStill/GetVideo
|
* Putvideo/PutStill/GetVideo
|
||||||
|
|
|
@ -613,7 +613,6 @@ ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
|
||||||
goto out ;
|
goto out ;
|
||||||
num_registered_adaptors =
|
num_registered_adaptors =
|
||||||
KdXVListGenericAdaptors (screen, ®istered_adaptors);
|
KdXVListGenericAdaptors (screen, ®istered_adaptors);
|
||||||
EPHYR_LOG ("") ;
|
|
||||||
|
|
||||||
num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
|
num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
|
||||||
adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
|
adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
|
||||||
|
@ -824,36 +823,19 @@ ephyrPutImage (KdScreenInfo *a_info,
|
||||||
pointer a_port_priv)
|
pointer a_port_priv)
|
||||||
{
|
{
|
||||||
EphyrPortPriv *port_priv = a_port_priv ;
|
EphyrPortPriv *port_priv = a_port_priv ;
|
||||||
BoxRec clipped_area, dst_box ;
|
|
||||||
int result=BadImplementation ;
|
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_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
|
||||||
|
|
||||||
EPHYR_LOG ("enter\n") ;
|
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,
|
if (!ephyrHostXVPutImage (port_priv->port_number,
|
||||||
a_id,
|
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_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") ;
|
EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
|
||||||
goto out ;
|
goto out ;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue