/* * Copyright (c) 2013 Jens Kuske * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "vdpau_private.h" #include #include #include #include #include #include #include "rgba.h" #include "sunxi_disp.h" static uint64_t get_time(void) { struct timespec tp; if (clock_gettime(CLOCK_MONOTONIC, &tp) == -1) return 0; return (uint64_t)tp.tv_sec * 1000000000ULL + (uint64_t)tp.tv_nsec; } VdpStatus vdp_presentation_queue_target_create_x11(VdpDevice device, Drawable drawable, VdpPresentationQueueTarget *target) { if (!target || !drawable) return VDP_STATUS_INVALID_POINTER; device_ctx_t *dev = handle_get(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; queue_target_ctx_t *qt = handle_create(sizeof(*qt), target); if (!qt) return VDP_STATUS_RESOURCES; qt->drawable = drawable; XSetWindowBackground(dev->display, drawable, 0x000102); qt->disp = sunxi_disp_open(dev->osd_enabled); if (!qt->disp) qt->disp = sunxi_disp2_open(dev->osd_enabled); if (!qt->disp) { dev->osd_enabled = 0; qt->disp = sunxi_disp1_5_open(dev->osd_enabled); } if (!qt->disp) return VDP_STATUS_ERROR; return VDP_STATUS_OK; } VdpStatus vdp_presentation_queue_target_destroy(VdpPresentationQueueTarget presentation_queue_target) { queue_target_ctx_t *qt = handle_get(presentation_queue_target); if (!qt) return VDP_STATUS_INVALID_HANDLE; qt->disp->close(qt->disp); handle_destroy(presentation_queue_target); return VDP_STATUS_OK; } VdpStatus vdp_presentation_queue_create(VdpDevice device, VdpPresentationQueueTarget presentation_queue_target, VdpPresentationQueue *presentation_queue) { if (!presentation_queue) return VDP_STATUS_INVALID_POINTER; device_ctx_t *dev = handle_get(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; queue_target_ctx_t *qt = handle_get(presentation_queue_target); if (!qt) return VDP_STATUS_INVALID_HANDLE; queue_ctx_t *q = handle_create(sizeof(*q), presentation_queue); if (!q) return VDP_STATUS_RESOURCES; q->target = qt; q->device = dev; return VDP_STATUS_OK; } VdpStatus vdp_presentation_queue_destroy(VdpPresentationQueue presentation_queue) { queue_ctx_t *q = handle_get(presentation_queue); if (!q) return VDP_STATUS_INVALID_HANDLE; handle_destroy(presentation_queue); return VDP_STATUS_OK; } VdpStatus vdp_presentation_queue_set_background_color(VdpPresentationQueue presentation_queue, VdpColor *const background_color) { if (!background_color) return VDP_STATUS_INVALID_POINTER; queue_ctx_t *q = handle_get(presentation_queue); if (!q) return VDP_STATUS_INVALID_HANDLE; q->background.red = background_color->red; q->background.green = background_color->green; q->background.blue = background_color->blue; q->background.alpha = background_color->alpha; return VDP_STATUS_OK; } VdpStatus vdp_presentation_queue_get_background_color(VdpPresentationQueue presentation_queue, VdpColor *const background_color) { if (!background_color) return VDP_STATUS_INVALID_POINTER; queue_ctx_t *q = handle_get(presentation_queue); if (!q) return VDP_STATUS_INVALID_HANDLE; background_color->red = q->background.red; background_color->green = q->background.green; background_color->blue = q->background.blue; background_color->alpha = q->background.alpha; return VDP_STATUS_OK; } VdpStatus vdp_presentation_queue_get_time(VdpPresentationQueue presentation_queue, VdpTime *current_time) { queue_ctx_t *q = handle_get(presentation_queue); if (!q) return VDP_STATUS_INVALID_HANDLE; *current_time = get_time(); return VDP_STATUS_OK; } VdpStatus vdp_presentation_queue_display(VdpPresentationQueue presentation_queue, VdpOutputSurface surface, uint32_t clip_width, uint32_t clip_height, VdpTime earliest_presentation_time) { queue_ctx_t *q = handle_get(presentation_queue); if (!q) return VDP_STATUS_INVALID_HANDLE; output_surface_ctx_t *os = handle_get(surface); if (!os) return VDP_STATUS_INVALID_HANDLE; if (earliest_presentation_time != 0) VDPAU_DBG_ONCE("Presentation time not supported"); Window c; int x,y; XTranslateCoordinates(q->device->display, q->target->drawable, RootWindow(q->device->display, q->device->screen), 0, 0, &x, &y, &c); XClearWindow(q->device->display, q->target->drawable); if (os->vs) q->target->disp->set_video_layer(q->target->disp, x, y, clip_width, clip_height, os); else q->target->disp->close_video_layer(q->target->disp); if (!q->device->osd_enabled) return VDP_STATUS_OK; if (os->rgba.flags & RGBA_FLAG_NEEDS_CLEAR) rgba_clear(&os->rgba); if (os->rgba.flags & RGBA_FLAG_DIRTY) { rgba_flush(&os->rgba); q->target->disp->set_osd_layer(q->target->disp, x, y, clip_width, clip_height, os); } else { q->target->disp->close_osd_layer(q->target->disp); } return VDP_STATUS_OK; } VdpStatus vdp_presentation_queue_block_until_surface_idle(VdpPresentationQueue presentation_queue, VdpOutputSurface surface, VdpTime *first_presentation_time) { queue_ctx_t *q = handle_get(presentation_queue); if (!q) return VDP_STATUS_INVALID_HANDLE; output_surface_ctx_t *out = handle_get(surface); if (!out) return VDP_STATUS_INVALID_HANDLE; *first_presentation_time = get_time(); return VDP_STATUS_OK; } VdpStatus vdp_presentation_queue_query_surface_status(VdpPresentationQueue presentation_queue, VdpOutputSurface surface, VdpPresentationQueueStatus *status, VdpTime *first_presentation_time) { queue_ctx_t *q = handle_get(presentation_queue); if (!q) return VDP_STATUS_INVALID_HANDLE; output_surface_ctx_t *out = handle_get(surface); if (!out) return VDP_STATUS_INVALID_HANDLE; *status = VDP_PRESENTATION_QUEUE_STATUS_VISIBLE; *first_presentation_time = get_time(); return VDP_STATUS_OK; }