output.c revision 494e0025d995fb2cab04474d13880ee438b0c868
1/************************************************************************** 2 * 3 * Copyright 2010 Thomas Balling Sørensen. 4 * Copyright 2011 Christian König. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28 29#include <vdpau/vdpau.h> 30 31#include "util/u_debug.h" 32#include "util/u_memory.h" 33#include "util/u_sampler.h" 34#include "util/u_format.h" 35 36#include "vdpau_private.h" 37 38/** 39 * Create a VdpOutputSurface. 40 */ 41VdpStatus 42vlVdpOutputSurfaceCreate(VdpDevice device, 43 VdpRGBAFormat rgba_format, 44 uint32_t width, uint32_t height, 45 VdpOutputSurface *surface) 46{ 47 struct pipe_context *pipe; 48 struct pipe_resource res_tmpl, *res; 49 struct pipe_sampler_view sv_templ; 50 struct pipe_surface surf_templ; 51 52 vlVdpOutputSurface *vlsurface = NULL; 53 54 if (!(width && height)) 55 return VDP_STATUS_INVALID_SIZE; 56 57 vlVdpDevice *dev = vlGetDataHTAB(device); 58 if (!dev) 59 return VDP_STATUS_INVALID_HANDLE; 60 61 pipe = dev->context; 62 if (!pipe) 63 return VDP_STATUS_INVALID_HANDLE; 64 65 vlsurface = CALLOC(1, sizeof(vlVdpOutputSurface)); 66 if (!vlsurface) 67 return VDP_STATUS_RESOURCES; 68 69 vlsurface->device = dev; 70 71 memset(&res_tmpl, 0, sizeof(res_tmpl)); 72 73 res_tmpl.target = PIPE_TEXTURE_2D; 74 res_tmpl.format = FormatRGBAToPipe(rgba_format); 75 res_tmpl.width0 = width; 76 res_tmpl.height0 = height; 77 res_tmpl.depth0 = 1; 78 res_tmpl.array_size = 1; 79 res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 80 res_tmpl.usage = PIPE_USAGE_STATIC; 81 82 res = pipe->screen->resource_create(pipe->screen, &res_tmpl); 83 if (!res) { 84 FREE(dev); 85 return VDP_STATUS_ERROR; 86 } 87 88 vlVdpDefaultSamplerViewTemplate(&sv_templ, res); 89 vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ); 90 if (!vlsurface->sampler_view) { 91 pipe_resource_reference(&res, NULL); 92 FREE(dev); 93 return VDP_STATUS_ERROR; 94 } 95 96 memset(&surf_templ, 0, sizeof(surf_templ)); 97 surf_templ.format = res->format; 98 surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 99 vlsurface->surface = pipe->create_surface(pipe, res, &surf_templ); 100 if (!vlsurface->surface) { 101 pipe_resource_reference(&res, NULL); 102 FREE(dev); 103 return VDP_STATUS_ERROR; 104 } 105 106 *surface = vlAddDataHTAB(vlsurface); 107 if (*surface == 0) { 108 pipe_resource_reference(&res, NULL); 109 FREE(dev); 110 return VDP_STATUS_ERROR; 111 } 112 113 pipe_resource_reference(&res, NULL); 114 115 vl_compositor_init_state(&vlsurface->cstate, pipe); 116 vl_compositor_reset_dirty_area(&vlsurface->dirty_area); 117 118 return VDP_STATUS_OK; 119} 120 121/** 122 * Destroy a VdpOutputSurface. 123 */ 124VdpStatus 125vlVdpOutputSurfaceDestroy(VdpOutputSurface surface) 126{ 127 vlVdpOutputSurface *vlsurface; 128 129 vlsurface = vlGetDataHTAB(surface); 130 if (!vlsurface) 131 return VDP_STATUS_INVALID_HANDLE; 132 133 vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); 134 135 pipe_surface_reference(&vlsurface->surface, NULL); 136 pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); 137 vl_compositor_cleanup_state(&vlsurface->cstate); 138 139 vlRemoveDataHTAB(surface); 140 FREE(vlsurface); 141 142 return VDP_STATUS_OK; 143} 144 145/** 146 * Retrieve the parameters used to create a VdpOutputSurface. 147 */ 148VdpStatus 149vlVdpOutputSurfaceGetParameters(VdpOutputSurface surface, 150 VdpRGBAFormat *rgba_format, 151 uint32_t *width, uint32_t *height) 152{ 153 vlVdpOutputSurface *vlsurface; 154 155 vlsurface = vlGetDataHTAB(surface); 156 if (!vlsurface) 157 return VDP_STATUS_INVALID_HANDLE; 158 159 *rgba_format = PipeToFormatRGBA(vlsurface->sampler_view->texture->format); 160 *width = vlsurface->sampler_view->texture->width0; 161 *height = vlsurface->sampler_view->texture->height0; 162 163 return VDP_STATUS_OK; 164} 165 166/** 167 * Copy image data from a VdpOutputSurface to application memory in the 168 * surface's native format. 169 */ 170VdpStatus 171vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface, 172 VdpRect const *source_rect, 173 void *const *destination_data, 174 uint32_t const *destination_pitches) 175{ 176 return VDP_STATUS_NO_IMPLEMENTATION; 177} 178 179/** 180 * Copy image data from application memory in the surface's native format to 181 * a VdpOutputSurface. 182 */ 183VdpStatus 184vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface, 185 void const *const *source_data, 186 uint32_t const *source_pitches, 187 VdpRect const *destination_rect) 188{ 189 vlVdpOutputSurface *vlsurface; 190 struct pipe_box dst_box; 191 struct pipe_context *pipe; 192 193 vlsurface = vlGetDataHTAB(surface); 194 if (!vlsurface) 195 return VDP_STATUS_INVALID_HANDLE; 196 197 pipe = vlsurface->device->context; 198 if (!pipe) 199 return VDP_STATUS_INVALID_HANDLE; 200 201 vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); 202 203 dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture); 204 pipe->transfer_inline_write(pipe, vlsurface->sampler_view->texture, 0, 205 PIPE_TRANSFER_WRITE, &dst_box, *source_data, 206 *source_pitches, 0); 207 208 return VDP_STATUS_OK; 209} 210 211/** 212 * Copy image data from application memory in a specific indexed format to 213 * a VdpOutputSurface. 214 */ 215VdpStatus 216vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface, 217 VdpIndexedFormat source_indexed_format, 218 void const *const *source_data, 219 uint32_t const *source_pitch, 220 VdpRect const *destination_rect, 221 VdpColorTableFormat color_table_format, 222 void const *color_table) 223{ 224 vlVdpOutputSurface *vlsurface; 225 struct pipe_context *context; 226 struct vl_compositor *compositor; 227 struct vl_compositor_state *cstate; 228 229 enum pipe_format index_format; 230 enum pipe_format colortbl_format; 231 232 struct pipe_resource *res, res_tmpl; 233 struct pipe_sampler_view sv_tmpl; 234 struct pipe_sampler_view *sv_idx = NULL, *sv_tbl = NULL; 235 236 struct pipe_box box; 237 struct u_rect dst_rect; 238 239 vlsurface = vlGetDataHTAB(surface); 240 if (!vlsurface) 241 return VDP_STATUS_INVALID_HANDLE; 242 243 vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); 244 245 context = vlsurface->device->context; 246 compositor = &vlsurface->device->compositor; 247 cstate = &vlsurface->cstate; 248 249 index_format = FormatIndexedToPipe(source_indexed_format); 250 if (index_format == PIPE_FORMAT_NONE) 251 return VDP_STATUS_INVALID_INDEXED_FORMAT; 252 253 if (!source_data || !source_pitch) 254 return VDP_STATUS_INVALID_POINTER; 255 256 colortbl_format = FormatColorTableToPipe(color_table_format); 257 if (colortbl_format == PIPE_FORMAT_NONE) 258 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT; 259 260 if (!color_table) 261 return VDP_STATUS_INVALID_POINTER; 262 263 memset(&res_tmpl, 0, sizeof(res_tmpl)); 264 res_tmpl.target = PIPE_TEXTURE_2D; 265 res_tmpl.format = index_format; 266 267 if (destination_rect) { 268 res_tmpl.width0 = abs(destination_rect->x0-destination_rect->x1); 269 res_tmpl.height0 = abs(destination_rect->y0-destination_rect->y1); 270 } else { 271 res_tmpl.width0 = vlsurface->surface->texture->width0; 272 res_tmpl.height0 = vlsurface->surface->texture->height0; 273 } 274 res_tmpl.depth0 = 1; 275 res_tmpl.array_size = 1; 276 res_tmpl.usage = PIPE_USAGE_STAGING; 277 res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; 278 279 res = context->screen->resource_create(context->screen, &res_tmpl); 280 if (!res) 281 goto error_resource; 282 283 box.x = box.y = box.z = 0; 284 box.width = res->width0; 285 box.height = res->height0; 286 box.depth = res->depth0; 287 288 context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box, 289 source_data[0], source_pitch[0], 290 source_pitch[0] * res->height0); 291 292 memset(&sv_tmpl, 0, sizeof(sv_tmpl)); 293 u_sampler_view_default_template(&sv_tmpl, res, res->format); 294 295 sv_idx = context->create_sampler_view(context, res, &sv_tmpl); 296 pipe_resource_reference(&res, NULL); 297 298 if (!sv_idx) 299 goto error_resource; 300 301 memset(&res_tmpl, 0, sizeof(res_tmpl)); 302 res_tmpl.target = PIPE_TEXTURE_1D; 303 res_tmpl.format = colortbl_format; 304 res_tmpl.width0 = 1 << util_format_get_component_bits( 305 index_format, UTIL_FORMAT_COLORSPACE_RGB, 0); 306 res_tmpl.height0 = 1; 307 res_tmpl.depth0 = 1; 308 res_tmpl.array_size = 1; 309 res_tmpl.usage = PIPE_USAGE_STAGING; 310 res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; 311 312 res = context->screen->resource_create(context->screen, &res_tmpl); 313 if (!res) 314 goto error_resource; 315 316 box.x = box.y = box.z = 0; 317 box.width = res->width0; 318 box.height = res->height0; 319 box.depth = res->depth0; 320 321 context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box, color_table, 322 util_format_get_stride(colortbl_format, res->width0), 0); 323 324 memset(&sv_tmpl, 0, sizeof(sv_tmpl)); 325 u_sampler_view_default_template(&sv_tmpl, res, res->format); 326 327 sv_tbl = context->create_sampler_view(context, res, &sv_tmpl); 328 pipe_resource_reference(&res, NULL); 329 330 if (!sv_tbl) 331 goto error_resource; 332 333 vl_compositor_clear_layers(cstate); 334 vl_compositor_set_palette_layer(cstate, compositor, 0, sv_idx, sv_tbl, NULL, NULL, false); 335 vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 336 vl_compositor_render(cstate, compositor, vlsurface->surface, NULL); 337 338 pipe_sampler_view_reference(&sv_idx, NULL); 339 pipe_sampler_view_reference(&sv_tbl, NULL); 340 341 return VDP_STATUS_OK; 342 343error_resource: 344 pipe_sampler_view_reference(&sv_idx, NULL); 345 pipe_sampler_view_reference(&sv_tbl, NULL); 346 return VDP_STATUS_RESOURCES; 347} 348 349/** 350 * Copy image data from application memory in a specific YCbCr format to 351 * a VdpOutputSurface. 352 */ 353VdpStatus 354vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface, 355 VdpYCbCrFormat source_ycbcr_format, 356 void const *const *source_data, 357 uint32_t const *source_pitches, 358 VdpRect const *destination_rect, 359 VdpCSCMatrix const *csc_matrix) 360{ 361 return VDP_STATUS_NO_IMPLEMENTATION; 362} 363 364static unsigned 365BlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor) 366{ 367 switch (factor) { 368 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO: 369 return PIPE_BLENDFACTOR_ZERO; 370 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE: 371 return PIPE_BLENDFACTOR_ONE; 372 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR: 373 return PIPE_BLENDFACTOR_SRC_COLOR; 374 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: 375 return PIPE_BLENDFACTOR_INV_SRC_COLOR; 376 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA: 377 return PIPE_BLENDFACTOR_SRC_ALPHA; 378 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: 379 return PIPE_BLENDFACTOR_INV_SRC_ALPHA; 380 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA: 381 return PIPE_BLENDFACTOR_DST_ALPHA; 382 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: 383 return PIPE_BLENDFACTOR_INV_DST_ALPHA; 384 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR: 385 return PIPE_BLENDFACTOR_DST_COLOR; 386 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR: 387 return PIPE_BLENDFACTOR_INV_DST_COLOR; 388 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE: 389 return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE; 390 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR: 391 return PIPE_BLENDFACTOR_CONST_COLOR; 392 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: 393 return PIPE_BLENDFACTOR_INV_CONST_COLOR; 394 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA: 395 return PIPE_BLENDFACTOR_CONST_ALPHA; 396 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: 397 return PIPE_BLENDFACTOR_INV_CONST_ALPHA; 398 default: 399 assert(0); 400 return PIPE_BLENDFACTOR_ONE; 401 } 402} 403 404static unsigned 405BlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation) 406{ 407 switch (equation) { 408 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT: 409 return PIPE_BLEND_SUBTRACT; 410 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT: 411 return PIPE_BLEND_REVERSE_SUBTRACT; 412 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD: 413 return PIPE_BLEND_ADD; 414 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN: 415 return PIPE_BLEND_MIN; 416 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX: 417 return PIPE_BLEND_MAX; 418 default: 419 assert(0); 420 return PIPE_BLEND_ADD; 421 } 422} 423 424static void * 425BlenderToPipe(struct pipe_context *context, 426 VdpOutputSurfaceRenderBlendState const *blend_state) 427{ 428 struct pipe_blend_state blend; 429 430 memset(&blend, 0, sizeof blend); 431 blend.independent_blend_enable = 0; 432 433 if (blend_state) { 434 blend.rt[0].blend_enable = 1; 435 blend.rt[0].rgb_src_factor = BlendFactorToPipe(blend_state->blend_factor_source_color); 436 blend.rt[0].rgb_dst_factor = BlendFactorToPipe(blend_state->blend_factor_destination_color); 437 blend.rt[0].alpha_src_factor = BlendFactorToPipe(blend_state->blend_factor_source_alpha); 438 blend.rt[0].alpha_dst_factor = BlendFactorToPipe(blend_state->blend_factor_destination_alpha); 439 blend.rt[0].rgb_func = BlendEquationToPipe(blend_state->blend_equation_color); 440 blend.rt[0].alpha_func = BlendEquationToPipe(blend_state->blend_equation_alpha); 441 } else { 442 blend.rt[0].blend_enable = 0; 443 } 444 445 blend.logicop_enable = 0; 446 blend.logicop_func = PIPE_LOGICOP_CLEAR; 447 blend.rt[0].colormask = PIPE_MASK_RGBA; 448 blend.dither = 0; 449 450 return context->create_blend_state(context, &blend); 451} 452 453static struct vertex4f * 454ColorsToPipe(VdpColor const *colors, uint32_t flags, struct vertex4f result[4]) 455{ 456 unsigned i; 457 struct vertex4f *dst = result; 458 459 if (!colors) 460 return NULL; 461 462 for (i = 0; i < 4; ++i) { 463 dst->x = colors->red; 464 dst->y = colors->green; 465 dst->z = colors->blue; 466 dst->w = colors->alpha; 467 468 ++dst; 469 if (flags & VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX) 470 ++colors; 471 } 472 return result; 473} 474 475/** 476 * Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of 477 * another VdpOutputSurface; Output Surface object VdpOutputSurface. 478 */ 479VdpStatus 480vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface, 481 VdpRect const *destination_rect, 482 VdpOutputSurface source_surface, 483 VdpRect const *source_rect, 484 VdpColor const *colors, 485 VdpOutputSurfaceRenderBlendState const *blend_state, 486 uint32_t flags) 487{ 488 vlVdpOutputSurface *dst_vlsurface; 489 vlVdpOutputSurface *src_vlsurface; 490 491 struct pipe_context *context; 492 struct vl_compositor *compositor; 493 struct vl_compositor_state *cstate; 494 495 struct u_rect src_rect, dst_rect; 496 497 struct vertex4f vlcolors[4]; 498 void *blend; 499 500 dst_vlsurface = vlGetDataHTAB(destination_surface); 501 if (!dst_vlsurface) 502 return VDP_STATUS_INVALID_HANDLE; 503 504 src_vlsurface = vlGetDataHTAB(source_surface); 505 if (!src_vlsurface) 506 return VDP_STATUS_INVALID_HANDLE; 507 508 if (dst_vlsurface->device != src_vlsurface->device) 509 return VDP_STATUS_HANDLE_DEVICE_MISMATCH; 510 511 vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL); 512 513 context = dst_vlsurface->device->context; 514 compositor = &dst_vlsurface->device->compositor; 515 cstate = &dst_vlsurface->cstate; 516 517 blend = BlenderToPipe(context, blend_state); 518 519 vl_compositor_clear_layers(cstate); 520 vl_compositor_set_layer_blend(cstate, 0, blend, false); 521 vl_compositor_set_rgba_layer(cstate, compositor, 0, src_vlsurface->sampler_view, 522 RectToPipe(source_rect, &src_rect), NULL, 523 ColorsToPipe(colors, flags, vlcolors)); 524 vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 525 vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL); 526 527 context->delete_blend_state(context, blend); 528 529 return VDP_STATUS_OK; 530} 531 532/** 533 * Composite a sub-rectangle of a VdpBitmapSurface into a sub-rectangle of 534 * a VdpOutputSurface; Output Surface object VdpOutputSurface. 535 */ 536VdpStatus 537vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface, 538 VdpRect const *destination_rect, 539 VdpBitmapSurface source_surface, 540 VdpRect const *source_rect, 541 VdpColor const *colors, 542 VdpOutputSurfaceRenderBlendState const *blend_state, 543 uint32_t flags) 544{ 545 vlVdpOutputSurface *dst_vlsurface; 546 vlVdpBitmapSurface *src_vlsurface; 547 548 struct pipe_context *context; 549 struct vl_compositor *compositor; 550 struct vl_compositor_state *cstate; 551 552 struct u_rect src_rect, dst_rect; 553 554 struct vertex4f vlcolors[4]; 555 void *blend; 556 557 dst_vlsurface = vlGetDataHTAB(destination_surface); 558 if (!dst_vlsurface) 559 return VDP_STATUS_INVALID_HANDLE; 560 561 src_vlsurface = vlGetDataHTAB(source_surface); 562 if (!src_vlsurface) 563 return VDP_STATUS_INVALID_HANDLE; 564 565 if (dst_vlsurface->device != src_vlsurface->device) 566 return VDP_STATUS_HANDLE_DEVICE_MISMATCH; 567 568 vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL); 569 570 context = dst_vlsurface->device->context; 571 compositor = &dst_vlsurface->device->compositor; 572 cstate = &dst_vlsurface->cstate; 573 574 blend = BlenderToPipe(context, blend_state); 575 576 vl_compositor_clear_layers(cstate); 577 vl_compositor_set_layer_blend(cstate, 0, blend, false); 578 vl_compositor_set_rgba_layer(cstate, compositor, 0, src_vlsurface->sampler_view, 579 RectToPipe(source_rect, &src_rect), NULL, 580 ColorsToPipe(colors, flags, vlcolors)); 581 vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 582 vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL); 583 584 context->delete_blend_state(context, blend); 585 586 return VDP_STATUS_OK; 587} 588