X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fvdpau%2Fpresentation.c;h=0e086fc18b42ae89517b39e86f8d19253e4a8a3a;hb=e8e0756bd35e5e3b70a0eee323f5aaa3707fe11d;hp=b3b543b4a80d44a91445e4838cb4c15cabee4380;hpb=85534e6f48c1ad6ff8dee77e0407c6c3dedb4b84;p=mesa.git diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c index b3b543b4a80..0e086fc18b4 100644 --- a/src/gallium/state_trackers/vdpau/presentation.c +++ b/src/gallium/state_trackers/vdpau/presentation.c @@ -26,6 +26,8 @@ **************************************************************************/ #include +#include +#include #include @@ -67,12 +69,14 @@ vlVdpPresentationQueueCreate(VdpDevice device, 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; @@ -117,6 +121,7 @@ vlVdpPresentationQueueSetBackgroundColor(VdpPresentationQueue presentation_queue VdpColor *const background_color) { vlVdpPresentationQueue *pq; + union pipe_color_union color; VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Setting background color\n"); @@ -127,7 +132,12 @@ vlVdpPresentationQueueSetBackgroundColor(VdpPresentationQueue presentation_queue 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; } @@ -140,6 +150,7 @@ vlVdpPresentationQueueGetBackgroundColor(VdpPresentationQueue presentation_queue VdpColor *const background_color) { vlVdpPresentationQueue *pq; + union pipe_color_union color; VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Getting background color\n"); @@ -150,7 +161,12 @@ vlVdpPresentationQueueGetBackgroundColor(VdpPresentationQueue presentation_queue 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; } @@ -162,12 +178,22 @@ VdpStatus 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; } /** @@ -184,7 +210,10 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue, 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) @@ -198,18 +227,35 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue, 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); } @@ -236,10 +282,29 @@ vlVdpPresentationQueueBlockUntilSurfaceIdle(VdpPresentationQueue presentation_qu 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; } @@ -252,8 +317,38 @@ vlVdpPresentationQueueQuerySurfaceStatus(VdpPresentationQueue presentation_queue 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; }