#include "util/u_memory.h"
#include "util/u_debug.h"
+#include "util/u_sampler.h"
#include "vl_winsys.h"
default: return "Unknown Error";
}
}
+
+void
+vlVdpResolveDelayedRendering(vlVdpDevice *dev, struct pipe_surface *surface, struct u_rect *dirty_area)
+{
+ struct vl_compositor_state *cstate;
+ vlVdpOutputSurface *vlsurface;
+
+ assert(dev);
+
+ cstate = dev->delayed_rendering.cstate;
+ if (!cstate)
+ return;
+
+ vlsurface = vlGetDataHTAB(dev->delayed_rendering.surface);
+ if (!vlsurface)
+ return;
+
+ if (!surface) {
+ surface = vlsurface->surface;
+ dirty_area = &vlsurface->dirty_area;
+ }
+
+ vl_compositor_render(cstate, &dev->compositor, surface, dirty_area);
+
+ dev->delayed_rendering.surface = VDP_INVALID_HANDLE;
+ dev->delayed_rendering.cstate = NULL;
+
+ /* test if we need to create a new sampler for the just filled texture */
+ if (surface->texture != vlsurface->sampler_view->texture) {
+ struct pipe_resource *res = surface->texture;
+ struct pipe_sampler_view sv_templ;
+
+ memset(&sv_templ, 0, sizeof(sv_templ));
+ u_sampler_view_default_template(&sv_templ, res, res->format);
+ pipe_sampler_view_reference(&vlsurface->sampler_view,
+ dev->context->create_sampler_view(dev->context, res, &sv_templ));
+ }
+
+ return;
+}
+
+void
+vlVdpSave4DelayedRendering(vlVdpDevice *dev, VdpOutputSurface surface, struct vl_compositor_state *cstate)
+{
+ assert(dev);
+
+ vlVdpResolveDelayedRendering(dev, NULL, NULL);
+
+ dev->delayed_rendering.surface = surface;
+ dev->delayed_rendering.cstate = cstate;
+}
vmixer = vlGetDataHTAB(mixer);
if (!vmixer)
return VDP_STATUS_INVALID_HANDLE;
+
+ vlVdpResolveDelayedRendering(vmixer->device, NULL, NULL);
+
vlRemoveDataHTAB(mixer);
vl_compositor_cleanup_state(&vmixer->cstate);
if (!vmixer)
return VDP_STATUS_INVALID_HANDLE;
+ vlVdpResolveDelayedRendering(vmixer->device, NULL, NULL);
+
compositor = &vmixer->device->compositor;
surf = vlGetDataHTAB(video_surface_current);
RectToPipe(video_source_rect, &src_rect), NULL, deinterlace);
vl_compositor_set_layer_dst_area(&vmixer->cstate, layer++, RectToPipe(destination_video_rect, &dst_rect));
vl_compositor_set_dst_clip(&vmixer->cstate, RectToPipe(destination_rect, &dst_clip));
- vl_compositor_render(&vmixer->cstate, compositor, dst->surface, &dst->dirty_area);
-
- /* applying the noise reduction after scaling is actually not very
- clever, but currently we should avoid to copy around the image
- data once more. */
- if (vmixer->noise_reduction.filter)
- vl_median_filter_render(vmixer->noise_reduction.filter,
- dst->sampler_view, dst->surface);
-
- if (vmixer->sharpness.filter)
- vl_matrix_filter_render(vmixer->sharpness.filter,
- dst->sampler_view, dst->surface);
+ if (!vmixer->noise_reduction.filter && !vmixer->sharpness.filter)
+ vlVdpSave4DelayedRendering(vmixer->device, destination_surface, &vmixer->cstate);
+ else {
+ vl_compositor_render(&vmixer->cstate, compositor, dst->surface, &dst->dirty_area);
+
+ /* applying the noise reduction after scaling is actually not very
+ clever, but currently we should avoid to copy around the image
+ data once more. */
+ if (vmixer->noise_reduction.filter)
+ vl_median_filter_render(vmixer->noise_reduction.filter,
+ dst->sampler_view, dst->surface);
+
+ if (vmixer->sharpness.filter)
+ vl_matrix_filter_render(vmixer->sharpness.filter,
+ dst->sampler_view, dst->surface);
+ }
return VDP_STATUS_OK;
}
if (!vlsurface)
return VDP_STATUS_INVALID_HANDLE;
+ vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
+
pipe_surface_reference(&vlsurface->surface, NULL);
pipe_sampler_view_reference(&vlsurface->sampler_view, NULL);
vl_compositor_cleanup_state(&vlsurface->cstate);
if (!vlsurface)
return VDP_STATUS_INVALID_HANDLE;
+ vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
+
context = vlsurface->device->context;
compositor = &vlsurface->device->compositor;
cstate = &vlsurface->cstate;
if (dst_vlsurface->device != src_vlsurface->device)
return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
+ vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL);
+
context = dst_vlsurface->device->context;
compositor = &dst_vlsurface->device->compositor;
cstate = &dst_vlsurface->cstate;
struct u_rect src_rect, dst_clip, *dirty_area;
struct vl_compositor *compositor;
+ struct vl_compositor_state *cstate;
pq = vlGetDataHTAB(presentation_queue);
if (!pq)
return VDP_STATUS_INVALID_HANDLE;
+
pipe = pq->device->context;
compositor = &pq->device->compositor;
+ cstate = &pq->cstate;
tex = vl_screen_texture_from_drawable(pq->device->vscreen, pq->drawable);
if (!tex)
surf->timestamp = (vlVdpTime)earliest_presentation_time;
- src_rect.x0 = 0;
- src_rect.y0 = 0;
- src_rect.x1 = surf_draw->width;
- src_rect.y1 = surf_draw->height;
-
dst_clip.x0 = 0;
dst_clip.y0 = 0;
dst_clip.x1 = clip_width ? clip_width : surf_draw->width;
dst_clip.y1 = clip_height ? clip_height : surf_draw->height;
- vl_compositor_clear_layers(&pq->cstate);
- vl_compositor_set_rgba_layer(&pq->cstate, compositor, 0, surf->sampler_view, &src_rect, NULL, NULL);
- vl_compositor_set_dst_clip(&pq->cstate, &dst_clip);
- vl_compositor_render(&pq->cstate, compositor, surf_draw, dirty_area);
+ if (pq->device->delayed_rendering.surface == surface &&
+ dst_clip.x1 == surf_draw->width && dst_clip.y1 == surf_draw->height) {
+
+ // TODO: we correctly support the clipping here, but not the pq background color in the clipped area....
+ cstate = pq->device->delayed_rendering.cstate;
+ vl_compositor_set_dst_clip(cstate, &dst_clip);
+ vlVdpResolveDelayedRendering(pq->device, surf_draw, dirty_area);
+
+ } else {
+ vlVdpResolveDelayedRendering(pq->device, NULL, NULL);
+
+ src_rect.x0 = 0;
+ src_rect.y0 = 0;
+ src_rect.x1 = surf_draw->width;
+ src_rect.y1 = surf_draw->height;
+
+ vl_compositor_clear_layers(cstate);
+ vl_compositor_set_rgba_layer(cstate, compositor, 0, surf->sampler_view, &src_rect, NULL, NULL);
+ vl_compositor_set_dst_clip(cstate, &dst_clip);
+ vl_compositor_render(cstate, compositor, surf_draw, dirty_area);
+ }
pipe->screen->flush_frontbuffer
(
struct vl_screen *vscreen;
struct pipe_context *context;
struct vl_compositor compositor;
+
+ struct {
+ struct vl_compositor_state *cstate;
+ VdpOutputSurface surface;
+ } delayed_rendering;
} vlVdpDevice;
typedef struct
VdpDeviceCreateX11 vdp_imp_device_create_x11;
VdpPresentationQueueTargetCreateX11 vlVdpPresentationQueueTargetCreateX11;
+/* Delayed rendering funtionality */
+void vlVdpResolveDelayedRendering(vlVdpDevice *dev, struct pipe_surface *surface, struct u_rect *dirty_area);
+void vlVdpSave4DelayedRendering(vlVdpDevice *dev, VdpOutputSurface surface, struct vl_compositor_state *cstate);
+
/* Internal function pointers */
VdpGetErrorString vlVdpGetErrorString;
VdpDeviceDestroy vlVdpDeviceDestroy;