1 /**************************************************************************
3 * Copyright 2010 Thomas Balling Sørensen.
4 * Copyright 2011 Christian König.
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:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
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.
27 **************************************************************************/
29 #include <vdpau/vdpau.h>
31 #include "util/u_debug.h"
32 #include "util/u_memory.h"
33 #include "util/u_sampler.h"
34 #include "util/u_format.h"
36 #include "vdpau_private.h"
39 * Create a VdpOutputSurface.
42 vlVdpOutputSurfaceCreate(VdpDevice device
,
43 VdpRGBAFormat rgba_format
,
44 uint32_t width
, uint32_t height
,
45 VdpOutputSurface
*surface
)
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
;
52 vlVdpOutputSurface
*vlsurface
= NULL
;
54 if (!(width
&& height
))
55 return VDP_STATUS_INVALID_SIZE
;
57 vlVdpDevice
*dev
= vlGetDataHTAB(device
);
59 return VDP_STATUS_INVALID_HANDLE
;
63 return VDP_STATUS_INVALID_HANDLE
;
65 vlsurface
= CALLOC(1, sizeof(vlVdpOutputSurface
));
67 return VDP_STATUS_RESOURCES
;
69 vlsurface
->device
= dev
;
71 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
73 res_tmpl
.target
= PIPE_TEXTURE_2D
;
74 res_tmpl
.format
= FormatRGBAToPipe(rgba_format
);
75 res_tmpl
.width0
= width
;
76 res_tmpl
.height0
= height
;
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
;
82 res
= pipe
->screen
->resource_create(pipe
->screen
, &res_tmpl
);
85 return VDP_STATUS_ERROR
;
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
);
93 return VDP_STATUS_ERROR
;
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
);
103 return VDP_STATUS_ERROR
;
106 *surface
= vlAddDataHTAB(vlsurface
);
108 pipe_resource_reference(&res
, NULL
);
110 return VDP_STATUS_ERROR
;
113 pipe_resource_reference(&res
, NULL
);
115 vl_compositor_init_state(&vlsurface
->cstate
, pipe
);
116 vl_compositor_reset_dirty_area(&vlsurface
->dirty_area
);
118 return VDP_STATUS_OK
;
122 * Destroy a VdpOutputSurface.
125 vlVdpOutputSurfaceDestroy(VdpOutputSurface surface
)
127 vlVdpOutputSurface
*vlsurface
;
129 vlsurface
= vlGetDataHTAB(surface
);
131 return VDP_STATUS_INVALID_HANDLE
;
133 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
135 pipe_surface_reference(&vlsurface
->surface
, NULL
);
136 pipe_sampler_view_reference(&vlsurface
->sampler_view
, NULL
);
137 vl_compositor_cleanup_state(&vlsurface
->cstate
);
139 vlRemoveDataHTAB(surface
);
142 return VDP_STATUS_OK
;
146 * Retrieve the parameters used to create a VdpOutputSurface.
149 vlVdpOutputSurfaceGetParameters(VdpOutputSurface surface
,
150 VdpRGBAFormat
*rgba_format
,
151 uint32_t *width
, uint32_t *height
)
153 vlVdpOutputSurface
*vlsurface
;
155 vlsurface
= vlGetDataHTAB(surface
);
157 return VDP_STATUS_INVALID_HANDLE
;
159 *rgba_format
= PipeToFormatRGBA(vlsurface
->sampler_view
->texture
->format
);
160 *width
= vlsurface
->sampler_view
->texture
->width0
;
161 *height
= vlsurface
->sampler_view
->texture
->height0
;
163 return VDP_STATUS_OK
;
167 * Copy image data from a VdpOutputSurface to application memory in the
168 * surface's native format.
171 vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface
,
172 VdpRect
const *source_rect
,
173 void *const *destination_data
,
174 uint32_t const *destination_pitches
)
176 vlVdpOutputSurface
*vlsurface
;
177 struct pipe_context
*pipe
;
178 struct pipe_resource
*res
;
180 struct pipe_transfer
*transfer
;
183 vlsurface
= vlGetDataHTAB(surface
);
185 return VDP_STATUS_INVALID_HANDLE
;
187 pipe
= vlsurface
->device
->context
;
189 return VDP_STATUS_INVALID_HANDLE
;
191 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
193 res
= vlsurface
->sampler_view
->texture
;
194 box
= RectToPipeBox(source_rect
, res
);
195 transfer
= pipe
->get_transfer(pipe
, res
, 0, PIPE_TRANSFER_READ
, &box
);
196 if (transfer
== NULL
)
197 return VDP_STATUS_RESOURCES
;
199 map
= pipe_transfer_map(pipe
, transfer
);
201 pipe_transfer_destroy(pipe
, transfer
);
202 return VDP_STATUS_RESOURCES
;
205 util_copy_rect(*destination_data
, res
->format
, *destination_pitches
, 0, 0,
206 box
.width
, box
.height
, map
, transfer
->stride
, 0, 0);
208 pipe_transfer_unmap(pipe
, transfer
);
209 pipe_transfer_destroy(pipe
, transfer
);
211 return VDP_STATUS_OK
;
215 * Copy image data from application memory in the surface's native format to
216 * a VdpOutputSurface.
219 vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface
,
220 void const *const *source_data
,
221 uint32_t const *source_pitches
,
222 VdpRect
const *destination_rect
)
224 vlVdpOutputSurface
*vlsurface
;
225 struct pipe_box dst_box
;
226 struct pipe_context
*pipe
;
228 vlsurface
= vlGetDataHTAB(surface
);
230 return VDP_STATUS_INVALID_HANDLE
;
232 pipe
= vlsurface
->device
->context
;
234 return VDP_STATUS_INVALID_HANDLE
;
236 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
238 dst_box
= RectToPipeBox(destination_rect
, vlsurface
->sampler_view
->texture
);
239 pipe
->transfer_inline_write(pipe
, vlsurface
->sampler_view
->texture
, 0,
240 PIPE_TRANSFER_WRITE
, &dst_box
, *source_data
,
243 return VDP_STATUS_OK
;
247 * Copy image data from application memory in a specific indexed format to
248 * a VdpOutputSurface.
251 vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface
,
252 VdpIndexedFormat source_indexed_format
,
253 void const *const *source_data
,
254 uint32_t const *source_pitch
,
255 VdpRect
const *destination_rect
,
256 VdpColorTableFormat color_table_format
,
257 void const *color_table
)
259 vlVdpOutputSurface
*vlsurface
;
260 struct pipe_context
*context
;
261 struct vl_compositor
*compositor
;
262 struct vl_compositor_state
*cstate
;
264 enum pipe_format index_format
;
265 enum pipe_format colortbl_format
;
267 struct pipe_resource
*res
, res_tmpl
;
268 struct pipe_sampler_view sv_tmpl
;
269 struct pipe_sampler_view
*sv_idx
= NULL
, *sv_tbl
= NULL
;
272 struct u_rect dst_rect
;
274 vlsurface
= vlGetDataHTAB(surface
);
276 return VDP_STATUS_INVALID_HANDLE
;
278 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
280 context
= vlsurface
->device
->context
;
281 compositor
= &vlsurface
->device
->compositor
;
282 cstate
= &vlsurface
->cstate
;
284 index_format
= FormatIndexedToPipe(source_indexed_format
);
285 if (index_format
== PIPE_FORMAT_NONE
)
286 return VDP_STATUS_INVALID_INDEXED_FORMAT
;
288 if (!source_data
|| !source_pitch
)
289 return VDP_STATUS_INVALID_POINTER
;
291 colortbl_format
= FormatColorTableToPipe(color_table_format
);
292 if (colortbl_format
== PIPE_FORMAT_NONE
)
293 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT
;
296 return VDP_STATUS_INVALID_POINTER
;
298 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
299 res_tmpl
.target
= PIPE_TEXTURE_2D
;
300 res_tmpl
.format
= index_format
;
302 if (destination_rect
) {
303 res_tmpl
.width0
= abs(destination_rect
->x0
-destination_rect
->x1
);
304 res_tmpl
.height0
= abs(destination_rect
->y0
-destination_rect
->y1
);
306 res_tmpl
.width0
= vlsurface
->surface
->texture
->width0
;
307 res_tmpl
.height0
= vlsurface
->surface
->texture
->height0
;
310 res_tmpl
.array_size
= 1;
311 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
312 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
314 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
318 box
.x
= box
.y
= box
.z
= 0;
319 box
.width
= res
->width0
;
320 box
.height
= res
->height0
;
321 box
.depth
= res
->depth0
;
323 context
->transfer_inline_write(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
,
324 source_data
[0], source_pitch
[0],
325 source_pitch
[0] * res
->height0
);
327 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
328 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
330 sv_idx
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
331 pipe_resource_reference(&res
, NULL
);
336 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
337 res_tmpl
.target
= PIPE_TEXTURE_1D
;
338 res_tmpl
.format
= colortbl_format
;
339 res_tmpl
.width0
= 1 << util_format_get_component_bits(
340 index_format
, UTIL_FORMAT_COLORSPACE_RGB
, 0);
341 res_tmpl
.height0
= 1;
343 res_tmpl
.array_size
= 1;
344 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
345 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
347 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
351 box
.x
= box
.y
= box
.z
= 0;
352 box
.width
= res
->width0
;
353 box
.height
= res
->height0
;
354 box
.depth
= res
->depth0
;
356 context
->transfer_inline_write(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
, color_table
,
357 util_format_get_stride(colortbl_format
, res
->width0
), 0);
359 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
360 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
362 sv_tbl
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
363 pipe_resource_reference(&res
, NULL
);
368 vl_compositor_clear_layers(cstate
);
369 vl_compositor_set_palette_layer(cstate
, compositor
, 0, sv_idx
, sv_tbl
, NULL
, NULL
, false);
370 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
371 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, NULL
);
373 pipe_sampler_view_reference(&sv_idx
, NULL
);
374 pipe_sampler_view_reference(&sv_tbl
, NULL
);
376 return VDP_STATUS_OK
;
379 pipe_sampler_view_reference(&sv_idx
, NULL
);
380 pipe_sampler_view_reference(&sv_tbl
, NULL
);
381 return VDP_STATUS_RESOURCES
;
385 * Copy image data from application memory in a specific YCbCr format to
386 * a VdpOutputSurface.
389 vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface
,
390 VdpYCbCrFormat source_ycbcr_format
,
391 void const *const *source_data
,
392 uint32_t const *source_pitches
,
393 VdpRect
const *destination_rect
,
394 VdpCSCMatrix
const *csc_matrix
)
396 return VDP_STATUS_NO_IMPLEMENTATION
;
400 BlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor
)
403 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO
:
404 return PIPE_BLENDFACTOR_ZERO
;
405 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE
:
406 return PIPE_BLENDFACTOR_ONE
;
407 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR
:
408 return PIPE_BLENDFACTOR_SRC_COLOR
;
409 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR
:
410 return PIPE_BLENDFACTOR_INV_SRC_COLOR
;
411 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA
:
412 return PIPE_BLENDFACTOR_SRC_ALPHA
;
413 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
:
414 return PIPE_BLENDFACTOR_INV_SRC_ALPHA
;
415 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA
:
416 return PIPE_BLENDFACTOR_DST_ALPHA
;
417 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA
:
418 return PIPE_BLENDFACTOR_INV_DST_ALPHA
;
419 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR
:
420 return PIPE_BLENDFACTOR_DST_COLOR
;
421 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR
:
422 return PIPE_BLENDFACTOR_INV_DST_COLOR
;
423 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE
:
424 return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
;
425 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR
:
426 return PIPE_BLENDFACTOR_CONST_COLOR
;
427 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
:
428 return PIPE_BLENDFACTOR_INV_CONST_COLOR
;
429 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA
:
430 return PIPE_BLENDFACTOR_CONST_ALPHA
;
431 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
:
432 return PIPE_BLENDFACTOR_INV_CONST_ALPHA
;
435 return PIPE_BLENDFACTOR_ONE
;
440 BlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation
)
443 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT
:
444 return PIPE_BLEND_SUBTRACT
;
445 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT
:
446 return PIPE_BLEND_REVERSE_SUBTRACT
;
447 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD
:
448 return PIPE_BLEND_ADD
;
449 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN
:
450 return PIPE_BLEND_MIN
;
451 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX
:
452 return PIPE_BLEND_MAX
;
455 return PIPE_BLEND_ADD
;
460 BlenderToPipe(struct pipe_context
*context
,
461 VdpOutputSurfaceRenderBlendState
const *blend_state
)
463 struct pipe_blend_state blend
;
465 memset(&blend
, 0, sizeof blend
);
466 blend
.independent_blend_enable
= 0;
469 blend
.rt
[0].blend_enable
= 1;
470 blend
.rt
[0].rgb_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_color
);
471 blend
.rt
[0].rgb_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_color
);
472 blend
.rt
[0].alpha_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_alpha
);
473 blend
.rt
[0].alpha_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_alpha
);
474 blend
.rt
[0].rgb_func
= BlendEquationToPipe(blend_state
->blend_equation_color
);
475 blend
.rt
[0].alpha_func
= BlendEquationToPipe(blend_state
->blend_equation_alpha
);
477 blend
.rt
[0].blend_enable
= 0;
480 blend
.logicop_enable
= 0;
481 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
482 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
485 return context
->create_blend_state(context
, &blend
);
488 static struct vertex4f
*
489 ColorsToPipe(VdpColor
const *colors
, uint32_t flags
, struct vertex4f result
[4])
492 struct vertex4f
*dst
= result
;
497 for (i
= 0; i
< 4; ++i
) {
498 dst
->x
= colors
->red
;
499 dst
->y
= colors
->green
;
500 dst
->z
= colors
->blue
;
501 dst
->w
= colors
->alpha
;
504 if (flags
& VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX
)
511 * Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of
512 * another VdpOutputSurface; Output Surface object VdpOutputSurface.
515 vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface
,
516 VdpRect
const *destination_rect
,
517 VdpOutputSurface source_surface
,
518 VdpRect
const *source_rect
,
519 VdpColor
const *colors
,
520 VdpOutputSurfaceRenderBlendState
const *blend_state
,
523 vlVdpOutputSurface
*dst_vlsurface
;
524 vlVdpOutputSurface
*src_vlsurface
;
526 struct pipe_context
*context
;
527 struct vl_compositor
*compositor
;
528 struct vl_compositor_state
*cstate
;
530 struct u_rect src_rect
, dst_rect
;
532 struct vertex4f vlcolors
[4];
535 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
537 return VDP_STATUS_INVALID_HANDLE
;
539 src_vlsurface
= vlGetDataHTAB(source_surface
);
541 return VDP_STATUS_INVALID_HANDLE
;
543 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
544 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
546 vlVdpResolveDelayedRendering(dst_vlsurface
->device
, NULL
, NULL
);
548 context
= dst_vlsurface
->device
->context
;
549 compositor
= &dst_vlsurface
->device
->compositor
;
550 cstate
= &dst_vlsurface
->cstate
;
552 blend
= BlenderToPipe(context
, blend_state
);
554 vl_compositor_clear_layers(cstate
);
555 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
556 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_vlsurface
->sampler_view
,
557 RectToPipe(source_rect
, &src_rect
), NULL
,
558 ColorsToPipe(colors
, flags
, vlcolors
));
559 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
560 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, NULL
);
562 context
->delete_blend_state(context
, blend
);
564 return VDP_STATUS_OK
;
568 * Composite a sub-rectangle of a VdpBitmapSurface into a sub-rectangle of
569 * a VdpOutputSurface; Output Surface object VdpOutputSurface.
572 vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface
,
573 VdpRect
const *destination_rect
,
574 VdpBitmapSurface source_surface
,
575 VdpRect
const *source_rect
,
576 VdpColor
const *colors
,
577 VdpOutputSurfaceRenderBlendState
const *blend_state
,
580 vlVdpOutputSurface
*dst_vlsurface
;
581 vlVdpBitmapSurface
*src_vlsurface
;
583 struct pipe_context
*context
;
584 struct vl_compositor
*compositor
;
585 struct vl_compositor_state
*cstate
;
587 struct u_rect src_rect
, dst_rect
;
589 struct vertex4f vlcolors
[4];
592 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
594 return VDP_STATUS_INVALID_HANDLE
;
596 src_vlsurface
= vlGetDataHTAB(source_surface
);
598 return VDP_STATUS_INVALID_HANDLE
;
600 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
601 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
603 vlVdpResolveDelayedRendering(dst_vlsurface
->device
, NULL
, NULL
);
605 context
= dst_vlsurface
->device
->context
;
606 compositor
= &dst_vlsurface
->device
->compositor
;
607 cstate
= &dst_vlsurface
->cstate
;
609 blend
= BlenderToPipe(context
, blend_state
);
611 vl_compositor_clear_layers(cstate
);
612 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
613 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_vlsurface
->sampler_view
,
614 RectToPipe(source_rect
, &src_rect
), NULL
,
615 ColorsToPipe(colors
, flags
, vlcolors
));
616 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
617 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, NULL
);
619 context
->delete_blend_state(context
, blend
);
621 return VDP_STATUS_OK
;