native_dri2.c revision d63b2622f1c47d6f82fe96c9f1b749d908883a23
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/*
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * Mesa 3-D graphics library
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * Version:  7.8
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner *
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * Permission is hereby granted, free of charge, to any person obtaining a
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * copy of this software and associated documentation files (the "Software"),
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * to deal in the Software without restriction, including without limitation
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * the rights to use, copy, modify, merge, publish, distribute, sublicense,
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * and/or sell copies of the Software, and to permit persons to whom the
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * Software is furnished to do so, subject to the following conditions:
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * The above copyright notice and this permission notice shall be included
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * in all copies or substantial portions of the Software.
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *
1794deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20161755a09898c95d21bfff33707da9ca41cd53c5John McCall * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22409c99edb8b623403fade6f3a9e9c86acda74455Anders Carlsson * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * DEALINGS IN THE SOFTWARE.
24525a05093a4816af961fe2bc6b8a81c17e2e26c2Chris Lattner */
253b8d116703db8018f855cbb4733ace426422623bNate Begeman
26b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar#include "util/u_memory.h"
27c5ae899b4bbf65488445316c63168079177db0edSteve Naroff#include "util/u_math.h"
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "util/u_format.h"
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "util/u_inlines.h"
30590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner#include "util/u_hash_table.h"
31c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson#include "pipe/p_compiler.h"
32c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "pipe/p_screen.h"
33c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "pipe/p_context.h"
34c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "pipe/p_state.h"
358e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor#include "state_tracker/drm_driver.h"
36c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "egllog.h"
3756ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff
38409c99edb8b623403fade6f3a9e9c86acda74455Anders Carlsson#include "native_x11.h"
3988a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor#include "x11_screen.h"
4088a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor
41833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall#ifdef GLX_DIRECT_RENDERING
42d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
4388a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregorenum dri2_surface_type {
447ab9d574d27ecee1f130e5755aa403e5ab529b6bAnders Carlsson   DRI2_SURFACE_TYPE_WINDOW,
457ab9d574d27ecee1f130e5755aa403e5ab529b6bAnders Carlsson   DRI2_SURFACE_TYPE_PIXMAP,
467ab9d574d27ecee1f130e5755aa403e5ab529b6bAnders Carlsson};
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstruct dri2_display {
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   struct native_display base;
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   Display *dpy;
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   boolean own_dpy;
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
53898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   struct native_event_handler *event_handler;
54bef0efd11bc4430a3ee437a3213cec5c18af855aChris Lattner
559ea62768fca25d829d80199cf4f8cf0f4dd39251Douglas Gregor   struct x11_screen *xscr;
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   int xscr_number;
57898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   const char *dri_driver;
58898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   int dri_major, dri_minor;
59898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   struct dri2_config *configs;
61898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   int num_configs;
62898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
63898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   struct util_hash_table *surfaces;
64898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor};
65b3eef68111ffc220e449be96da1747998c057790Douglas Gregor
66898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorstruct dri2_surface {
67898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   struct native_surface base;
68898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   Drawable drawable;
690b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor   enum dri2_surface_type type;
700b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor   enum pipe_format color_format;
710b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor   struct dri2_display *dri2dpy;
721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7343d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor   unsigned int server_stamp;
7443d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor   unsigned int client_stamp;
7543d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor   int width, height;
7643d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor   struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
7743d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor   uint valid_mask;
7843d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor
7943d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor   boolean have_back, have_fake;
8043d9d9243329b1b75d1a6efdad9f16d6fb386b8eDouglas Gregor
811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   struct x11_drawable_buffer *last_xbufs;
82f7c2aa0b049272d8f318988c1965760dcb852578Douglas Gregor   int last_num_xbufs;
831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
849d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor
859d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregorstruct dri2_config {
869d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor   struct native_config base;
879d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor};
889d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor
899d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregorstatic INLINE struct dri2_display *
909d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregordri2_display(const struct native_display *ndpy)
91905d11d53aeb6b26744f44fedc2b2820c7a62df6Douglas Gregor{
928320aaaa01d931aa234fc3bce05b399ef41898d5Daniel Dunbar   return (struct dri2_display *) ndpy;
93f7c2aa0b049272d8f318988c1965760dcb852578Douglas Gregor}
941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
959d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregorstatic INLINE struct dri2_surface *
9677ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenekdri2_surface(const struct native_surface *nsurf)
97898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor{
98898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   return (struct dri2_surface *) nsurf;
99898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor}
1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
101898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorstatic INLINE struct dri2_config *
102898574e7496ba8fd76290079d3a9d06954992734Douglas Gregordri2_config(const struct native_config *nconf)
103898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor{
104898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   return (struct dri2_config *) nconf;
105898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor}
1060b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
1070b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor/**
1080b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor * Process the buffers returned by the server.
109898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor */
110898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorstatic void
111898574e7496ba8fd76290079d3a9d06954992734Douglas Gregordri2_surface_process_drawable_buffers(struct native_surface *nsurf,
112898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor                                      struct x11_drawable_buffer *xbufs,
113898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor                                      int num_xbufs)
114898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor{
1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   struct dri2_surface *dri2surf = dri2_surface(nsurf);
116898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   struct dri2_display *dri2dpy = dri2surf->dri2dpy;
117898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   struct pipe_resource templ;
118898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   struct winsys_handle whandle;
119898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   uint valid_mask;
120898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   int i;
121898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1220b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor   /* free the old textures */
1230b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor   for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
1240b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor      pipe_resource_reference(&dri2surf->textures[i], NULL);
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   dri2surf->valid_mask = 0x0;
1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   dri2surf->have_back = FALSE;
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   dri2surf->have_fake = FALSE;
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   if (!xbufs)
1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return;
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   memset(&templ, 0, sizeof(templ));
134026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner   templ.target = PIPE_TEXTURE_2D;
135026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner   templ.last_level = 0;
136026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner   templ.width0 = dri2surf->width;
137026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner   templ.height0 = dri2surf->height;
138026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner   templ.depth0 = 1;
139df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump   templ.format = dri2surf->color_format;
1401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   templ.bind = PIPE_BIND_RENDER_TARGET;
1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   valid_mask = 0x0;
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   for (i = 0; i < num_xbufs; i++) {
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      struct x11_drawable_buffer *xbuf = &xbufs[i];
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      const char *desc;
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      enum native_attachment natt;
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      switch (xbuf->attachment) {
1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      case DRI2BufferFrontLeft:
15008ad47cbd1f81fcb31dbc731c13b885a07e12704Bill Wendling         natt = NATIVE_ATTACHMENT_FRONT_LEFT;
15176458501a8963fa11b91c9337a487de6871169b4Sebastian Redl         desc = "DRI2 Front Buffer";
1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         break;
1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      case DRI2BufferFakeFrontLeft:
1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         natt = NATIVE_ATTACHMENT_FRONT_LEFT;
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         desc = "DRI2 Fake Front Buffer";
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         dri2surf->have_fake = TRUE;
157fec0b49c3fa621fbf63e420f3d54a5bb3a0265d2Steve Naroff         break;
15886f194083504938df72135b5b66bf0c5cafd9498Douglas Gregor      case DRI2BufferBackLeft:
1592514a309204341798f96912ce7a90841bea59727Fariborz Jahanian         natt = NATIVE_ATTACHMENT_BACK_LEFT;
160e9ff443040cb571ae2c5c2626c4dc9a9a812d84aFariborz Jahanian         desc = "DRI2 Back Buffer";
161e873fb74219f48407ae0b8fa083aa7f0b6ff1427Douglas Gregor         dri2surf->have_back = TRUE;
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         break;
16328be73f74c9e241a23ea24fe5756623de6bf1084Chris Lattner      default:
16453202857c60214d80950a975e6e52aebf30bd16aEli Friedman         desc = NULL;
16553202857c60214d80950a975e6e52aebf30bd16aEli Friedman         break;
16653202857c60214d80950a975e6e52aebf30bd16aEli Friedman      }
1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      if (!desc || dri2surf->textures[natt]) {
1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         if (!desc)
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         else
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            _eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
17344e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar         continue;
17444e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar      }
17544e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar
17644e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar      memset(&whandle, 0, sizeof(whandle));
1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      whandle.stride = xbuf->pitch;
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      whandle.handle = xbuf->name;
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      dri2surf->textures[natt] = dri2dpy->base.screen->resource_from_handle(
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         dri2dpy->base.screen, &templ, &whandle);
181fec0b49c3fa621fbf63e420f3d54a5bb3a0265d2Steve Naroff      if (dri2surf->textures[natt])
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         valid_mask |= 1 << natt;
183ca354faa7e9b99af17070c82b9662a5fca76422cChris Lattner   }
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   dri2surf->valid_mask = valid_mask;
1864f6a7d7ead09b439216c32f2de806a998aeb222aSteve Naroff}
1875daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian
188ba8d2d684e74a20bef03828c21c991d222c7e9e5Fariborz Jahanian/**
18986f194083504938df72135b5b66bf0c5cafd9498Douglas Gregor * Get the buffers from the server.
1902514a309204341798f96912ce7a90841bea59727Fariborz Jahanian */
191e9ff443040cb571ae2c5c2626c4dc9a9a812d84aFariborz Jahanianstatic void
192e873fb74219f48407ae0b8fa083aa7f0b6ff1427Douglas Gregordri2_surface_get_buffers(struct native_surface *nsurf, uint buffer_mask)
1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer{
19444e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar   struct dri2_surface *dri2surf = dri2_surface(nsurf);
19544e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar   struct dri2_display *dri2dpy = dri2surf->dri2dpy;
1961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS * 2];
19733bbbc5ec8269bc2cde5b84f970fa49319a30267Douglas Gregor   int num_ins, num_outs, att;
19833bbbc5ec8269bc2cde5b84f970fa49319a30267Douglas Gregor   struct x11_drawable_buffer *xbufs;
19933bbbc5ec8269bc2cde5b84f970fa49319a30267Douglas Gregor   uint bpp = util_format_get_blocksizebits(dri2surf->color_format);
2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   boolean with_format = FALSE; /* never ask for depth/stencil */
20138d068e8f13a119b89a3b8b0f79f35cab1ffd09aAnders Carlsson
20238d068e8f13a119b89a3b8b0f79f35cab1ffd09aAnders Carlsson   /* We must get the front on servers which doesn't support with format
20338d068e8f13a119b89a3b8b0f79f35cab1ffd09aAnders Carlsson    * due to a silly bug in core dri2. You can't copy to/from a buffer
2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    * that you haven't requested and you recive BadValue errors */
205093802675b1548f2a5f44c29938d65cce00d58bbAnders Carlsson   if (dri2surf->dri2dpy->dri_minor < 1) {
206093802675b1548f2a5f44c29938d65cce00d58bbAnders Carlsson      with_format = FALSE;
207c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      buffer_mask |= (1 << NATIVE_ATTACHMENT_FRONT_LEFT);
2082b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner   }
2092b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner
2102b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner   /* prepare the attachments */
2112b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner   num_ins = 0;
2122b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner   for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
213c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      if (native_attachment_mask_test(buffer_mask, att)) {
2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         unsigned int dri2att;
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         switch (att) {
2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         case NATIVE_ATTACHMENT_FRONT_LEFT:
218590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner            dri2att = DRI2BufferFrontLeft;
219590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner            break;
2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         case NATIVE_ATTACHMENT_BACK_LEFT:
221590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner            dri2att = DRI2BufferBackLeft;
2228070a8497c0fb3e6f70a557f788405d8945b1208Daniel Dunbar            break;
223590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner         case NATIVE_ATTACHMENT_FRONT_RIGHT:
2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            dri2att = DRI2BufferFrontRight;
225c9e8f606787b0bc0c3b08e566b87cc1751694168Eli Friedman            break;
226c9e8f606787b0bc0c3b08e566b87cc1751694168Eli Friedman         case NATIVE_ATTACHMENT_BACK_RIGHT:
227c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt            dri2att = DRI2BufferBackRight;
2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            break;
22994deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson         default:
23094deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson            assert(0);
2312d6744ff04c1690a1485178d550d2fab84a0270bDaniel Dunbar            dri2att = 0;
23294deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson            break;
2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump         }
23494deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson
23594deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson         dri2atts[num_ins++] = dri2att;
23694deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson         if (with_format)
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            dri2atts[num_ins++] = bpp;
23894deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson      }
23994deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson   }
24094deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson   if (with_format)
24194deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson      num_ins /= 2;
24294deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson
24394deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson   xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable,
24494deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson                                    &dri2surf->width, &dri2surf->height,
24594deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson                                    dri2atts, with_format, num_ins, &num_outs);
24694deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson
24794deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson   /* we should be able to do better... */
24894deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson   if (xbufs && dri2surf->last_num_xbufs == num_outs &&
2491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump       memcmp(dri2surf->last_xbufs, xbufs, sizeof(*xbufs) * num_outs) == 0) {
25094deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson      FREE(xbufs);
251e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara      dri2surf->client_stamp = dri2surf->server_stamp;
252e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara      return;
253e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara   }
254e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara
255e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara   dri2_surface_process_drawable_buffers(&dri2surf->base, xbufs, num_outs);
256e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara
257e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara   dri2surf->server_stamp++;
258e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara   dri2surf->client_stamp = dri2surf->server_stamp;
259e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara
26094deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson   if (dri2surf->last_xbufs)
26194deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson      FREE(dri2surf->last_xbufs);
2626ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner   dri2surf->last_xbufs = xbufs;
263019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner   dri2surf->last_num_xbufs = num_outs;
264019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner}
265019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner
2665b45d4ef1ea3f04ec863daf8aa29be6c6e021750Anders Carlsson/**
2675b45d4ef1ea3f04ec863daf8aa29be6c6e021750Anders Carlsson * Update the buffers of the surface.  This is a slow function due to the
268cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall * round-trip to the server.
269cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall */
270cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCallstatic boolean
271cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCalldri2_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
272cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall{
2736ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner   struct dri2_surface *dri2surf = dri2_surface(nsurf);
27445b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner
27545b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner   dri2_surface_get_buffers(&dri2surf->base, buffer_mask);
276c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson
2776ddf4784a22b994b954ed74c6061d4603d474639Fariborz Jahanian   return ((dri2surf->valid_mask & buffer_mask) == buffer_mask);
278c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt}
2796ddf4784a22b994b954ed74c6061d4603d474639Fariborz Jahanian
2806ddf4784a22b994b954ed74c6061d4603d474639Fariborz Jahanian/**
281393c247fe025ccb5f914e37e948192ea86faef8cFariborz Jahanian * Return TRUE if the surface receives DRI2_InvalidateBuffers events.
282c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt */
28351fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlssonstatic INLINE boolean
28451fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlssondri2_surface_receive_events(struct native_surface *nsurf)
28551fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson{
28651fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson   struct dri2_surface *dri2surf = dri2_surface(nsurf);
287b2f295c8050fb8c141bf2cf38eed0a56e99d0092Eli Friedman   return (dri2surf->dri2dpy->dri_minor >= 3);
288b2f295c8050fb8c141bf2cf38eed0a56e99d0092Eli Friedman}
2891b78276a75a5a0f496a82429c1ff9604d622a76dAnders Carlsson
2901b78276a75a5a0f496a82429c1ff9604d622a76dAnders Carlssonstatic boolean
291e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnaradri2_surface_flush_frontbuffer(struct native_surface *nsurf)
292e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara{
293e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara   struct dri2_surface *dri2surf = dri2_surface(nsurf);
294ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor   struct dri2_display *dri2dpy = dri2surf->dri2dpy;
295ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor
296ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor   /* copy to real front buffer */
297ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor   if (dri2surf->have_fake)
298ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor      x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
299c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt            0, 0, dri2surf->width, dri2surf->height,
300ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor            DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
301ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor
302ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor   /* force buffers to be updated in next validation call */
303c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   if (!dri2_surface_receive_events(&dri2surf->base)) {
304ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor      dri2surf->server_stamp++;
305ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor      dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
306ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor            &dri2surf->base, dri2surf->server_stamp);
307ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor   }
308c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
309efa9b3877ef298bcb792600ac33521827e1f7fafAnders Carlsson   return TRUE;
310efa9b3877ef298bcb792600ac33521827e1f7fafAnders Carlsson}
311efa9b3877ef298bcb792600ac33521827e1f7fafAnders Carlsson
312ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregorstatic boolean
313ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregordri2_surface_swap_buffers(struct native_surface *nsurf)
314efa9b3877ef298bcb792600ac33521827e1f7fafAnders Carlsson{
31544baa8abba2a1552b6b50bf750a8750ab9da9f76Fariborz Jahanian   struct dri2_surface *dri2surf = dri2_surface(nsurf);
3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   struct dri2_display *dri2dpy = dri2surf->dri2dpy;
317102e390bcb5a1fb1a8fdbc8505e6dfd905374bbdFariborz Jahanian
3181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   /* copy to front buffer */
3194e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek   if (dri2surf->have_back)
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
3214e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek            0, 0, dri2surf->width, dri2surf->height,
3224e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek            DRI2BufferBackLeft, DRI2BufferFrontLeft);
3232b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner
32456f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner   /* and update fake front buffer */
32556f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner   if (dri2surf->have_fake)
32627c8dc06f65d7abcf6a7e7f64a7960c9a150ca01Douglas Gregor      x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
32756f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner            0, 0, dri2surf->width, dri2surf->height,
3281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
3292fc46bf1a9bc31d50f82de37c70ea257d3cded27John McCall
3302fc46bf1a9bc31d50f82de37c70ea257d3cded27John McCall   /* force buffers to be updated in next validation call */
3312fc46bf1a9bc31d50f82de37c70ea257d3cded27John McCall   if (!dri2_surface_receive_events(&dri2surf->base)) {
3322fc46bf1a9bc31d50f82de37c70ea257d3cded27John McCall      dri2surf->server_stamp++;
333ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner      dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
334ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner            &dri2surf->base, dri2surf->server_stamp);
335ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner   }
336ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner
3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   return TRUE;
3386eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor}
3396eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor
3406eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregorstatic boolean
341c302113179a1c2b1254224ea9b6f5316ceeb375cSean Huntdri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
3426eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor                      unsigned int *seq_num, struct pipe_resource **textures,
3436eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor                      int *width, int *height)
3446eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor{
3456eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor   struct dri2_surface *dri2surf = dri2_surface(nsurf);
346c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
3472f59979a7cc7929f53c9984423b0abeb83113442Douglas Gregor   if (dri2surf->server_stamp != dri2surf->client_stamp ||
3482f59979a7cc7929f53c9984423b0abeb83113442Douglas Gregor       (dri2surf->valid_mask & attachment_mask) != attachment_mask) {
3492f59979a7cc7929f53c9984423b0abeb83113442Douglas Gregor      if (!dri2_surface_update_buffers(&dri2surf->base, attachment_mask))
3502f59979a7cc7929f53c9984423b0abeb83113442Douglas Gregor         return FALSE;
3512f59979a7cc7929f53c9984423b0abeb83113442Douglas Gregor   }
3522f59979a7cc7929f53c9984423b0abeb83113442Douglas Gregor
3532f59979a7cc7929f53c9984423b0abeb83113442Douglas Gregor   if (seq_num)
3542f59979a7cc7929f53c9984423b0abeb83113442Douglas Gregor      *seq_num = dri2surf->client_stamp;
3552f59979a7cc7929f53c9984423b0abeb83113442Douglas Gregor
3562b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner   if (textures) {
3574e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek      int att;
3584e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek      for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
35956f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner         if (native_attachment_mask_test(attachment_mask, att)) {
36056f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner            struct pipe_resource *ptex = dri2surf->textures[att];
36156f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner
362ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner            textures[att] = NULL;
363ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner            pipe_resource_reference(&textures[att], ptex);
364ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner         }
3651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      }
366898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   }
367898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
368898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor   if (width)
3691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      *width = dri2surf->width;
3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   if (height)
3711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      *height = dri2surf->height;
3725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   return TRUE;
3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
3755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic void
3775549976193e34417d4474a5f4a514268ef6666c7Ted Kremenekdri2_surface_wait(struct native_surface *nsurf)
3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer{
3795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   struct dri2_surface *dri2surf = dri2_surface(nsurf);
3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   struct dri2_display *dri2dpy = dri2surf->dri2dpy;
381a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
382a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   if (dri2surf->have_fake) {
383a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
384a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor            0, 0, dri2surf->width, dri2surf->height,
385a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor            DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
386c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   }
387a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor}
388a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
389a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregorstatic void
390a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregordri2_surface_destroy(struct native_surface *nsurf)
391a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor{
392a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   struct dri2_surface *dri2surf = dri2_surface(nsurf);
393a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   int i;
394a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
395a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   if (dri2surf->last_xbufs)
396c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      FREE(dri2surf->last_xbufs);
397a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
398a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
399c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      struct pipe_resource *ptex = dri2surf->textures[i];
400a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      pipe_resource_reference(&ptex, NULL);
401a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   }
402a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
403a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   if (dri2surf->drawable) {
404c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr,
405a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor            dri2surf->drawable, FALSE);
406833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
407833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall      util_hash_table_remove(dri2surf->dri2dpy->surfaces,
408a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor            (void *) dri2surf->drawable);
409c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   }
410a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   FREE(dri2surf);
411833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall}
412833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
413a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregorstatic struct dri2_surface *
414d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCalldri2_display_create_surface(struct native_display *ndpy,
415d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                            enum dri2_surface_type type,
416d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                            Drawable drawable,
417d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                            const struct native_config *nconf)
418a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor{
419c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   struct dri2_display *dri2dpy = dri2_display(ndpy);
4205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   struct dri2_config *dri2conf = dri2_config(nconf);
4215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   struct dri2_surface *dri2surf;
4225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
423a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   dri2surf = CALLOC_STRUCT(dri2_surface);
424c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   if (!dri2surf)
425a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      return NULL;
426a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
427c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   dri2surf->dri2dpy = dri2dpy;
428a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   dri2surf->type = type;
429a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   dri2surf->drawable = drawable;
430a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   dri2surf->color_format = dri2conf->base.color_format;
431c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
432c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   dri2surf->base.destroy = dri2_surface_destroy;
433a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   dri2surf->base.swap_buffers = dri2_surface_swap_buffers;
434c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   dri2surf->base.flush_frontbuffer = dri2_surface_flush_frontbuffer;
435a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   dri2surf->base.validate = dri2_surface_validate;
436dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCall   dri2surf->base.wait = dri2_surface_wait;
437c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
438a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   if (drawable) {
4395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE);
4409e922b1663ecb95dc7eee03002fd66ed18fb3192Argyrios Kyrtzidis      /* initialize the geometry */
441a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      dri2_surface_update_buffers(&dri2surf->base, 0x0);
442a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
4432cf719c3c3d805f630dfc6b1255e52647820888eSebastian Redl      util_hash_table_set(dri2surf->dri2dpy->surfaces,
444a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor            (void *) dri2surf->drawable, (void *) &dri2surf->base);
445c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   }
446a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
447a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   return dri2surf;
448c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt}
449a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
450a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregorstatic struct native_surface *
451a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregordri2_display_create_window_surface(struct native_display *ndpy,
452a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor                                   EGLNativeWindowType win,
453c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                                   const struct native_config *nconf)
454a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor{
455a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   struct dri2_surface *dri2surf;
456a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
4572cf719c3c3d805f630dfc6b1255e52647820888eSebastian Redl   dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_WINDOW,
458a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor         (Drawable) win, nconf);
459c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   return (dri2surf) ? &dri2surf->base : NULL;
4602cf719c3c3d805f630dfc6b1255e52647820888eSebastian Redl}
461a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
462c302113179a1c2b1254224ea9b6f5316ceeb375cSean Huntstatic struct native_surface *
463a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregordri2_display_create_pixmap_surface(struct native_display *ndpy,
464a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor                                   EGLNativePixmapType pix,
465a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor                                   const struct native_config *nconf)
466c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt{
467a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   struct dri2_surface *dri2surf;
468a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
469a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PIXMAP,
470a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor         (Drawable) pix, nconf);
471a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   return (dri2surf) ? &dri2surf->base : NULL;
472c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt}
473a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
474dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCallstatic int
475d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallchoose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32])
4760da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor{
477c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   int count = 0;
4789e922b1663ecb95dc7eee03002fd66ed18fb3192Argyrios Kyrtzidis
4790da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor   switch (mode->rgbBits) {
4800da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor   case 32:
4810da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
4829e922b1663ecb95dc7eee03002fd66ed18fb3192Argyrios Kyrtzidis      formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
483dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCall      break;
4840da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor   case 24:
4850da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      formats[count++] = PIPE_FORMAT_B8G8R8X8_UNORM;
4860da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM;
4871a49af9681c350fef58e677f85ccb9a77e8e9d0aDouglas Gregor      formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
4885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
489dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCall      break;
4900da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor   case 16:
4910da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      formats[count++] = PIPE_FORMAT_B5G6R5_UNORM;
4920da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      break;
4931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   default:
4940b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor      break;
4951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   }
4960b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
4970b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor   return count;
498a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor}
499a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
500a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregorstatic boolean
501dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCallis_format_supported(struct pipe_screen *screen,
502a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor                    enum pipe_format fmt, unsigned sample_count, boolean is_color)
5030da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor{
5040da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor   return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, sample_count,
505c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt         (is_color) ? PIPE_BIND_RENDER_TARGET :
506dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCall         PIPE_BIND_DEPTH_STENCIL, 0);
507dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCall}
508dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCall
509904eed3f6148758d39a2d3c88f3133274460d645Douglas Gregorstatic boolean
5109e922b1663ecb95dc7eee03002fd66ed18fb3192Argyrios Kyrtzidisdri2_display_convert_config(struct native_display *ndpy,
5110b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor                            const __GLcontextModes *mode,
512a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor                            struct native_config *nconf)
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump{
514a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   enum pipe_format formats[32];
515a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   int num_formats, i;
516a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   int sample_count = 0;
517c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
518a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode)
519a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      return FALSE;
520a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
521a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   /* only interested in native renderable configs */
522a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   if (!mode->xRenderable || !mode->drawableType)
523a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      return FALSE;
524c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
525a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   nconf->buffer_mask = 1 << NATIVE_ATTACHMENT_FRONT_LEFT;
526a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   if (mode->doubleBufferMode)
527c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_LEFT;
528c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   if (mode->stereoMode) {
529a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_FRONT_RIGHT;
530a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      if (mode->doubleBufferMode)
531a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor         nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_RIGHT;
532a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   }
533c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
534a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   /* choose color format */
535a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   num_formats = choose_color_format(mode, formats);
536c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   for (i = 0; i < num_formats; i++) {
537a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      if (is_format_supported(ndpy->screen, formats[i], sample_count, TRUE)) {
538a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor         nconf->color_format = formats[i];
539a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor         break;
540a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      }
541a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   }
542d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall   if (nconf->color_format == PIPE_FORMAT_NONE)
543d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall      return FALSE;
544d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
545d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall   if (mode->drawableType & GLX_WINDOW_BIT)
546d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall      nconf->window_bit = TRUE;
547d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall   if (mode->drawableType & GLX_PIXMAP_BIT)
548d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall      nconf->pixmap_bit = TRUE;
549c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
550a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   nconf->native_visual_id = mode->visualID;
551a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   nconf->native_visual_type = mode->visualType;
552a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   nconf->level = mode->level;
553a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   nconf->samples = mode->samples;
554a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
555c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   nconf->slow_config = (mode->visualRating == GLX_SLOW_CONFIG);
556a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
557a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   if (mode->transparentPixel == GLX_TRANSPARENT_RGB) {
558c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      nconf->transparent_rgb = TRUE;
559a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      nconf->transparent_rgb_values[0] = mode->transparentRed;
560a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      nconf->transparent_rgb_values[1] = mode->transparentGreen;
561833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall      nconf->transparent_rgb_values[2] = mode->transparentBlue;
562a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   }
563a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
564c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt   return TRUE;
565a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor}
566a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
567c302113179a1c2b1254224ea9b6f5316ceeb375cSean Huntstatic const struct native_config **
568a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregordri2_display_get_configs(struct native_display *ndpy, int *num_configs)
569a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor{
570a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   struct dri2_display *dri2dpy = dri2_display(ndpy);
571a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   const struct native_config **configs;
572a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   int i;
573c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
574a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   /* first time */
575a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor   if (!dri2dpy->configs) {
576c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      const __GLcontextModes *modes;
577a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      int num_modes, count;
578a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
579a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      modes = x11_screen_get_glx_configs(dri2dpy->xscr);
580a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      if (!modes)
581a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor         return NULL;
582c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      num_modes = x11_context_modes_count(modes);
583a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
584a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      dri2dpy->configs = CALLOC(num_modes, sizeof(*dri2dpy->configs));
585c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      if (!dri2dpy->configs)
5861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump         return NULL;
58799e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor
5885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      count = 0;
5895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      for (i = 0; i < num_modes; i++) {
5901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump         struct native_config *nconf = &dri2dpy->configs[count].base;
59177ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek         if (dri2_display_convert_config(&dri2dpy->base, modes, nconf))
59277ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek            count++;
59377ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek         modes = modes->next;
5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      }
5955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
596d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner      dri2dpy->num_configs = count;
597d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner   }
598227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson
599227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson   configs = MALLOC(dri2dpy->num_configs * sizeof(*configs));
600227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson   if (configs) {
601227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson      for (i = 0; i < dri2dpy->num_configs; i++)
602848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson         configs[i] = (const struct native_config *) &dri2dpy->configs[i];
603848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson      if (num_configs)
604848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson         *num_configs = dri2dpy->num_configs;
605848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson   }
606227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson
6071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   return configs;
608227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson}
609227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson
610227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlssonstatic boolean
611227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlssondri2_display_is_pixmap_supported(struct native_display *ndpy,
6121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                 EGLNativePixmapType pix,
613c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                                 const struct native_config *nconf)
614773f3973cf5e2b6b8788e895967dcb3c1e6ffe79Anders Carlsson{
6151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   struct dri2_display *dri2dpy = dri2_display(ndpy);
61617fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor   uint depth, nconf_depth;
6171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61817fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor   depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
61917fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor   nconf_depth = util_format_get_blocksizebits(nconf->color_format);
620227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson
62117fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor   /* simple depth match for now */
62217fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor   return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth));
62317fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor}
62417fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor
62517fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregorstatic int
626848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlssondri2_display_get_param(struct native_display *ndpy,
6273a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson                       enum native_param_type param)
628227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson{
629227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson   int val;
6301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   switch (param) {
632227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson   case NATIVE_PARAM_USE_NATIVE_BUFFER:
633d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner      /* DRI2GetBuffers use the native buffers */
6341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      val = TRUE;
63577ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek      break;
63677ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek   default:
63777ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek      val = 0;
638227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson      break;
639227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson   }
6405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   return val;
6425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
6435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic void
6455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerdri2_display_destroy(struct native_display *ndpy)
6465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer{
6472333f7727f97018d6742e1e0938133bcfad967abEli Friedman   struct dri2_display *dri2dpy = dri2_display(ndpy);
6485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   if (dri2dpy->configs)
650a135fb43eb94524a6529768596a4533eed9aa70dAnders Carlsson      FREE(dri2dpy->configs);
6510b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
6521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   if (dri2dpy->base.screen)
6530b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor      dri2dpy->base.screen->destroy(dri2dpy->base.screen);
6540b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
6555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   if (dri2dpy->surfaces)
6565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      util_hash_table_destroy(dri2dpy->surfaces);
6575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
658313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor   if (dri2dpy->xscr)
659313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor      x11_screen_destroy(dri2dpy->xscr);
660313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor   if (dri2dpy->own_dpy)
6610b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor      XCloseDisplay(dri2dpy->dpy);
6620b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor   FREE(dri2dpy);
6630b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor}
6641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic void
6665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerdri2_display_invalidate_buffers(struct x11_screen *xscr, Drawable drawable,
6675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                void *user_data)
6681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump{
66977ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek   struct native_display *ndpy = (struct native_display* ) user_data;
67077ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek   struct dri2_display *dri2dpy = dri2_display(ndpy);
67177ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek   struct native_surface *nsurf;
6725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   struct dri2_surface *dri2surf;
6735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   nsurf = (struct native_surface *)
6755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      util_hash_table_get(dri2dpy->surfaces, (void *) drawable);
6765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   if (!nsurf)
677c250aae4f645833aed3a6321bc8598f7330dce8dChris Lattner      return;
6785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   dri2surf = dri2_surface(nsurf);
680c250aae4f645833aed3a6321bc8598f7330dce8dChris Lattner
6812333f7727f97018d6742e1e0938133bcfad967abEli Friedman   dri2surf->server_stamp++;
6822333f7727f97018d6742e1e0938133bcfad967abEli Friedman   dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
6835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         &dri2surf->base, dri2surf->server_stamp);
6840b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor}
6850b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
6860b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor/**
6870b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor * Initialize DRI2 and pipe screen.
688018d8e0596dd57401eeddcf11ac84ff0a065fbbeChris Lattner */
689c250aae4f645833aed3a6321bc8598f7330dce8dChris Lattnerstatic boolean
6901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpdri2_display_init_screen(struct native_display *ndpy)
6915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer{
6921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   struct dri2_display *dri2dpy = dri2_display(ndpy);
6935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   int fd;
6945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6950b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor   if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
6960b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor       !x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) {
6970b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor      _eglLog(_EGL_WARNING, "GLX/DRI2 is not supported");
6980b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor      return FALSE;
6991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   }
7001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr,
7025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer         &dri2dpy->dri_major, &dri2dpy->dri_minor);
70377ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek
70477ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek   fd = x11_screen_enable_dri2(dri2dpy->xscr,
70577ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek         dri2_display_invalidate_buffers, &dri2dpy->base);
70677ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek   if (fd < 0)
7075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return FALSE;
7085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   dri2dpy->base.screen =
710525a05093a4816af961fe2bc6b8a81c17e2e26c2Chris Lattner      dri2dpy->event_handler->new_drm_screen(&dri2dpy->base,
711720c4ec57b6110873cd533ad434853a27e7c3f4aTed Kremenek            dri2dpy->dri_driver, fd);
7125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   if (!dri2dpy->base.screen) {
7135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      _eglLog(_EGL_WARNING, "failed to create DRM screen");
7141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return FALSE;
715720c4ec57b6110873cd533ad434853a27e7c3f4aTed Kremenek   }
7162333f7727f97018d6742e1e0938133bcfad967abEli Friedman
7172333f7727f97018d6742e1e0938133bcfad967abEli Friedman   return TRUE;
7185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
71917fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor
7201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic unsigned
72117fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregordri2_display_hash_table_hash(void *key)
72217fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor{
723c9bec4bfea9090a08dd83a7b213f0c8adf8d78ecChris Lattner   XID drawable = pointer_to_uintptr(key);
72417fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor   return (unsigned) drawable;
72517fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor}
726720c4ec57b6110873cd533ad434853a27e7c3f4aTed Kremenek
72717fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregorstatic int
728c9bec4bfea9090a08dd83a7b213f0c8adf8d78ecChris Lattnerdri2_display_hash_table_compare(void *key1, void *key2)
729da8249e57f3badecf925571881fe57243935c6c1Chris Lattner{
730da8249e57f3badecf925571881fe57243935c6c1Chris Lattner   return (key1 - key2);
731da8249e57f3badecf925571881fe57243935c6c1Chris Lattner}
732da8249e57f3badecf925571881fe57243935c6c1Chris Lattner
7331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstruct native_display *
73417fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregorx11_create_dri2_display(Display *dpy,
73517fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor                        struct native_event_handler *event_handler,
73617fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor                        void *user_data)
7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer{
7385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   struct dri2_display *dri2dpy;
7391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   dri2dpy = CALLOC_STRUCT(dri2_display);
7415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   if (!dri2dpy)
7425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return NULL;
7431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74477ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek   dri2dpy->event_handler = event_handler;
74577ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek   dri2dpy->base.user_data = user_data;
74677ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek
7475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   dri2dpy->dpy = dpy;
7485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer   if (!dri2dpy->dpy) {
7495d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner      dri2dpy->dpy = XOpenDisplay(NULL);
7505d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner      if (!dri2dpy->dpy) {
7515d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner         dri2_display_destroy(&dri2dpy->base);
7525d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner         return NULL;
7535d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner      }
7545d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner      dri2dpy->own_dpy = TRUE;
7555549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek   }
7565d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner
7575d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner   dri2dpy->xscr_number = DefaultScreen(dri2dpy->dpy);
7582333f7727f97018d6742e1e0938133bcfad967abEli Friedman   dri2dpy->xscr = x11_screen_create(dri2dpy->dpy, dri2dpy->xscr_number);
7591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   if (!dri2dpy->xscr) {
760cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor      dri2_display_destroy(&dri2dpy->base);
7611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return NULL;
762cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor   }
763cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor
7645549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek   if (!dri2_display_init_screen(&dri2dpy->base)) {
7655549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek      dri2_display_destroy(&dri2dpy->base);
766cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor      return NULL;
767cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor   }
7685d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner
7691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump   dri2dpy->surfaces = util_hash_table_create(dri2_display_hash_table_hash,
7701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump         dri2_display_hash_table_compare);
7715d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner   if (!dri2dpy->surfaces) {
7725d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner      dri2_display_destroy(&dri2dpy->base);
7731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return NULL;
7745d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner   }
7755d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner
7765d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner   dri2dpy->base.destroy = dri2_display_destroy;
7775d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner   dri2dpy->base.get_param = dri2_display_get_param;
7785d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner   dri2dpy->base.get_configs = dri2_display_get_configs;
779e6a82b2c29ad05534841e5f8fd033fb17b6f61e2Ted Kremenek   dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
780e6a82b2c29ad05534841e5f8fd033fb17b6f61e2Ted Kremenek   dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
781e6a82b2c29ad05534841e5f8fd033fb17b6f61e2Ted Kremenek   dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
782a7ad98ff0919d6a24ea7c46634ea29bea551c1a0Chris Lattner
783c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner   return &dri2dpy->base;
784c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner}
785690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner
786690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner#else /* GLX_DIRECT_RENDERING */
7878bea7c0ee44c71c817de7dc2be932b73bec90c9fChris Lattner
788690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattnerstruct native_display *
789c4a09c189981b4561428e4b56fd250718e2717bbChris Lattnerx11_create_dri2_display(Display *dpy,
790c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner                        struct native_event_handler *event_handler,
791c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner                        void *user_data)
792c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner{
793c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner   return NULL;
794c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner}
7955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
7965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif /* GLX_DIRECT_RENDERING */
7975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer