1e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton/**************************************************************************
2e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton *
3e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * Copyright 2009 Younes Manton.
4e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * All Rights Reserved.
5e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton *
6e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * Permission is hereby granted, free of charge, to any person obtaining a
7e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * copy of this software and associated documentation files (the
8e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * "Software"), to deal in the Software without restriction, including
9e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * without limitation the rights to use, copy, modify, merge, publish,
10e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * distribute, sub license, and/or sell copies of the Software, and to
11e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * permit persons to whom the Software is furnished to do so, subject to
12e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * the following conditions:
13e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton *
14e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * The above copyright notice and this permission notice (including the
15e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * next paragraph) shall be included in all copies or substantial portions
16e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * of the Software.
17e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton *
18e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton *
26e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton **************************************************************************/
27e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
28fc0a5e21d77ae2f082fd19dd2295e84f6fb7bd3bChristian König/* directly referenced from target Makefile, because of X dependencies */
29fc0a5e21d77ae2f082fd19dd2295e84f6fb7bd3bChristian König
30b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König#include <sys/types.h>
31b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König#include <sys/stat.h>
32b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König#include <fcntl.h>
33b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König
3480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König#include <X11/Xlib-xcb.h>
3580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König#include <xcb/dri2.h>
36b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König#include <xf86drm.h>
37b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König
38d4e8f384776cb9fefe20e792493642e074e8b229Kai Wasserbäch#include "pipe/p_screen.h"
39d4e8f384776cb9fefe20e792493642e074e8b229Kai Wasserbäch#include "pipe/p_context.h"
40d4e8f384776cb9fefe20e792493642e074e8b229Kai Wasserbäch#include "pipe/p_state.h"
41b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König#include "state_tracker/drm_driver.h"
42b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König
43d4e8f384776cb9fefe20e792493642e074e8b229Kai Wasserbäch#include "util/u_memory.h"
44d4e8f384776cb9fefe20e792493642e074e8b229Kai Wasserbäch#include "util/u_hash.h"
45d4e8f384776cb9fefe20e792493642e074e8b229Kai Wasserbäch#include "util/u_hash_table.h"
46d4e8f384776cb9fefe20e792493642e074e8b229Kai Wasserbäch#include "util/u_inlines.h"
47b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König
48c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König#include "vl/vl_compositor.h"
49fc0a5e21d77ae2f082fd19dd2295e84f6fb7bd3bChristian König#include "vl/vl_winsys.h"
50e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
51e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Mantonstruct vl_dri_screen
52e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton{
53e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   struct vl_screen base;
5480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_connection_t *conn;
5580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_drawable_t drawable;
5691ac681113b05f8fe4dff51c3b80f967ac05c867Christian König
57c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   unsigned width, height;
58c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König
59c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   bool current_buffer;
60c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   uint32_t buffer_names[2];
61c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   struct u_rect dirty_areas[2];
62c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König
6391ac681113b05f8fe4dff51c3b80f967ac05c867Christian König   bool flushed;
6491ac681113b05f8fe4dff51c3b80f967ac05c867Christian König   xcb_dri2_swap_buffers_cookie_t swap_cookie;
6591ac681113b05f8fe4dff51c3b80f967ac05c867Christian König   xcb_dri2_wait_sbc_cookie_t wait_cookie;
6691ac681113b05f8fe4dff51c3b80f967ac05c867Christian König   xcb_dri2_get_buffers_cookie_t buffers_cookie;
671d0c357a9733238985cbe029b174173ef927ac70Christian König
681d0c357a9733238985cbe029b174173ef927ac70Christian König   int64_t last_ust, ns_frame, last_msc, next_msc, skew_msc;
69e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton};
70e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
7191ac681113b05f8fe4dff51c3b80f967ac05c867Christian Königstatic const unsigned int attachments[1] = { XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT };
7291ac681113b05f8fe4dff51c3b80f967ac05c867Christian König
73404fb63b4649f58fce443615e49337d42b8ddeceYounes Mantonstatic void
741d0c357a9733238985cbe029b174173ef927ac70Christian Königvl_dri2_handle_stamps(struct vl_dri_screen* scrn,
751d0c357a9733238985cbe029b174173ef927ac70Christian König                      uint32_t ust_hi, uint32_t ust_lo,
761d0c357a9733238985cbe029b174173ef927ac70Christian König                      uint32_t msc_hi, uint32_t msc_lo)
771d0c357a9733238985cbe029b174173ef927ac70Christian König{
781d0c357a9733238985cbe029b174173ef927ac70Christian König   int64_t ust = ((((uint64_t)ust_hi) << 32) | ust_lo) * 1000;
791d0c357a9733238985cbe029b174173ef927ac70Christian König   int64_t msc = (((uint64_t)msc_hi) << 32) | msc_lo;
801d0c357a9733238985cbe029b174173ef927ac70Christian König
811d0c357a9733238985cbe029b174173ef927ac70Christian König   if (scrn->last_ust && scrn->last_msc && (ust > scrn->last_ust) && (msc > scrn->last_msc))
821d0c357a9733238985cbe029b174173ef927ac70Christian König      scrn->ns_frame = (ust - scrn->last_ust) / (msc - scrn->last_msc);
831d0c357a9733238985cbe029b174173ef927ac70Christian König
841d0c357a9733238985cbe029b174173ef927ac70Christian König   if (scrn->next_msc && (scrn->next_msc < msc))
851d0c357a9733238985cbe029b174173ef927ac70Christian König      scrn->skew_msc++;
861d0c357a9733238985cbe029b174173ef927ac70Christian König
871d0c357a9733238985cbe029b174173ef927ac70Christian König   scrn->last_ust = ust;
881d0c357a9733238985cbe029b174173ef927ac70Christian König   scrn->last_msc = msc;
891d0c357a9733238985cbe029b174173ef927ac70Christian König}
901d0c357a9733238985cbe029b174173ef927ac70Christian König
911d0c357a9733238985cbe029b174173ef927ac70Christian Königstatic xcb_dri2_get_buffers_reply_t*
921d0c357a9733238985cbe029b174173ef927ac70Christian Königvl_dri2_get_flush_reply(struct vl_dri_screen *scrn)
931d0c357a9733238985cbe029b174173ef927ac70Christian König{
941d0c357a9733238985cbe029b174173ef927ac70Christian König   xcb_dri2_wait_sbc_reply_t *wait_sbc_reply;
951d0c357a9733238985cbe029b174173ef927ac70Christian König
961d0c357a9733238985cbe029b174173ef927ac70Christian König   assert(scrn);
971d0c357a9733238985cbe029b174173ef927ac70Christian König
981d0c357a9733238985cbe029b174173ef927ac70Christian König   if (!scrn->flushed)
991d0c357a9733238985cbe029b174173ef927ac70Christian König      return NULL;
1001d0c357a9733238985cbe029b174173ef927ac70Christian König
1011d0c357a9733238985cbe029b174173ef927ac70Christian König   scrn->flushed = false;
1021d0c357a9733238985cbe029b174173ef927ac70Christian König
1031d0c357a9733238985cbe029b174173ef927ac70Christian König   free(xcb_dri2_swap_buffers_reply(scrn->conn, scrn->swap_cookie, NULL));
1041d0c357a9733238985cbe029b174173ef927ac70Christian König
1051d0c357a9733238985cbe029b174173ef927ac70Christian König   wait_sbc_reply = xcb_dri2_wait_sbc_reply(scrn->conn, scrn->wait_cookie, NULL);
1061d0c357a9733238985cbe029b174173ef927ac70Christian König   if (!wait_sbc_reply)
1071d0c357a9733238985cbe029b174173ef927ac70Christian König      return NULL;
1081d0c357a9733238985cbe029b174173ef927ac70Christian König   vl_dri2_handle_stamps(scrn, wait_sbc_reply->ust_hi, wait_sbc_reply->ust_lo,
1091d0c357a9733238985cbe029b174173ef927ac70Christian König                         wait_sbc_reply->msc_hi, wait_sbc_reply->msc_lo);
1101d0c357a9733238985cbe029b174173ef927ac70Christian König   free(wait_sbc_reply);
1111d0c357a9733238985cbe029b174173ef927ac70Christian König
1121d0c357a9733238985cbe029b174173ef927ac70Christian König   return xcb_dri2_get_buffers_reply(scrn->conn, scrn->buffers_cookie, NULL);
1131d0c357a9733238985cbe029b174173ef927ac70Christian König}
1141d0c357a9733238985cbe029b174173ef927ac70Christian König
1151d0c357a9733238985cbe029b174173ef927ac70Christian Königstatic void
116404fb63b4649f58fce443615e49337d42b8ddeceYounes Mantonvl_dri2_flush_frontbuffer(struct pipe_screen *screen,
117772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König                          struct pipe_resource *resource,
118772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König                          unsigned level, unsigned layer,
119772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König                          void *context_private)
120404fb63b4649f58fce443615e49337d42b8ddeceYounes Manton{
12180b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   struct vl_dri_screen *scrn = (struct vl_dri_screen*)context_private;
1221d0c357a9733238985cbe029b174173ef927ac70Christian König   uint32_t msc_hi, msc_lo;
123404fb63b4649f58fce443615e49337d42b8ddeceYounes Manton
124404fb63b4649f58fce443615e49337d42b8ddeceYounes Manton   assert(screen);
125772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König   assert(resource);
126404fb63b4649f58fce443615e49337d42b8ddeceYounes Manton   assert(context_private);
127404fb63b4649f58fce443615e49337d42b8ddeceYounes Manton
1281d0c357a9733238985cbe029b174173ef927ac70Christian König   free(vl_dri2_get_flush_reply(scrn));
1291d0c357a9733238985cbe029b174173ef927ac70Christian König
1301d0c357a9733238985cbe029b174173ef927ac70Christian König   msc_hi = scrn->next_msc >> 32;
1311d0c357a9733238985cbe029b174173ef927ac70Christian König   msc_lo = scrn->next_msc & 0xFFFFFFFF;
13291ac681113b05f8fe4dff51c3b80f967ac05c867Christian König
1331d0c357a9733238985cbe029b174173ef927ac70Christian König   scrn->swap_cookie = xcb_dri2_swap_buffers_unchecked(scrn->conn, scrn->drawable, msc_hi, msc_lo, 0, 0, 0, 0);
13491ac681113b05f8fe4dff51c3b80f967ac05c867Christian König   scrn->wait_cookie = xcb_dri2_wait_sbc_unchecked(scrn->conn, scrn->drawable, 0, 0);
13591ac681113b05f8fe4dff51c3b80f967ac05c867Christian König   scrn->buffers_cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, scrn->drawable, 1, 1, attachments);
136c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König
1371d0c357a9733238985cbe029b174173ef927ac70Christian König   scrn->flushed = true;
138c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   scrn->current_buffer = !scrn->current_buffer;
13980b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König}
14080b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
14180b40a4841a4af93a1bc93e4746a418a9cee0a55Christian Königstatic void
14280b40a4841a4af93a1bc93e4746a418a9cee0a55Christian Königvl_dri2_destroy_drawable(struct vl_dri_screen *scrn)
14380b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König{
14480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_void_cookie_t destroy_cookie;
14580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   if (scrn->drawable) {
1461d0c357a9733238985cbe029b174173ef927ac70Christian König      free(vl_dri2_get_flush_reply(scrn));
14780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König      destroy_cookie = xcb_dri2_destroy_drawable_checked(scrn->conn, scrn->drawable);
14880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König      /* ignore any error here, since the drawable can be destroyed long ago */
14980b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König      free(xcb_request_check(scrn->conn, destroy_cookie));
15080b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   }
151404fb63b4649f58fce443615e49337d42b8ddeceYounes Manton}
152404fb63b4649f58fce443615e49337d42b8ddeceYounes Manton
1531d0c357a9733238985cbe029b174173ef927ac70Christian Königstatic void
1541d0c357a9733238985cbe029b174173ef927ac70Christian Königvl_dri2_set_drawable(struct vl_dri_screen *scrn, Drawable drawable)
1551d0c357a9733238985cbe029b174173ef927ac70Christian König{
1561d0c357a9733238985cbe029b174173ef927ac70Christian König   assert(scrn);
1571d0c357a9733238985cbe029b174173ef927ac70Christian König   assert(drawable);
1581d0c357a9733238985cbe029b174173ef927ac70Christian König
1591d0c357a9733238985cbe029b174173ef927ac70Christian König   if (scrn->drawable == drawable)
1601d0c357a9733238985cbe029b174173ef927ac70Christian König      return;
1611d0c357a9733238985cbe029b174173ef927ac70Christian König
1621d0c357a9733238985cbe029b174173ef927ac70Christian König   vl_dri2_destroy_drawable(scrn);
1631d0c357a9733238985cbe029b174173ef927ac70Christian König
1641d0c357a9733238985cbe029b174173ef927ac70Christian König   xcb_dri2_create_drawable(scrn->conn, drawable);
1651d0c357a9733238985cbe029b174173ef927ac70Christian König   scrn->current_buffer = false;
1661d0c357a9733238985cbe029b174173ef927ac70Christian König   vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]);
1671d0c357a9733238985cbe029b174173ef927ac70Christian König   vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]);
1681d0c357a9733238985cbe029b174173ef927ac70Christian König   scrn->drawable = drawable;
1691d0c357a9733238985cbe029b174173ef927ac70Christian König}
1701d0c357a9733238985cbe029b174173ef927ac70Christian König
1711448e829e86981e6144410ba6a3d0f16357fb2b3Christian Königstruct pipe_resource*
1721448e829e86981e6144410ba6a3d0f16357fb2b3Christian Königvl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable)
173e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton{
17480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
17580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
17663d53063f7a0b1351fa361f2176b17819eaca36cChristian König   struct winsys_handle dri2_handle;
1771448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   struct pipe_resource template, *tex;
17880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
17980b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_dri2_get_buffers_reply_t *reply;
18063d53063f7a0b1351fa361f2176b17819eaca36cChristian König   xcb_dri2_dri2_buffer_t *buffers, *back_left;
18163d53063f7a0b1351fa361f2176b17819eaca36cChristian König
18263d53063f7a0b1351fa361f2176b17819eaca36cChristian König   unsigned i;
18380b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
18480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   assert(scrn);
18580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
1861d0c357a9733238985cbe029b174173ef927ac70Christian König   vl_dri2_set_drawable(scrn, drawable);
1871d0c357a9733238985cbe029b174173ef927ac70Christian König   reply = vl_dri2_get_flush_reply(scrn);
1881d0c357a9733238985cbe029b174173ef927ac70Christian König   if (!reply) {
1891d0c357a9733238985cbe029b174173ef927ac70Christian König      xcb_dri2_get_buffers_cookie_t cookie;
1901d0c357a9733238985cbe029b174173ef927ac70Christian König      cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, drawable, 1, 1, attachments);
1911d0c357a9733238985cbe029b174173ef927ac70Christian König      reply = xcb_dri2_get_buffers_reply(scrn->conn, cookie, NULL);
192404fb63b4649f58fce443615e49337d42b8ddeceYounes Manton   }
19380b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   if (!reply)
19480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König      return NULL;
1951448e829e86981e6144410ba6a3d0f16357fb2b3Christian König
19680b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   buffers = xcb_dri2_get_buffers_buffers(reply);
19780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   if (!buffers)  {
19880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König      free(reply);
1991448e829e86981e6144410ba6a3d0f16357fb2b3Christian König      return NULL;
20080b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   }
20180b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
20263d53063f7a0b1351fa361f2176b17819eaca36cChristian König   for (i = 0; i < reply->count; ++i) {
20363d53063f7a0b1351fa361f2176b17819eaca36cChristian König      if (buffers[i].attachment == XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT) {
20463d53063f7a0b1351fa361f2176b17819eaca36cChristian König         back_left = &buffers[i];
20563d53063f7a0b1351fa361f2176b17819eaca36cChristian König         break;
20663d53063f7a0b1351fa361f2176b17819eaca36cChristian König      }
20763d53063f7a0b1351fa361f2176b17819eaca36cChristian König   }
20863d53063f7a0b1351fa361f2176b17819eaca36cChristian König
20963d53063f7a0b1351fa361f2176b17819eaca36cChristian König   if (i == reply->count) {
21063d53063f7a0b1351fa361f2176b17819eaca36cChristian König      free(reply);
21163d53063f7a0b1351fa361f2176b17819eaca36cChristian König      return NULL;
21263d53063f7a0b1351fa361f2176b17819eaca36cChristian König   }
21363d53063f7a0b1351fa361f2176b17819eaca36cChristian König
214c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   if (reply->width != scrn->width || reply->height != scrn->height) {
215c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König      vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]);
216c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König      vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]);
217c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König      scrn->width = reply->width;
218c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König      scrn->height = reply->height;
219c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König
22063d53063f7a0b1351fa361f2176b17819eaca36cChristian König   } else if (back_left->name != scrn->buffer_names[scrn->current_buffer]) {
221c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König      vl_compositor_reset_dirty_area(&scrn->dirty_areas[scrn->current_buffer]);
22263d53063f7a0b1351fa361f2176b17819eaca36cChristian König      scrn->buffer_names[scrn->current_buffer] = back_left->name;
223c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   }
224c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König
22563d53063f7a0b1351fa361f2176b17819eaca36cChristian König   memset(&dri2_handle, 0, sizeof(dri2_handle));
22663d53063f7a0b1351fa361f2176b17819eaca36cChristian König   dri2_handle.type = DRM_API_HANDLE_TYPE_SHARED;
22763d53063f7a0b1351fa361f2176b17819eaca36cChristian König   dri2_handle.handle = back_left->name;
22863d53063f7a0b1351fa361f2176b17819eaca36cChristian König   dri2_handle.stride = back_left->pitch;
2291448e829e86981e6144410ba6a3d0f16357fb2b3Christian König
2301448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   memset(&template, 0, sizeof(template));
2311448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   template.target = PIPE_TEXTURE_2D;
2321448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
2331448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   template.last_level = 0;
23480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   template.width0 = reply->width;
23580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   template.height0 = reply->height;
2361448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   template.depth0 = 1;
23780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   template.array_size = 1;
2381448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   template.usage = PIPE_USAGE_STATIC;
2391448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   template.bind = PIPE_BIND_RENDER_TARGET;
2401448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   template.flags = 0;
2411448e829e86981e6144410ba6a3d0f16357fb2b3Christian König
24263d53063f7a0b1351fa361f2176b17819eaca36cChristian König   tex = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &template, &dri2_handle);
24380b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   free(reply);
2441448e829e86981e6144410ba6a3d0f16357fb2b3Christian König
2451448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   return tex;
2466414952efe3b53fd33d73d592da74975a1075330Younes Manton}
2476414952efe3b53fd33d73d592da74975a1075330Younes Manton
248c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian Königstruct u_rect *
249c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian Königvl_screen_get_dirty_area(struct vl_screen *vscreen)
250c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König{
251c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
252c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   assert(scrn);
253c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   return &scrn->dirty_areas[scrn->current_buffer];
254c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König}
255c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König
2561d0c357a9733238985cbe029b174173ef927ac70Christian Königuint64_t
2571d0c357a9733238985cbe029b174173ef927ac70Christian Königvl_screen_get_timestamp(struct vl_screen *vscreen, Drawable drawable)
2581d0c357a9733238985cbe029b174173ef927ac70Christian König{
2591d0c357a9733238985cbe029b174173ef927ac70Christian König   struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
2601d0c357a9733238985cbe029b174173ef927ac70Christian König   xcb_dri2_get_msc_cookie_t cookie;
2611d0c357a9733238985cbe029b174173ef927ac70Christian König   xcb_dri2_get_msc_reply_t *reply;
2621d0c357a9733238985cbe029b174173ef927ac70Christian König
2631d0c357a9733238985cbe029b174173ef927ac70Christian König   assert(scrn);
2641d0c357a9733238985cbe029b174173ef927ac70Christian König
2651d0c357a9733238985cbe029b174173ef927ac70Christian König   vl_dri2_set_drawable(scrn, drawable);
2661d0c357a9733238985cbe029b174173ef927ac70Christian König   if (!scrn->last_ust) {
2671d0c357a9733238985cbe029b174173ef927ac70Christian König      cookie = xcb_dri2_get_msc_unchecked(scrn->conn, drawable);
2681d0c357a9733238985cbe029b174173ef927ac70Christian König      reply = xcb_dri2_get_msc_reply(scrn->conn, cookie, NULL);
2691d0c357a9733238985cbe029b174173ef927ac70Christian König
2701d0c357a9733238985cbe029b174173ef927ac70Christian König      if (reply) {
2711d0c357a9733238985cbe029b174173ef927ac70Christian König         vl_dri2_handle_stamps(scrn, reply->ust_hi, reply->ust_lo,
2721d0c357a9733238985cbe029b174173ef927ac70Christian König                               reply->msc_hi, reply->msc_lo);
2731d0c357a9733238985cbe029b174173ef927ac70Christian König         free(reply);
2741d0c357a9733238985cbe029b174173ef927ac70Christian König      }
2751d0c357a9733238985cbe029b174173ef927ac70Christian König   }
2761d0c357a9733238985cbe029b174173ef927ac70Christian König   return scrn->last_ust;
2771d0c357a9733238985cbe029b174173ef927ac70Christian König}
2781d0c357a9733238985cbe029b174173ef927ac70Christian König
2791d0c357a9733238985cbe029b174173ef927ac70Christian Königvoid
2801d0c357a9733238985cbe029b174173ef927ac70Christian Königvl_screen_set_next_timestamp(struct vl_screen *vscreen, uint64_t stamp)
2811d0c357a9733238985cbe029b174173ef927ac70Christian König{
2821d0c357a9733238985cbe029b174173ef927ac70Christian König   struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
2831d0c357a9733238985cbe029b174173ef927ac70Christian König   assert(scrn);
2841d0c357a9733238985cbe029b174173ef927ac70Christian König   if (stamp && scrn->last_ust && scrn->ns_frame && scrn->last_msc)
2851d0c357a9733238985cbe029b174173ef927ac70Christian König      scrn->next_msc = ((int64_t)stamp - scrn->last_ust) / scrn->ns_frame + scrn->last_msc + scrn->skew_msc;
2861d0c357a9733238985cbe029b174173ef927ac70Christian König   else
2871d0c357a9733238985cbe029b174173ef927ac70Christian König      scrn->next_msc = 0;
2881d0c357a9733238985cbe029b174173ef927ac70Christian König}
2891d0c357a9733238985cbe029b174173ef927ac70Christian König
2906414952efe3b53fd33d73d592da74975a1075330Younes Mantonvoid*
2911448e829e86981e6144410ba6a3d0f16357fb2b3Christian Königvl_screen_get_private(struct vl_screen *vscreen)
2926414952efe3b53fd33d73d592da74975a1075330Younes Manton{
2931448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   return vscreen;
2946414952efe3b53fd33d73d592da74975a1075330Younes Manton}
2956414952efe3b53fd33d73d592da74975a1075330Younes Manton
296e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Mantonstruct vl_screen*
297e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Mantonvl_screen_create(Display *display, int screen)
298e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton{
29980b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   struct vl_dri_screen *scrn;
30080b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   const xcb_query_extension_reply_t *extension;
30180b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_dri2_query_version_cookie_t dri2_query_cookie;
30280b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_dri2_query_version_reply_t *dri2_query = NULL;
30380b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_dri2_connect_cookie_t connect_cookie;
30480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_dri2_connect_reply_t *connect = NULL;
30580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_dri2_authenticate_cookie_t authenticate_cookie;
30680b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_dri2_authenticate_reply_t *authenticate = NULL;
30780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_screen_iterator_t s;
30880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_generic_error_t *error = NULL;
30980b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   char *device_name;
310fc0a5e21d77ae2f082fd19dd2295e84f6fb7bd3bChristian König   int fd, device_name_length;
311e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
31280b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   drm_magic_t magic;
31380b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
314e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   assert(display);
315e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
31680b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   scrn = CALLOC_STRUCT(vl_dri_screen);
31780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   if (!scrn)
31880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König      return NULL;
31980b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
32080b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   scrn->conn = XGetXCBConnection(display);
32180b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   if (!scrn->conn)
32280b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König      goto free_screen;
32380b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
32480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   xcb_prefetch_extension_data(scrn->conn, &xcb_dri2_id);
32580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
32680b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   extension = xcb_get_extension_data(scrn->conn, &xcb_dri2_id);
32780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   if (!(extension && extension->present))
32880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König      goto free_screen;
32980b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
33080b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   dri2_query_cookie = xcb_dri2_query_version (scrn->conn, XCB_DRI2_MAJOR_VERSION, XCB_DRI2_MINOR_VERSION);
33180b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   dri2_query = xcb_dri2_query_version_reply (scrn->conn, dri2_query_cookie, &error);
33266480c0f565eb5dc7ae4a5dc792341f6886f481aChristian König   if (dri2_query == NULL || error != NULL || dri2_query->minor_version < 2)
33380b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König      goto free_screen;
3346414952efe3b53fd33d73d592da74975a1075330Younes Manton
33580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   s = xcb_setup_roots_iterator(xcb_get_setup(scrn->conn));
33680b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   connect_cookie = xcb_dri2_connect_unchecked(scrn->conn, s.data->root, XCB_DRI2_DRIVER_TYPE_DRI);
33780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   connect = xcb_dri2_connect_reply(scrn->conn, connect_cookie, NULL);
33880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   if (connect == NULL || connect->driver_name_length + connect->device_name_length == 0)
339b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König      goto free_screen;
340b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König
341fc0a5e21d77ae2f082fd19dd2295e84f6fb7bd3bChristian König   device_name_length = xcb_dri2_connect_device_name_length(connect);
342fc0a5e21d77ae2f082fd19dd2295e84f6fb7bd3bChristian König   device_name = CALLOC(1, device_name_length);
343fc0a5e21d77ae2f082fd19dd2295e84f6fb7bd3bChristian König   memcpy(device_name, xcb_dri2_connect_device_name(connect), device_name_length);
344fc0a5e21d77ae2f082fd19dd2295e84f6fb7bd3bChristian König   device_name[device_name_length] = 0;
34580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   fd = open(device_name, O_RDWR);
34680b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   free(device_name);
347b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König
348b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König   if (fd < 0)
349b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König      goto free_screen;
350b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König
351b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König   if (drmGetMagic(fd, &magic))
352b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König      goto free_screen;
353e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
35480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   authenticate_cookie = xcb_dri2_authenticate_unchecked(scrn->conn, s.data->root, magic);
35580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   authenticate = xcb_dri2_authenticate_reply(scrn->conn, authenticate_cookie, NULL);
356b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König
35780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   if (authenticate == NULL || !authenticate->authenticated)
35880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König      goto free_screen;
359e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
36080b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   scrn->base.pscreen = driver_descriptor.create_screen(fd);
36180b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   if (!scrn->base.pscreen)
362b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian König      goto free_screen;
363e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
36480b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer;
365c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]);
366c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]);
3676414952efe3b53fd33d73d592da74975a1075330Younes Manton
36880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   free(dri2_query);
36980b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   free(connect);
37080b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   free(authenticate);
371e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
37280b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   return &scrn->base;
3736414952efe3b53fd33d73d592da74975a1075330Younes Manton
374b34c35a5243e0f4a23721891dbbccff8863b7d4cChristian Königfree_screen:
37580b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   FREE(scrn);
37680b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
37780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   free(dri2_query);
37880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   free(connect);
37980b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   free(authenticate);
38080b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   free(error);
38180b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König
3826414952efe3b53fd33d73d592da74975a1075330Younes Manton   return NULL;
383e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton}
384e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
385e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Mantonvoid vl_screen_destroy(struct vl_screen *vscreen)
386e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton{
38780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
388e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
389e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   assert(vscreen);
390e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
39191ac681113b05f8fe4dff51c3b80f967ac05c867Christian König   if (scrn->flushed) {
39291ac681113b05f8fe4dff51c3b80f967ac05c867Christian König      free(xcb_dri2_swap_buffers_reply(scrn->conn, scrn->swap_cookie, NULL));
39391ac681113b05f8fe4dff51c3b80f967ac05c867Christian König      free(xcb_dri2_wait_sbc_reply(scrn->conn, scrn->wait_cookie, NULL));
39491ac681113b05f8fe4dff51c3b80f967ac05c867Christian König      free(xcb_dri2_get_buffers_reply(scrn->conn, scrn->buffers_cookie, NULL));
39591ac681113b05f8fe4dff51c3b80f967ac05c867Christian König   }
39691ac681113b05f8fe4dff51c3b80f967ac05c867Christian König
39780b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   vl_dri2_destroy_drawable(scrn);
39880b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   scrn->base.pscreen->destroy(scrn->base.pscreen);
39980b40a4841a4af93a1bc93e4746a418a9cee0a55Christian König   FREE(scrn);
400e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton}
401