From c4848526db77714406ecff83cf3ae1e6c0d4599e Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 18 Nov 2009 10:35:50 +0800 Subject: [PATCH] the VA API spec metion that the dest rectangle to vaAssociateSubpicture() is relative to the parent surface. So, we have another level of scaling since the surface can be scaled during vaPutSurface. This patch tries to fix that. --- i965_drv_video/i965_drv_video.c | 10 ++++- i965_drv_video/i965_drv_video.h | 14 +++--- i965_drv_video/i965_render.c | 99 +++++++++++++++++++++-------------------- 3 files changed, 66 insertions(+), 57 deletions(-) diff --git a/i965_drv_video/i965_drv_video.c b/i965_drv_video/i965_drv_video.c index 1dc424d..ec15c49 100644 --- a/i965_drv_video/i965_drv_video.c +++ b/i965_drv_video/i965_drv_video.c @@ -499,8 +499,14 @@ i965_AssociateSubpicture(VADriverContextP ctx, struct object_subpic *obj_subpic = SUBPIC(subpicture); int i; - obj_subpic->dstx = dest_x; - obj_subpic->dsty = dest_y; + obj_subpic->src_rect.x = src_x; + obj_subpic->src_rect.y = src_y; + obj_subpic->src_rect.width = src_width; + obj_subpic->src_rect.height = src_height; + obj_subpic->dst_rect.x = dest_x; + obj_subpic->dst_rect.y = dest_y; + obj_subpic->dst_rect.width = dest_width; + obj_subpic->dst_rect.height = dest_height; for (i = 0; i < num_surfaces; i++) { struct object_surface *obj_surface = SURFACE(target_surfaces[i]); diff --git a/i965_drv_video/i965_drv_video.h b/i965_drv_video/i965_drv_video.h index 855e6b9..785ab0a 100644 --- a/i965_drv_video/i965_drv_video.h +++ b/i965_drv_video/i965_drv_video.h @@ -91,7 +91,7 @@ struct object_surface struct object_base base; VASurfaceStatus status; VASubpictureID subpic; - int width; + int width; int height; int size; dri_bo *bo; @@ -118,12 +118,12 @@ struct object_subpic { struct object_base base; VAImageID image; - int dstx; - int dsty; - int width; - int height; - unsigned char palette[3][16]; - dri_bo *bo; + VARectangle src_rect; + VARectangle dst_rect; + int width; + int height; + unsigned char palette[3][16]; + dri_bo *bo; }; diff --git a/i965_drv_video/i965_render.c b/i965_drv_video/i965_render.c index 1e1b1dd..fecfc9e 100644 --- a/i965_drv_video/i965_render.c +++ b/i965_drv_video/i965_render.c @@ -788,58 +788,57 @@ i965_render_binding_table(VADriverContextP ctx) static void i965_subpic_render_upload_vertex(VADriverContextP ctx, - VASurfaceID surface, - short srcx, - short srcy, - unsigned short srcw, - unsigned short srch, - short destx, - short desty, - unsigned short destw, - unsigned short desth) + VASurfaceID surface, + const VARectangle *output_rect) { - struct i965_driver_data *i965 = i965_driver_data(ctx); + struct i965_driver_data *i965 = i965_driver_data(ctx); struct i965_render_state *render_state = &i965->render_state; - struct intel_region *dest_region = render_state->draw_region; - struct object_surface *obj_surface; - struct object_subpic *obj_subpic; - float *vb; - float src_scale_x, src_scale_y; - int i, width, height; - obj_surface = SURFACE(surface); - obj_subpic = SUBPIC(obj_surface->subpic); - assert(obj_surface); - assert(obj_subpic); - - int box_x1 = dest_region->x + obj_subpic->dstx; - int box_y1 = dest_region->y + obj_subpic->dsty; - int box_x2 = box_x1 + obj_subpic->width; - int box_y2 = box_y1 + obj_subpic->height; - - width = obj_surface->width; - height = obj_surface->height; - src_scale_x = ((float)srcw / width) / (float)destw; - src_scale_y = ((float)srch / height) / (float)desth; + struct object_surface *obj_surface = SURFACE(surface); + struct object_subpic *obj_subpic = SUBPIC(obj_surface->subpic); + + const float psx = (float)obj_surface->width / (float)obj_subpic->width; + const float psy = (float)obj_surface->height / (float)obj_subpic->height; + const float ssx = (float)output_rect->width / (float)obj_surface->width; + const float ssy = (float)output_rect->height / (float)obj_surface->height; + const float sx = psx * ssx; + const float sy = psy * ssy; + float *vb, tx1, tx2, ty1, ty2, x1, x2, y1, y2; + int i = 0; + + VARectangle dst_rect; + dst_rect.x = output_rect->x + sx * (float)obj_subpic->dst_rect.x; + dst_rect.y = output_rect->y + sx * (float)obj_subpic->dst_rect.y; + dst_rect.width = sx * (float)obj_subpic->dst_rect.width; + dst_rect.height = sy * (float)obj_subpic->dst_rect.height; dri_bo_map(render_state->vb.vertex_buffer, 1); assert(render_state->vb.vertex_buffer->virtual); vb = render_state->vb.vertex_buffer->virtual; - /*vertex covers the full subpicture*/ - i = 0; - vb[i++] = 1; - vb[i++] = 1; - vb[i++] = (float)box_x2; - vb[i++] = (float)box_y2; - - vb[i++] = 0.0; - vb[i++] = 1; - vb[i++] = (float)box_x1; - vb[i++] = (float)box_y2; - vb[i++] = 0.0; - vb[i++] = 0.0; - vb[i++] = (float)box_x1; - vb[i++] = (float)box_y1; + tx1 = (float)obj_subpic->src_rect.x / (float)obj_subpic->width; + ty1 = (float)obj_subpic->src_rect.y / (float)obj_subpic->height; + tx2 = (float)(obj_subpic->src_rect.x + obj_subpic->src_rect.width) / (float)obj_subpic->width; + ty2 = (float)(obj_subpic->src_rect.y + obj_subpic->src_rect.height) / (float)obj_subpic->height; + + x1 = (float)dst_rect.x; + y1 = (float)dst_rect.y; + x2 = (float)(dst_rect.x + dst_rect.width); + y2 = (float)(dst_rect.y + dst_rect.height); + + vb[i++] = tx2; + vb[i++] = ty2; + vb[i++] = x2; + vb[i++] = y2; + + vb[i++] = tx1; + vb[i++] = ty2; + vb[i++] = x1; + vb[i++] = y2; + + vb[i++] = tx1; + vb[i++] = ty1; + vb[i++] = x1; + vb[i++] = y1; dri_bo_unmap(render_state->vb.vertex_buffer); } @@ -947,9 +946,13 @@ i965_subpic_render_state_setup(VADriverContextP ctx, i965_render_cc_viewport(ctx); i965_subpic_render_cc_unit(ctx); i965_render_binding_table(ctx); - i965_subpic_render_upload_vertex(ctx, surface, - srcx, srcy, srcw, srch, - destx, desty, destw, desth); + + VARectangle output_rect; + output_rect.x = destx; + output_rect.y = desty; + output_rect.width = destw; + output_rect.height = desth; + i965_subpic_render_upload_vertex(ctx, surface, &output_rect); } -- 2.7.4