output.c revision d14c879d82d62f4000045dc6f001186559b81faa
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 "vl/vl_csc.h" 37 38#include "vdpau_private.h" 39 40/** 41 * Create a VdpOutputSurface. 42 */ 43VdpStatus 44vlVdpOutputSurfaceCreate(VdpDevice device, 45 VdpRGBAFormat rgba_format, 46 uint32_t width, uint32_t height, 47 VdpOutputSurface *surface) 48{ 49 struct pipe_context *pipe; 50 struct pipe_resource res_tmpl, *res; 51 struct pipe_sampler_view sv_templ; 52 struct pipe_surface surf_templ; 53 54 vlVdpOutputSurface *vlsurface = NULL; 55 56 if (!(width && height)) 57 return VDP_STATUS_INVALID_SIZE; 58 59 vlVdpDevice *dev = vlGetDataHTAB(device); 60 if (!dev) 61 return VDP_STATUS_INVALID_HANDLE; 62 63 pipe = dev->context; 64 if (!pipe) 65 return VDP_STATUS_INVALID_HANDLE; 66 67 vlsurface = CALLOC(1, sizeof(vlVdpOutputSurface)); 68 if (!vlsurface) 69 return VDP_STATUS_RESOURCES; 70 71 vlsurface->device = dev; 72 73 memset(&res_tmpl, 0, sizeof(res_tmpl)); 74 75 res_tmpl.target = PIPE_TEXTURE_2D; 76 res_tmpl.format = FormatRGBAToPipe(rgba_format); 77 res_tmpl.width0 = width; 78 res_tmpl.height0 = height; 79 res_tmpl.depth0 = 1; 80 res_tmpl.array_size = 1; 81 res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 82 res_tmpl.usage = PIPE_USAGE_STATIC; 83 84 res = pipe->screen->resource_create(pipe->screen, &res_tmpl); 85 if (!res) { 86 FREE(dev); 87 return VDP_STATUS_ERROR; 88 } 89 90 vlVdpDefaultSamplerViewTemplate(&sv_templ, res); 91 vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ); 92 if (!vlsurface->sampler_view) { 93 pipe_resource_reference(&res, NULL); 94 FREE(dev); 95 return VDP_STATUS_ERROR; 96 } 97 98 memset(&surf_templ, 0, sizeof(surf_templ)); 99 surf_templ.format = res->format; 100 surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 101 vlsurface->surface = pipe->create_surface(pipe, res, &surf_templ); 102 if (!vlsurface->surface) { 103 pipe_resource_reference(&res, NULL); 104 FREE(dev); 105 return VDP_STATUS_ERROR; 106 } 107 108 *surface = vlAddDataHTAB(vlsurface); 109 if (*surface == 0) { 110 pipe_resource_reference(&res, NULL); 111 FREE(dev); 112 return VDP_STATUS_ERROR; 113 } 114 115 pipe_resource_reference(&res, NULL); 116 117 vl_compositor_init_state(&vlsurface->cstate, pipe); 118 vl_compositor_reset_dirty_area(&vlsurface->dirty_area); 119 120 return VDP_STATUS_OK; 121} 122 123/** 124 * Destroy a VdpOutputSurface. 125 */ 126VdpStatus 127vlVdpOutputSurfaceDestroy(VdpOutputSurface surface) 128{ 129 vlVdpOutputSurface *vlsurface; 130 131 vlsurface = vlGetDataHTAB(surface); 132 if (!vlsurface) 133 return VDP_STATUS_INVALID_HANDLE; 134 135 vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); 136 137 pipe_surface_reference(&vlsurface->surface, NULL); 138 pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); 139 vl_compositor_cleanup_state(&vlsurface->cstate); 140 141 vlRemoveDataHTAB(surface); 142 FREE(vlsurface); 143 144 return VDP_STATUS_OK; 145} 146 147/** 148 * Retrieve the parameters used to create a VdpOutputSurface. 149 */ 150VdpStatus 151vlVdpOutputSurfaceGetParameters(VdpOutputSurface surface, 152 VdpRGBAFormat *rgba_format, 153 uint32_t *width, uint32_t *height) 154{ 155 vlVdpOutputSurface *vlsurface; 156 157 vlsurface = vlGetDataHTAB(surface); 158 if (!vlsurface) 159 return VDP_STATUS_INVALID_HANDLE; 160 161 *rgba_format = PipeToFormatRGBA(vlsurface->sampler_view->texture->format); 162 *width = vlsurface->sampler_view->texture->width0; 163 *height = vlsurface->sampler_view->texture->height0; 164 165 return VDP_STATUS_OK; 166} 167 168/** 169 * Copy image data from a VdpOutputSurface to application memory in the 170 * surface's native format. 171 */ 172VdpStatus 173vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface, 174 VdpRect const *source_rect, 175 void *const *destination_data, 176 uint32_t const *destination_pitches) 177{ 178 vlVdpOutputSurface *vlsurface; 179 struct pipe_context *pipe; 180 struct pipe_resource *res; 181 struct pipe_box box; 182 struct pipe_transfer *transfer; 183 uint8_t *map; 184 185 vlsurface = vlGetDataHTAB(surface); 186 if (!vlsurface) 187 return VDP_STATUS_INVALID_HANDLE; 188 189 pipe = vlsurface->device->context; 190 if (!pipe) 191 return VDP_STATUS_INVALID_HANDLE; 192 193 vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); 194 195 res = vlsurface->sampler_view->texture; 196 box = RectToPipeBox(source_rect, res); 197 transfer = pipe->get_transfer(pipe, res, 0, PIPE_TRANSFER_READ, &box); 198 if (transfer == NULL) 199 return VDP_STATUS_RESOURCES; 200 201 map = pipe_transfer_map(pipe, transfer); 202 if (map == NULL) { 203 pipe_transfer_destroy(pipe, transfer); 204 return VDP_STATUS_RESOURCES; 205 } 206 207 util_copy_rect(*destination_data, res->format, *destination_pitches, 0, 0, 208 box.width, box.height, map, transfer->stride, 0, 0); 209 210 pipe_transfer_unmap(pipe, transfer); 211 pipe_transfer_destroy(pipe, transfer); 212 213 return VDP_STATUS_OK; 214} 215 216/** 217 * Copy image data from application memory in the surface's native format to 218 * a VdpOutputSurface. 219 */ 220VdpStatus 221vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface, 222 void const *const *source_data, 223 uint32_t const *source_pitches, 224 VdpRect const *destination_rect) 225{ 226 vlVdpOutputSurface *vlsurface; 227 struct pipe_box dst_box; 228 struct pipe_context *pipe; 229 230 vlsurface = vlGetDataHTAB(surface); 231 if (!vlsurface) 232 return VDP_STATUS_INVALID_HANDLE; 233 234 pipe = vlsurface->device->context; 235 if (!pipe) 236 return VDP_STATUS_INVALID_HANDLE; 237 238 vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); 239 240 dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture); 241 pipe->transfer_inline_write(pipe, vlsurface->sampler_view->texture, 0, 242 PIPE_TRANSFER_WRITE, &dst_box, *source_data, 243 *source_pitches, 0); 244 245 return VDP_STATUS_OK; 246} 247 248/** 249 * Copy image data from application memory in a specific indexed format to 250 * a VdpOutputSurface. 251 */ 252VdpStatus 253vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface, 254 VdpIndexedFormat source_indexed_format, 255 void const *const *source_data, 256 uint32_t const *source_pitch, 257 VdpRect const *destination_rect, 258 VdpColorTableFormat color_table_format, 259 void const *color_table) 260{ 261 vlVdpOutputSurface *vlsurface; 262 struct pipe_context *context; 263 struct vl_compositor *compositor; 264 struct vl_compositor_state *cstate; 265 266 enum pipe_format index_format; 267 enum pipe_format colortbl_format; 268 269 struct pipe_resource *res, res_tmpl; 270 struct pipe_sampler_view sv_tmpl; 271 struct pipe_sampler_view *sv_idx = NULL, *sv_tbl = NULL; 272 273 struct pipe_box box; 274 struct u_rect dst_rect; 275 276 vlsurface = vlGetDataHTAB(surface); 277 if (!vlsurface) 278 return VDP_STATUS_INVALID_HANDLE; 279 280 vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); 281 282 context = vlsurface->device->context; 283 compositor = &vlsurface->device->compositor; 284 cstate = &vlsurface->cstate; 285 286 index_format = FormatIndexedToPipe(source_indexed_format); 287 if (index_format == PIPE_FORMAT_NONE) 288 return VDP_STATUS_INVALID_INDEXED_FORMAT; 289 290 if (!source_data || !source_pitch) 291 return VDP_STATUS_INVALID_POINTER; 292 293 colortbl_format = FormatColorTableToPipe(color_table_format); 294 if (colortbl_format == PIPE_FORMAT_NONE) 295 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT; 296 297 if (!color_table) 298 return VDP_STATUS_INVALID_POINTER; 299 300 memset(&res_tmpl, 0, sizeof(res_tmpl)); 301 res_tmpl.target = PIPE_TEXTURE_2D; 302 res_tmpl.format = index_format; 303 304 if (destination_rect) { 305 res_tmpl.width0 = abs(destination_rect->x0-destination_rect->x1); 306 res_tmpl.height0 = abs(destination_rect->y0-destination_rect->y1); 307 } else { 308 res_tmpl.width0 = vlsurface->surface->texture->width0; 309 res_tmpl.height0 = vlsurface->surface->texture->height0; 310 } 311 res_tmpl.depth0 = 1; 312 res_tmpl.array_size = 1; 313 res_tmpl.usage = PIPE_USAGE_STAGING; 314 res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; 315 316 res = context->screen->resource_create(context->screen, &res_tmpl); 317 if (!res) 318 goto error_resource; 319 320 box.x = box.y = box.z = 0; 321 box.width = res->width0; 322 box.height = res->height0; 323 box.depth = res->depth0; 324 325 context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box, 326 source_data[0], source_pitch[0], 327 source_pitch[0] * res->height0); 328 329 memset(&sv_tmpl, 0, sizeof(sv_tmpl)); 330 u_sampler_view_default_template(&sv_tmpl, res, res->format); 331 332 sv_idx = context->create_sampler_view(context, res, &sv_tmpl); 333 pipe_resource_reference(&res, NULL); 334 335 if (!sv_idx) 336 goto error_resource; 337 338 memset(&res_tmpl, 0, sizeof(res_tmpl)); 339 res_tmpl.target = PIPE_TEXTURE_1D; 340 res_tmpl.format = colortbl_format; 341 res_tmpl.width0 = 1 << util_format_get_component_bits( 342 index_format, UTIL_FORMAT_COLORSPACE_RGB, 0); 343 res_tmpl.height0 = 1; 344 res_tmpl.depth0 = 1; 345 res_tmpl.array_size = 1; 346 res_tmpl.usage = PIPE_USAGE_STAGING; 347 res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; 348 349 res = context->screen->resource_create(context->screen, &res_tmpl); 350 if (!res) 351 goto error_resource; 352 353 box.x = box.y = box.z = 0; 354 box.width = res->width0; 355 box.height = res->height0; 356 box.depth = res->depth0; 357 358 context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box, color_table, 359 util_format_get_stride(colortbl_format, res->width0), 0); 360 361 memset(&sv_tmpl, 0, sizeof(sv_tmpl)); 362 u_sampler_view_default_template(&sv_tmpl, res, res->format); 363 364 sv_tbl = context->create_sampler_view(context, res, &sv_tmpl); 365 pipe_resource_reference(&res, NULL); 366 367 if (!sv_tbl) 368 goto error_resource; 369 370 vl_compositor_clear_layers(cstate); 371 vl_compositor_set_palette_layer(cstate, compositor, 0, sv_idx, sv_tbl, NULL, NULL, false); 372 vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 373 vl_compositor_render(cstate, compositor, vlsurface->surface, NULL); 374 375 pipe_sampler_view_reference(&sv_idx, NULL); 376 pipe_sampler_view_reference(&sv_tbl, NULL); 377 378 return VDP_STATUS_OK; 379 380error_resource: 381 pipe_sampler_view_reference(&sv_idx, NULL); 382 pipe_sampler_view_reference(&sv_tbl, NULL); 383 return VDP_STATUS_RESOURCES; 384} 385 386/** 387 * Copy image data from application memory in a specific YCbCr format to 388 * a VdpOutputSurface. 389 */ 390VdpStatus 391vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface, 392 VdpYCbCrFormat source_ycbcr_format, 393 void const *const *source_data, 394 uint32_t const *source_pitches, 395 VdpRect const *destination_rect, 396 VdpCSCMatrix const *csc_matrix) 397{ 398 vlVdpOutputSurface *vlsurface; 399 struct vl_compositor *compositor; 400 struct vl_compositor_state *cstate; 401 402 struct pipe_context *pipe; 403 enum pipe_format format; 404 struct pipe_video_buffer vtmpl, *vbuffer; 405 struct u_rect dst_rect; 406 struct pipe_sampler_view **sampler_views; 407 408 unsigned i; 409 410 vlsurface = vlGetDataHTAB(surface); 411 if (!vlsurface) 412 return VDP_STATUS_INVALID_HANDLE; 413 414 vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); 415 416 pipe = vlsurface->device->context; 417 compositor = &vlsurface->device->compositor; 418 cstate = &vlsurface->cstate; 419 420 format = FormatYCBCRToPipe(source_ycbcr_format); 421 if (format == PIPE_FORMAT_NONE) 422 return VDP_STATUS_INVALID_Y_CB_CR_FORMAT; 423 424 if (!source_data || !source_pitches) 425 return VDP_STATUS_INVALID_POINTER; 426 427 memset(&vtmpl, 0, sizeof(vtmpl)); 428 vtmpl.buffer_format = format; 429 vtmpl.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; 430 431 if (destination_rect) { 432 vtmpl.width = abs(destination_rect->x0-destination_rect->x1); 433 vtmpl.height = abs(destination_rect->y0-destination_rect->y1); 434 } else { 435 vtmpl.width = vlsurface->surface->texture->width0; 436 vtmpl.height = vlsurface->surface->texture->height0; 437 } 438 439 vbuffer = pipe->create_video_buffer(pipe, &vtmpl); 440 if (!vbuffer) 441 return VDP_STATUS_RESOURCES; 442 443 sampler_views = vbuffer->get_sampler_view_planes(vbuffer); 444 if (!sampler_views) { 445 vbuffer->destroy(vbuffer); 446 return VDP_STATUS_RESOURCES; 447 } 448 449 for (i = 0; i < 3; ++i) { 450 struct pipe_sampler_view *sv = sampler_views[i]; 451 if (!sv) continue; 452 453 struct pipe_box dst_box = { 454 0, 0, 0, 455 sv->texture->width0, sv->texture->height0, 1 456 }; 457 458 pipe->transfer_inline_write(pipe, sv->texture, 0, PIPE_TRANSFER_WRITE, &dst_box, 459 source_data[i], source_pitches[i], 0); 460 } 461 462 if (!csc_matrix) { 463 vl_csc_matrix csc; 464 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, 1, &csc); 465 vl_compositor_set_csc_matrix(cstate, (const vl_csc_matrix*)&csc); 466 } else { 467 vl_compositor_set_csc_matrix(cstate, csc_matrix); 468 } 469 470 vl_compositor_clear_layers(cstate); 471 vl_compositor_set_buffer_layer(cstate, compositor, 0, vbuffer, NULL, NULL, VL_COMPOSITOR_WEAVE); 472 vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 473 vl_compositor_render(cstate, compositor, vlsurface->surface, NULL); 474 475 vbuffer->destroy(vbuffer); 476 477 return VDP_STATUS_OK; 478} 479 480static unsigned 481BlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor) 482{ 483 switch (factor) { 484 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO: 485 return PIPE_BLENDFACTOR_ZERO; 486 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE: 487 return PIPE_BLENDFACTOR_ONE; 488 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR: 489 return PIPE_BLENDFACTOR_SRC_COLOR; 490 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: 491 return PIPE_BLENDFACTOR_INV_SRC_COLOR; 492 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA: 493 return PIPE_BLENDFACTOR_SRC_ALPHA; 494 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: 495 return PIPE_BLENDFACTOR_INV_SRC_ALPHA; 496 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA: 497 return PIPE_BLENDFACTOR_DST_ALPHA; 498 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: 499 return PIPE_BLENDFACTOR_INV_DST_ALPHA; 500 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR: 501 return PIPE_BLENDFACTOR_DST_COLOR; 502 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR: 503 return PIPE_BLENDFACTOR_INV_DST_COLOR; 504 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE: 505 return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE; 506 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR: 507 return PIPE_BLENDFACTOR_CONST_COLOR; 508 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: 509 return PIPE_BLENDFACTOR_INV_CONST_COLOR; 510 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA: 511 return PIPE_BLENDFACTOR_CONST_ALPHA; 512 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: 513 return PIPE_BLENDFACTOR_INV_CONST_ALPHA; 514 default: 515 assert(0); 516 return PIPE_BLENDFACTOR_ONE; 517 } 518} 519 520static unsigned 521BlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation) 522{ 523 switch (equation) { 524 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT: 525 return PIPE_BLEND_SUBTRACT; 526 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT: 527 return PIPE_BLEND_REVERSE_SUBTRACT; 528 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD: 529 return PIPE_BLEND_ADD; 530 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN: 531 return PIPE_BLEND_MIN; 532 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX: 533 return PIPE_BLEND_MAX; 534 default: 535 assert(0); 536 return PIPE_BLEND_ADD; 537 } 538} 539 540static void * 541BlenderToPipe(struct pipe_context *context, 542 VdpOutputSurfaceRenderBlendState const *blend_state) 543{ 544 struct pipe_blend_state blend; 545 546 memset(&blend, 0, sizeof blend); 547 blend.independent_blend_enable = 0; 548 549 if (blend_state) { 550 blend.rt[0].blend_enable = 1; 551 blend.rt[0].rgb_src_factor = BlendFactorToPipe(blend_state->blend_factor_source_color); 552 blend.rt[0].rgb_dst_factor = BlendFactorToPipe(blend_state->blend_factor_destination_color); 553 blend.rt[0].alpha_src_factor = BlendFactorToPipe(blend_state->blend_factor_source_alpha); 554 blend.rt[0].alpha_dst_factor = BlendFactorToPipe(blend_state->blend_factor_destination_alpha); 555 blend.rt[0].rgb_func = BlendEquationToPipe(blend_state->blend_equation_color); 556 blend.rt[0].alpha_func = BlendEquationToPipe(blend_state->blend_equation_alpha); 557 } else { 558 blend.rt[0].blend_enable = 0; 559 } 560 561 blend.logicop_enable = 0; 562 blend.logicop_func = PIPE_LOGICOP_CLEAR; 563 blend.rt[0].colormask = PIPE_MASK_RGBA; 564 blend.dither = 0; 565 566 return context->create_blend_state(context, &blend); 567} 568 569static struct vertex4f * 570ColorsToPipe(VdpColor const *colors, uint32_t flags, struct vertex4f result[4]) 571{ 572 unsigned i; 573 struct vertex4f *dst = result; 574 575 if (!colors) 576 return NULL; 577 578 for (i = 0; i < 4; ++i) { 579 dst->x = colors->red; 580 dst->y = colors->green; 581 dst->z = colors->blue; 582 dst->w = colors->alpha; 583 584 ++dst; 585 if (flags & VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX) 586 ++colors; 587 } 588 return result; 589} 590 591/** 592 * Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of 593 * another VdpOutputSurface; Output Surface object VdpOutputSurface. 594 */ 595VdpStatus 596vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface, 597 VdpRect const *destination_rect, 598 VdpOutputSurface source_surface, 599 VdpRect const *source_rect, 600 VdpColor const *colors, 601 VdpOutputSurfaceRenderBlendState const *blend_state, 602 uint32_t flags) 603{ 604 vlVdpOutputSurface *dst_vlsurface; 605 vlVdpOutputSurface *src_vlsurface; 606 607 struct pipe_context *context; 608 struct vl_compositor *compositor; 609 struct vl_compositor_state *cstate; 610 611 struct u_rect src_rect, dst_rect; 612 613 struct vertex4f vlcolors[4]; 614 void *blend; 615 616 dst_vlsurface = vlGetDataHTAB(destination_surface); 617 if (!dst_vlsurface) 618 return VDP_STATUS_INVALID_HANDLE; 619 620 src_vlsurface = vlGetDataHTAB(source_surface); 621 if (!src_vlsurface) 622 return VDP_STATUS_INVALID_HANDLE; 623 624 if (dst_vlsurface->device != src_vlsurface->device) 625 return VDP_STATUS_HANDLE_DEVICE_MISMATCH; 626 627 vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL); 628 629 context = dst_vlsurface->device->context; 630 compositor = &dst_vlsurface->device->compositor; 631 cstate = &dst_vlsurface->cstate; 632 633 blend = BlenderToPipe(context, blend_state); 634 635 vl_compositor_clear_layers(cstate); 636 vl_compositor_set_layer_blend(cstate, 0, blend, false); 637 vl_compositor_set_rgba_layer(cstate, compositor, 0, src_vlsurface->sampler_view, 638 RectToPipe(source_rect, &src_rect), NULL, 639 ColorsToPipe(colors, flags, vlcolors)); 640 vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 641 vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL); 642 643 context->delete_blend_state(context, blend); 644 645 return VDP_STATUS_OK; 646} 647 648/** 649 * Composite a sub-rectangle of a VdpBitmapSurface into a sub-rectangle of 650 * a VdpOutputSurface; Output Surface object VdpOutputSurface. 651 */ 652VdpStatus 653vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface, 654 VdpRect const *destination_rect, 655 VdpBitmapSurface source_surface, 656 VdpRect const *source_rect, 657 VdpColor const *colors, 658 VdpOutputSurfaceRenderBlendState const *blend_state, 659 uint32_t flags) 660{ 661 vlVdpOutputSurface *dst_vlsurface; 662 vlVdpBitmapSurface *src_vlsurface; 663 664 struct pipe_context *context; 665 struct vl_compositor *compositor; 666 struct vl_compositor_state *cstate; 667 668 struct u_rect src_rect, dst_rect; 669 670 struct vertex4f vlcolors[4]; 671 void *blend; 672 673 dst_vlsurface = vlGetDataHTAB(destination_surface); 674 if (!dst_vlsurface) 675 return VDP_STATUS_INVALID_HANDLE; 676 677 src_vlsurface = vlGetDataHTAB(source_surface); 678 if (!src_vlsurface) 679 return VDP_STATUS_INVALID_HANDLE; 680 681 if (dst_vlsurface->device != src_vlsurface->device) 682 return VDP_STATUS_HANDLE_DEVICE_MISMATCH; 683 684 vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL); 685 686 context = dst_vlsurface->device->context; 687 compositor = &dst_vlsurface->device->compositor; 688 cstate = &dst_vlsurface->cstate; 689 690 blend = BlenderToPipe(context, blend_state); 691 692 vl_compositor_clear_layers(cstate); 693 vl_compositor_set_layer_blend(cstate, 0, blend, false); 694 vl_compositor_set_rgba_layer(cstate, compositor, 0, src_vlsurface->sampler_view, 695 RectToPipe(source_rect, &src_rect), NULL, 696 ColorsToPipe(colors, flags, vlcolors)); 697 vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 698 vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL); 699 700 context->delete_blend_state(context, blend); 701 702 return VDP_STATUS_OK; 703} 704