**************************************************************************/
#include <stdio.h>
+#include <time.h>
+#include <sys/timeb.h>
#include <vdpau/vdpau.h>
pq->device = dev;
pq->drawable = pqt->drawable;
-
+
if (!vl_compositor_init(&pq->compositor, dev->context->pipe)) {
ret = VDP_STATUS_ERROR;
goto no_compositor;
}
+ vl_compositor_reset_dirty_area(&pq->dirty_area);
+
*presentation_queue = vlAddDataHTAB(pq);
if (*presentation_queue == 0) {
ret = VDP_STATUS_ERROR;
VdpColor *const background_color)
{
vlVdpPresentationQueue *pq;
+ union pipe_color_union color;
VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Setting background color\n");
if (!pq)
return VDP_STATUS_INVALID_HANDLE;
- vl_compositor_set_clear_color(&pq->compositor, (float*)background_color);
+ color.f[0] = background_color->red;
+ color.f[1] = background_color->green;
+ color.f[2] = background_color->blue;
+ color.f[3] = background_color->alpha;
+
+ vl_compositor_set_clear_color(&pq->compositor, &color);
return VDP_STATUS_OK;
}
VdpColor *const background_color)
{
vlVdpPresentationQueue *pq;
+ union pipe_color_union color;
VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Getting background color\n");
if (!pq)
return VDP_STATUS_INVALID_HANDLE;
- vl_compositor_get_clear_color(&pq->compositor, (float*)background_color);
+ vl_compositor_get_clear_color(&pq->compositor, &color);
+
+ background_color->red = color.f[0];
+ background_color->green = color.f[1];
+ background_color->blue = color.f[2];
+ background_color->alpha = color.f[3];
return VDP_STATUS_OK;
}
vlVdpPresentationQueueGetTime(VdpPresentationQueue presentation_queue,
VdpTime *current_time)
{
+ vlVdpPresentationQueue *pq;
+ struct timespec ts;
+
VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Getting queue time\n");
if (!current_time)
return VDP_STATUS_INVALID_POINTER;
- return VDP_STATUS_NO_IMPLEMENTATION;
+ pq = vlGetDataHTAB(presentation_queue);
+ if (!pq)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ *current_time = (uint64_t)ts.tv_sec * 1000000000LL + (uint64_t)ts.tv_nsec;
+
+ return VDP_STATUS_OK;
}
/**
vlVdpPresentationQueue *pq;
vlVdpOutputSurface *surf;
+
+ struct pipe_context *pipe;
struct pipe_surface *drawable_surface;
+ struct pipe_video_rect src_rect, dst_clip;
pq = vlGetDataHTAB(presentation_queue);
if (!pq)
if (!surf)
return VDP_STATUS_INVALID_HANDLE;
+ surf->timestamp = (vlVdpTime)earliest_presentation_time;
+
+ src_rect.x = 0;
+ src_rect.y = 0;
+ src_rect.w = drawable_surface->width;
+ src_rect.h = drawable_surface->height;
+
+ dst_clip.x = 0;
+ dst_clip.y = 0;
+ dst_clip.w = clip_width;
+ dst_clip.h = clip_height;
+
vl_compositor_clear_layers(&pq->compositor);
- vl_compositor_set_rgba_layer(&pq->compositor, 0, surf->sampler_view, NULL, NULL);
- vl_compositor_render(&pq->compositor, drawable_surface, NULL, NULL, true);
+ vl_compositor_set_rgba_layer(&pq->compositor, 0, surf->sampler_view, &src_rect, NULL);
+ vl_compositor_render(&pq->compositor, drawable_surface, NULL, &dst_clip, &pq->dirty_area);
+
+ pipe = pq->device->context->pipe;
- pq->device->context->pipe->screen->flush_frontbuffer
+ pipe->screen->flush_frontbuffer
(
- pq->device->context->pipe->screen,
+ pipe->screen,
drawable_surface->texture,
0, 0,
vl_contextprivate_get(pq->device->context, drawable_surface)
);
+ pipe->screen->fence_reference(pipe->screen, &surf->fence, NULL);
+ pipe->flush(pipe, &surf->fence);
+
if (dump_window == -1) {
dump_window = debug_get_num_option("VDPAU_DUMP", 0);
}
VdpOutputSurface surface,
VdpTime *first_presentation_time)
{
+ vlVdpPresentationQueue *pq;
+ vlVdpOutputSurface *surf;
+ struct pipe_screen *screen;
+
if (!first_presentation_time)
return VDP_STATUS_INVALID_POINTER;
- //return VDP_STATUS_NO_IMPLEMENTATION;
+ pq = vlGetDataHTAB(presentation_queue);
+ if (!pq)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ surf = vlGetDataHTAB(surface);
+ if (!surf)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ if (surf->fence) {
+ screen = pq->device->context->pipe->screen;
+ screen->fence_finish(screen, surf->fence, 0);
+ }
+
+ // We actually need to query the timestamp of the last VSYNC event from the hardware
+ vlVdpPresentationQueueGetTime(presentation_queue, first_presentation_time);
+
return VDP_STATUS_OK;
}
VdpPresentationQueueStatus *status,
VdpTime *first_presentation_time)
{
+ vlVdpPresentationQueue *pq;
+ vlVdpOutputSurface *surf;
+ struct pipe_screen *screen;
+
if (!(status && first_presentation_time))
return VDP_STATUS_INVALID_POINTER;
- return VDP_STATUS_NO_IMPLEMENTATION;
+ pq = vlGetDataHTAB(presentation_queue);
+ if (!pq)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ surf = vlGetDataHTAB(surface);
+ if (!surf)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ *first_presentation_time = 0;
+
+ if (!surf->fence) {
+ *status = VDP_PRESENTATION_QUEUE_STATUS_IDLE;
+ } else {
+ screen = pq->device->context->pipe->screen;
+ if (screen->fence_signalled(screen, surf->fence)) {
+ screen->fence_reference(screen, &surf->fence, NULL);
+ *status = VDP_PRESENTATION_QUEUE_STATUS_VISIBLE;
+
+ // We actually need to query the timestamp of the last VSYNC event from the hardware
+ vlVdpPresentationQueueGetTime(presentation_queue, first_presentation_time);
+ *first_presentation_time += 1;
+ } else {
+ *status = VDP_PRESENTATION_QUEUE_STATUS_QUEUED;
+ }
+ }
+
+ return VDP_STATUS_OK;
}