summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwenole Beauchesne <gbeauchesne@splitted-desktop.com>2009-11-18 10:35:50 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2009-11-18 11:51:11 +0800
commitc4848526db77714406ecff83cf3ae1e6c0d4599e (patch)
tree6f80705cf563aa1a2bdb2f0af9d32562b46c02b8
parent29dfeb7e59e86f05e46f4c280c4ba0ae8ac0c85f (diff)
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.
-rw-r--r--i965_drv_video/i965_drv_video.c10
-rw-r--r--i965_drv_video/i965_drv_video.h14
-rw-r--r--i965_drv_video/i965_render.c99
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);
}