X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fvdpau%2Fpresentation.c;h=e7f387e6173809e2db3e637ef9b03940c73d9bda;hb=2d140ae70ac6ad69f39d427d95bd622d5640a1b7;hp=4d12bb3e700ab6394c622f92b2cac1e8ffd38fbc;hpb=d645dc65b6c5e7d46538e98208a703f0f7a5d20b;p=mesa.git diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c index 4d12bb3e700..e7f387e6173 100644 --- a/src/gallium/state_trackers/vdpau/presentation.c +++ b/src/gallium/state_trackers/vdpau/presentation.c @@ -18,7 +18,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -26,9 +26,6 @@ **************************************************************************/ #include -#include -#include - #include #include "util/u_debug.h" @@ -65,13 +62,16 @@ vlVdpPresentationQueueCreate(VdpDevice device, if (!pq) return VDP_STATUS_RESOURCES; - pq->device = dev; + DeviceReference(&pq->device, dev); pq->drawable = pqt->drawable; + pipe_mutex_lock(dev->mutex); if (!vl_compositor_init_state(&pq->cstate, dev->context)) { + pipe_mutex_unlock(dev->mutex); ret = VDP_STATUS_ERROR; goto no_compositor; } + pipe_mutex_unlock(dev->mutex); *presentation_queue = vlAddDataHTAB(pq); if (*presentation_queue == 0) { @@ -83,6 +83,7 @@ vlVdpPresentationQueueCreate(VdpDevice device, no_handle: no_compositor: + DeviceReference(&pq->device, NULL); FREE(pq); return ret; } @@ -99,9 +100,12 @@ vlVdpPresentationQueueDestroy(VdpPresentationQueue presentation_queue) if (!pq) return VDP_STATUS_INVALID_HANDLE; + pipe_mutex_lock(pq->device->mutex); vl_compositor_cleanup_state(&pq->cstate); + pipe_mutex_unlock(pq->device->mutex); vlRemoveDataHTAB(presentation_queue); + DeviceReference(&pq->device, NULL); FREE(pq); return VDP_STATUS_OK; @@ -129,7 +133,9 @@ vlVdpPresentationQueueSetBackgroundColor(VdpPresentationQueue presentation_queue color.f[2] = background_color->blue; color.f[3] = background_color->alpha; + pipe_mutex_lock(pq->device->mutex); vl_compositor_set_clear_color(&pq->cstate, &color); + pipe_mutex_unlock(pq->device->mutex); return VDP_STATUS_OK; } @@ -151,7 +157,9 @@ vlVdpPresentationQueueGetBackgroundColor(VdpPresentationQueue presentation_queue if (!pq) return VDP_STATUS_INVALID_HANDLE; + pipe_mutex_lock(pq->device->mutex); vl_compositor_get_clear_color(&pq->cstate, &color); + pipe_mutex_unlock(pq->device->mutex); background_color->red = color.f[0]; background_color->green = color.f[1]; @@ -169,7 +177,6 @@ vlVdpPresentationQueueGetTime(VdpPresentationQueue presentation_queue, VdpTime *current_time) { vlVdpPresentationQueue *pq; - struct timespec ts; if (!current_time) return VDP_STATUS_INVALID_POINTER; @@ -178,8 +185,10 @@ vlVdpPresentationQueueGetTime(VdpPresentationQueue 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; + pipe_mutex_lock(pq->device->mutex); + *current_time = pq->device->vscreen->get_timestamp(pq->device->vscreen, + (void *)pq->drawable); + pipe_mutex_unlock(pq->device->mutex); return VDP_STATUS_OK; } @@ -205,54 +214,69 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue, struct u_rect src_rect, dst_clip, *dirty_area; struct vl_compositor *compositor; + struct vl_compositor_state *cstate; + struct vl_screen *vscreen; pq = vlGetDataHTAB(presentation_queue); if (!pq) return VDP_STATUS_INVALID_HANDLE; + surf = vlGetDataHTAB(surface); + if (!surf) + return VDP_STATUS_INVALID_HANDLE; + pipe = pq->device->context; compositor = &pq->device->compositor; + cstate = &pq->cstate; + vscreen = pq->device->vscreen; - tex = vl_screen_texture_from_drawable(pq->device->vscreen, pq->drawable); - if (!tex) + pipe_mutex_lock(pq->device->mutex); + tex = vscreen->texture_from_drawable(vscreen, (void *)pq->drawable); + if (!tex) { + pipe_mutex_unlock(pq->device->mutex); return VDP_STATUS_INVALID_HANDLE; + } - dirty_area = vl_screen_get_dirty_area(pq->device->vscreen); + dirty_area = vscreen->get_dirty_area(vscreen); memset(&surf_templ, 0, sizeof(surf_templ)); surf_templ.format = tex->format; - surf_templ.usage = PIPE_BIND_RENDER_TARGET; surf_draw = pipe->create_surface(pipe, tex, &surf_templ); - surf = vlGetDataHTAB(surface); - if (!surf) - return VDP_STATUS_INVALID_HANDLE; - - 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); - 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; - pipe->screen->flush_frontbuffer - ( - pipe->screen, tex, 0, 0, - vl_screen_get_private(pq->device->vscreen) - ); + 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, true); + } + + vscreen->set_next_timestamp(vscreen, earliest_presentation_time); + pipe->screen->flush_frontbuffer(pipe->screen, tex, 0, 0, + vscreen->get_private(vscreen), NULL); pipe->screen->fence_reference(pipe->screen, &surf->fence, NULL); - pipe->flush(pipe, &surf->fence); + pipe->flush(pipe, &surf->fence, 0); + pq->last_surf = surf; if (dump_window == -1) { dump_window = debug_get_num_option("VDPAU_DUMP", 0); @@ -262,13 +286,17 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue, static unsigned int framenum = 0; char cmd[256]; - sprintf(cmd, "xwd -id %d -out vdpau_frame_%08d.xwd", (int)pq->drawable, ++framenum); - if (system(cmd) != 0) - VDPAU_MSG(VDPAU_ERR, "[VDPAU] Dumping surface %d failed.\n", surface); + if (framenum) { + sprintf(cmd, "xwd -id %d -silent -out vdpau_frame_%08d.xwd", (int)pq->drawable, framenum); + if (system(cmd) != 0) + VDPAU_MSG(VDPAU_ERR, "[VDPAU] Dumping surface %d failed.\n", surface); + } + framenum++; } pipe_resource_reference(&tex, NULL); pipe_surface_reference(&surf_draw, NULL); + pipe_mutex_unlock(pq->device->mutex); return VDP_STATUS_OK; } @@ -296,15 +324,15 @@ vlVdpPresentationQueueBlockUntilSurfaceIdle(VdpPresentationQueue presentation_qu if (!surf) return VDP_STATUS_INVALID_HANDLE; + pipe_mutex_lock(pq->device->mutex); if (surf->fence) { screen = pq->device->vscreen->pscreen; - screen->fence_finish(screen, surf->fence, 0); + screen->fence_finish(screen, surf->fence, PIPE_TIMEOUT_INFINITE); + screen->fence_reference(screen, &surf->fence, NULL); } + pipe_mutex_unlock(pq->device->mutex); - // 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; + return vlVdpPresentationQueueGetTime(presentation_queue, first_presentation_time); } /** @@ -334,18 +362,24 @@ vlVdpPresentationQueueQuerySurfaceStatus(VdpPresentationQueue presentation_queue *first_presentation_time = 0; if (!surf->fence) { - *status = VDP_PRESENTATION_QUEUE_STATUS_IDLE; + if (pq->last_surf == surf) + *status = VDP_PRESENTATION_QUEUE_STATUS_VISIBLE; + else + *status = VDP_PRESENTATION_QUEUE_STATUS_IDLE; } else { + pipe_mutex_lock(pq->device->mutex); screen = pq->device->vscreen->pscreen; - if (screen->fence_signalled(screen, surf->fence)) { + if (screen->fence_finish(screen, surf->fence, 0)) { screen->fence_reference(screen, &surf->fence, NULL); *status = VDP_PRESENTATION_QUEUE_STATUS_VISIBLE; + pipe_mutex_unlock(pq->device->mutex); // 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; + pipe_mutex_unlock(pq->device->mutex); } }