1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 Younes Manton. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* directly referenced from target Makefile, because of X dependencies */ 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/types.h> 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/stat.h> 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <fcntl.h> 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/Xlib-xcb.h> 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <xcb/dri2.h> 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <xf86drm.h> 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_state.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "state_tracker/drm_driver.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h" 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_hash.h" 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_hash_table.h" 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h" 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vl/vl_compositor.h" 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vl/vl_winsys.h" 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct vl_dri_screen 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vl_screen base; 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_connection_t *conn; 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_drawable_t drawable; 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned width, height; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool current_buffer; 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint32_t buffer_names[2]; 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct u_rect dirty_areas[2]; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool flushed; 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_swap_buffers_cookie_t swap_cookie; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_wait_sbc_cookie_t wait_cookie; 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_get_buffers_cookie_t buffers_cookie; 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int64_t last_ust, ns_frame, last_msc, next_msc, skew_msc; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const unsigned int attachments[1] = { XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT }; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_dri2_handle_stamps(struct vl_dri_screen* scrn, 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint32_t ust_hi, uint32_t ust_lo, 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint32_t msc_hi, uint32_t msc_lo) 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int64_t ust = ((((uint64_t)ust_hi) << 32) | ust_lo) * 1000; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int64_t msc = (((uint64_t)msc_hi) << 32) | msc_lo; 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (scrn->last_ust && scrn->last_msc && (ust > scrn->last_ust) && (msc > scrn->last_msc)) 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->ns_frame = (ust - scrn->last_ust) / (msc - scrn->last_msc); 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (scrn->next_msc && (scrn->next_msc < msc)) 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->skew_msc++; 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->last_ust = ust; 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->last_msc = msc; 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic xcb_dri2_get_buffers_reply_t* 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_dri2_get_flush_reply(struct vl_dri_screen *scrn) 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_wait_sbc_reply_t *wait_sbc_reply; 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(scrn); 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!scrn->flushed) 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->flushed = false; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(xcb_dri2_swap_buffers_reply(scrn->conn, scrn->swap_cookie, NULL)); 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org wait_sbc_reply = xcb_dri2_wait_sbc_reply(scrn->conn, scrn->wait_cookie, NULL); 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!wait_sbc_reply) 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_dri2_handle_stamps(scrn, wait_sbc_reply->ust_hi, wait_sbc_reply->ust_lo, 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org wait_sbc_reply->msc_hi, wait_sbc_reply->msc_lo); 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(wait_sbc_reply); 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return xcb_dri2_get_buffers_reply(scrn->conn, scrn->buffers_cookie, NULL); 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_dri2_flush_frontbuffer(struct pipe_screen *screen, 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource *resource, 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned level, unsigned layer, 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *context_private) 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vl_dri_screen *scrn = (struct vl_dri_screen*)context_private; 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint32_t msc_hi, msc_lo; 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(screen); 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(resource); 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(context_private); 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(vl_dri2_get_flush_reply(scrn)); 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org msc_hi = scrn->next_msc >> 32; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org msc_lo = scrn->next_msc & 0xFFFFFFFF; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->swap_cookie = xcb_dri2_swap_buffers_unchecked(scrn->conn, scrn->drawable, msc_hi, msc_lo, 0, 0, 0, 0); 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->wait_cookie = xcb_dri2_wait_sbc_unchecked(scrn->conn, scrn->drawable, 0, 0); 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->buffers_cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, scrn->drawable, 1, 1, attachments); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->flushed = true; 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->current_buffer = !scrn->current_buffer; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_dri2_destroy_drawable(struct vl_dri_screen *scrn) 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_void_cookie_t destroy_cookie; 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (scrn->drawable) { 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(vl_dri2_get_flush_reply(scrn)); 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destroy_cookie = xcb_dri2_destroy_drawable_checked(scrn->conn, scrn->drawable); 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* ignore any error here, since the drawable can be destroyed long ago */ 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(xcb_request_check(scrn->conn, destroy_cookie)); 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_dri2_set_drawable(struct vl_dri_screen *scrn, Drawable drawable) 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(scrn); 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(drawable); 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (scrn->drawable == drawable) 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_dri2_destroy_drawable(scrn); 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_create_drawable(scrn->conn, drawable); 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->current_buffer = false; 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]); 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]); 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->drawable = drawable; 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_resource* 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable) 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen; 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct winsys_handle dri2_handle; 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource template, *tex; 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_get_buffers_reply_t *reply; 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_dri2_buffer_t *buffers, *back_left; 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(scrn); 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_dri2_set_drawable(scrn, drawable); 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reply = vl_dri2_get_flush_reply(scrn); 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!reply) { 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_get_buffers_cookie_t cookie; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, drawable, 1, 1, attachments); 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reply = xcb_dri2_get_buffers_reply(scrn->conn, cookie, NULL); 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!reply) 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffers = xcb_dri2_get_buffers_buffers(reply); 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!buffers) { 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(reply); 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < reply->count; ++i) { 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (buffers[i].attachment == XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT) { 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org back_left = &buffers[i]; 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (i == reply->count) { 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(reply); 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reply->width != scrn->width || reply->height != scrn->height) { 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]); 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]); 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->width = reply->width; 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->height = reply->height; 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (back_left->name != scrn->buffer_names[scrn->current_buffer]) { 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_compositor_reset_dirty_area(&scrn->dirty_areas[scrn->current_buffer]); 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->buffer_names[scrn->current_buffer] = back_left->name; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&dri2_handle, 0, sizeof(dri2_handle)); 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dri2_handle.type = DRM_API_HANDLE_TYPE_SHARED; 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dri2_handle.handle = back_left->name; 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dri2_handle.stride = back_left->pitch; 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&template, 0, sizeof(template)); 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template.target = PIPE_TEXTURE_2D; 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template.format = PIPE_FORMAT_B8G8R8X8_UNORM; 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template.last_level = 0; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template.width0 = reply->width; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template.height0 = reply->height; 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template.depth0 = 1; 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template.array_size = 1; 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template.usage = PIPE_USAGE_STATIC; 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template.bind = PIPE_BIND_RENDER_TARGET; 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template.flags = 0; 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &template, &dri2_handle); 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(reply); 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return tex; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct u_rect * 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_screen_get_dirty_area(struct vl_screen *vscreen) 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen; 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(scrn); 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &scrn->dirty_areas[scrn->current_buffer]; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orguint64_t 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_screen_get_timestamp(struct vl_screen *vscreen, Drawable drawable) 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen; 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_get_msc_cookie_t cookie; 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_get_msc_reply_t *reply; 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(scrn); 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_dri2_set_drawable(scrn, drawable); 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!scrn->last_ust) { 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cookie = xcb_dri2_get_msc_unchecked(scrn->conn, drawable); 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reply = xcb_dri2_get_msc_reply(scrn->conn, cookie, NULL); 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reply) { 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_dri2_handle_stamps(scrn, reply->ust_hi, reply->ust_lo, 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reply->msc_hi, reply->msc_lo); 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(reply); 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return scrn->last_ust; 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_screen_set_next_timestamp(struct vl_screen *vscreen, uint64_t stamp) 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen; 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(scrn); 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stamp && scrn->last_ust && scrn->ns_frame && scrn->last_msc) 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->next_msc = ((int64_t)stamp - scrn->last_ust) / scrn->ns_frame + scrn->last_msc + scrn->skew_msc; 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->next_msc = 0; 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid* 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_screen_get_private(struct vl_screen *vscreen) 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return vscreen; 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct vl_screen* 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_screen_create(Display *display, int screen) 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vl_dri_screen *scrn; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const xcb_query_extension_reply_t *extension; 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_query_version_cookie_t dri2_query_cookie; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_query_version_reply_t *dri2_query = NULL; 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_connect_cookie_t connect_cookie; 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_connect_reply_t *connect = NULL; 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_authenticate_cookie_t authenticate_cookie; 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_dri2_authenticate_reply_t *authenticate = NULL; 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_screen_iterator_t s; 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_generic_error_t *error = NULL; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org char *device_name; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int fd, device_name_length; 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org drm_magic_t magic; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(display); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn = CALLOC_STRUCT(vl_dri_screen); 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!scrn) 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->conn = XGetXCBConnection(display); 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!scrn->conn) 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto free_screen; 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org xcb_prefetch_extension_data(scrn->conn, &xcb_dri2_id); 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org extension = xcb_get_extension_data(scrn->conn, &xcb_dri2_id); 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!(extension && extension->present)) 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto free_screen; 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dri2_query_cookie = xcb_dri2_query_version (scrn->conn, XCB_DRI2_MAJOR_VERSION, XCB_DRI2_MINOR_VERSION); 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dri2_query = xcb_dri2_query_version_reply (scrn->conn, dri2_query_cookie, &error); 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dri2_query == NULL || error != NULL || dri2_query->minor_version < 2) 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto free_screen; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s = xcb_setup_roots_iterator(xcb_get_setup(scrn->conn)); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org connect_cookie = xcb_dri2_connect_unchecked(scrn->conn, s.data->root, XCB_DRI2_DRIVER_TYPE_DRI); 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org connect = xcb_dri2_connect_reply(scrn->conn, connect_cookie, NULL); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (connect == NULL || connect->driver_name_length + connect->device_name_length == 0) 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto free_screen; 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org device_name_length = xcb_dri2_connect_device_name_length(connect); 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org device_name = CALLOC(1, device_name_length); 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(device_name, xcb_dri2_connect_device_name(connect), device_name_length); 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org device_name[device_name_length] = 0; 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fd = open(device_name, O_RDWR); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(device_name); 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fd < 0) 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto free_screen; 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (drmGetMagic(fd, &magic)) 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto free_screen; 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org authenticate_cookie = xcb_dri2_authenticate_unchecked(scrn->conn, s.data->root, magic); 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org authenticate = xcb_dri2_authenticate_reply(scrn->conn, authenticate_cookie, NULL); 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (authenticate == NULL || !authenticate->authenticated) 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto free_screen; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->base.pscreen = driver_descriptor.create_screen(fd); 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!scrn->base.pscreen) 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto free_screen; 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer; 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]); 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]); 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(dri2_query); 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(connect); 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(authenticate); 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &scrn->base; 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfree_screen: 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(scrn); 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(dri2_query); 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(connect); 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(authenticate); 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(error); 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid vl_screen_destroy(struct vl_screen *vscreen) 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen; 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(vscreen); 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (scrn->flushed) { 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(xcb_dri2_swap_buffers_reply(scrn->conn, scrn->swap_cookie, NULL)); 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(xcb_dri2_wait_sbc_reply(scrn->conn, scrn->wait_cookie, NULL)); 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(xcb_dri2_get_buffers_reply(scrn->conn, scrn->buffers_cookie, NULL)); 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vl_dri2_destroy_drawable(scrn); 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scrn->base.pscreen->destroy(scrn->base.pscreen); 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(scrn); 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 401