1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  7.9
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE.
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "egldriver.h"
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "eglcurrent.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "egllog.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_box.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "egl_g3d.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "egl_g3d_api.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "egl_g3d_image.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "egl_g3d_sync.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "egl_g3d_st.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "native.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the state tracker for the given context.
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct st_api *
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx,
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  enum st_profile_type *profile)
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_api *stapi;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint api = -1;
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *profile = ST_PROFILE_DEFAULT;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ctx->ClientAPI) {
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_OPENGL_ES_API:
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (ctx->ClientMajorVersion) {
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case 1:
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         api = ST_API_OPENGL;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *profile = ST_PROFILE_OPENGL_ES1;
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case 2:
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         api = ST_API_OPENGL;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         *profile = ST_PROFILE_OPENGL_ES2;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _eglLog(_EGL_WARNING, "unknown client major version %d",
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               ctx->ClientMajorVersion);
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_OPENVG_API:
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      api = ST_API_OPENVG;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_OPENGL_API:
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      api = ST_API_OPENGL;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   stapi = egl_g3d_get_st_api(drv, api);
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (stapi && !(stapi->profile_mask & (1 << *profile)))
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stapi = NULL;
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return stapi;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct egl_g3d_choose_config_data {
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLConfig criteria;
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   enum pipe_format format;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_compare_config(const _EGLConfig *conf1, const _EGLConfig *conf2,
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       void *priv_data)
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_choose_config_data *data =
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (struct egl_g3d_choose_config_data *) priv_data;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const _EGLConfig *criteria = &data->criteria;;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* EGL_NATIVE_VISUAL_TYPE ignored? */
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE);
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_match_config(const _EGLConfig *conf, void *priv_data)
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_choose_config_data *data =
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (struct egl_g3d_choose_config_data *) priv_data;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_config *gconf = egl_g3d_config(conf);
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (data->format != PIPE_FORMAT_NONE &&
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       data->format != gconf->native->color_format)
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return _eglMatchConfig(conf, &data->criteria);
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      EGLConfig *configs, EGLint size, EGLint *num_configs)
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_choose_config_data data;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_eglParseConfigAttribList(&data.criteria, dpy, attribs))
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   data.format = PIPE_FORMAT_NONE;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (data.criteria.MatchNativePixmap != EGL_NONE &&
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       data.criteria.MatchNativePixmap != EGL_DONT_CARE) {
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!gdpy->native->get_pixmap_format(gdpy->native,
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               (EGLNativePixmapType) data.criteria.MatchNativePixmap,
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               &data.format))
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglChooseConfig");
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return _eglFilterConfigArray(dpy->Configs, configs, size, num_configs,
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         egl_g3d_match_config, egl_g3d_compare_config, &data);
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLContext *
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       _EGLContext *share, const EGLint *attribs)
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_context *gshare = egl_g3d_context(share);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_config *gconf = egl_g3d_config(conf);
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_context *gctx;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct st_context_attribs stattribs;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   enum st_context_error ctx_err = 0;
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gctx = CALLOC_STRUCT(egl_g3d_context);
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gctx) {
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglError(EGL_BAD_ALLOC, "eglCreateContext");
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_eglInitContext(&gctx->base, dpy, conf, attribs)) {
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(gctx);
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&stattribs, 0, sizeof(stattribs));
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gconf)
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stattribs.visual = gconf->stvis;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gctx->stapi = egl_g3d_choose_st(drv, &gctx->base, &stattribs.profile);
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gctx->stapi) {
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(gctx);
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi,
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         &stattribs, &ctx_err, (gshare) ? gshare->stctxi : NULL);
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gctx->stctxi) {
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(gctx);
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gctx->stctxi->st_manager_private = (void *) &gctx->base;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &gctx->base;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Destroy a context.
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdestroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FIXME a context might live longer than its display */
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dpy->Initialized)
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gctx->stctxi->destroy(gctx->stctxi);
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(gctx);
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_eglPutContext(ctx))
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      destroy_context(dpy, ctx);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct egl_g3d_create_surface_arg {
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint type;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union {
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      EGLNativeWindowType win;
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      EGLNativePixmapType pix;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } u;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLSurface *
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       struct egl_g3d_create_surface_arg *arg,
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const EGLint *attribs)
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_config *gconf = egl_g3d_config(conf);
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct native_surface *nsurf;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const char *err;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (arg->type) {
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_WINDOW_BIT:
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      err = "eglCreateWindowSurface";
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_PIXMAP_BIT:
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      err = "eglCreatePixmapSurface";
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_MESA_screen_surface
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_SCREEN_BIT_MESA:
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      err = "eglCreateScreenSurface";
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      err = "eglCreateUnknownSurface";
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf = CALLOC_STRUCT(egl_g3d_surface);
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf) {
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglError(EGL_BAD_ALLOC, err);
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_eglInitSurface(&gsurf->base, dpy, arg->type, conf, attribs)) {
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(gsurf);
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* create the native surface */
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (arg->type) {
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_WINDOW_BIT:
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nsurf = gdpy->native->create_window_surface(gdpy->native,
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            arg->u.win, gconf->native);
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_PIXMAP_BIT:
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            arg->u.pix, gconf->native);
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_MESA_screen_surface
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_SCREEN_BIT_MESA:
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* prefer back buffer (move to _eglInitSurface?) */
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gsurf->base.RenderBuffer = EGL_BACK_BUFFER;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nsurf = gdpy->native->modeset->create_scanout_surface(gdpy->native,
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            gconf->native, gsurf->base.Width, gsurf->base.Height);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nsurf = NULL;
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!nsurf) {
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(gsurf);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* initialize the geometry */
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!nsurf->validate(nsurf, 0x0, &gsurf->sequence_number, NULL,
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            &gsurf->base.Width, &gsurf->base.Height)) {
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nsurf->destroy(nsurf);
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(gsurf);
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf->stvis = gconf->stvis;
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER &&
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       gconf->stvis.buffer_mask & ST_ATTACHMENT_FRONT_LEFT_MASK)
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gsurf->stvis.render_buffer = ST_ATTACHMENT_FRONT_LEFT;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* surfaces can always be posted when the display supports it */
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (dpy->Extensions.NV_post_sub_buffer)
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gsurf->base.PostSubBufferSupportedNV = EGL_TRUE;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base);
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf->stfbi) {
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nsurf->destroy(nsurf);
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(gsurf);
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nsurf->user_data = &gsurf->base;
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf->native = nsurf;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &gsurf->base;
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLSurface *
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              _EGLConfig *conf, EGLNativeWindowType win,
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              const EGLint *attribs)
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_create_surface_arg arg;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&arg, 0, sizeof(arg));
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg.type = EGL_WINDOW_BIT;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg.u.win = win;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLSurface *
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              _EGLConfig *conf, EGLNativePixmapType pix,
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              const EGLint *attribs)
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_create_surface_arg arg;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&arg, 0, sizeof(arg));
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg.type = EGL_PIXMAP_BIT;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg.u.pix = pix;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct egl_g3d_surface *
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_pbuffer_surface(_EGLDisplay *dpy, _EGLConfig *conf,
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const EGLint *attribs, const char *func)
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_config *gconf = egl_g3d_config(conf);
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf = CALLOC_STRUCT(egl_g3d_surface);
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf) {
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglError(EGL_BAD_ALLOC, func);
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_eglInitSurface(&gsurf->base, dpy, EGL_PBUFFER_BIT, conf, attribs)) {
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(gsurf);
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf->stvis = gconf->stvis;
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base);
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf->stfbi) {
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(gsurf);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return gsurf;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLSurface *
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               _EGLConfig *conf, const EGLint *attribs)
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf = create_pbuffer_surface(dpy, conf, attribs,
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         "eglCreatePbufferSurface");
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf)
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf->client_buffer_type = EGL_NONE;
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &gsurf->base;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLSurface *
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_create_pbuffer_from_client_buffer(_EGLDriver *drv, _EGLDisplay *dpy,
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          EGLenum buftype,
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          EGLClientBuffer buffer,
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          _EGLConfig *conf,
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          const EGLint *attribs)
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf;
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_resource *ptex = NULL;
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint pbuffer_attribs[32];
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint count, i;
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (buftype) {
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_OPENVG_IMAGE:
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* parse the attributes first */
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   count = 0;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; attribs && attribs[i] != EGL_NONE; i++) {
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      EGLint attr = attribs[i++];
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      EGLint val = attribs[i];
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      EGLint err = EGL_SUCCESS;
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (attr) {
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_TEXTURE_FORMAT:
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_TEXTURE_TARGET:
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_MIPMAP_TEXTURE:
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pbuffer_attribs[count++] = attr;
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         pbuffer_attribs[count++] = val;
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         err = EGL_BAD_ATTRIBUTE;
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* bail out */
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (err != EGL_SUCCESS) {
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _eglError(err, "eglCreatePbufferFromClientBuffer");
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return NULL;
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pbuffer_attribs[count++] = EGL_NONE;
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf = create_pbuffer_surface(dpy, conf, pbuffer_attribs,
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         "eglCreatePbufferFromClientBuffer");
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf)
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf->client_buffer_type = buftype;
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf->client_buffer = buffer;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* validate now so that it fails if the client buffer is invalid */
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf->stfbi->validate(gsurf->stfbi,
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            &gsurf->stvis.render_buffer, 1, &ptex)) {
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(gsurf);
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource_reference(&ptex, NULL);
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &gsurf->base;
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Destroy a surface.
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdestroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FIXME a surface might live longer than its display */
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!dpy->Initialized)
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource_reference(&gsurf->render_texture, NULL);
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gsurf->native)
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gsurf->native->destroy(gsurf->native);
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(gsurf);
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_eglPutSurface(surf))
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      destroy_surface(dpy, surf);
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gread = egl_g3d_surface(read);
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_context *old_gctx;
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLContext *old_ctx;
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLSurface *old_draw, *old_read;
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLBoolean ok = EGL_TRUE;
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* make new bindings */
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_eglBindContext(ctx, draw, read, &old_ctx, &old_draw, &old_read))
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   old_gctx = egl_g3d_context(old_ctx);
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (old_gctx) {
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* flush old context */
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      old_gctx->stctxi->flush(old_gctx->stctxi, ST_FLUSH_FRONT, NULL);
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gctx) {
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ok = gctx->stapi->make_current(gctx->stapi, gctx->stctxi,
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            (gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ok) {
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (gdraw) {
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (gdraw->base.Type == EGL_WINDOW_BIT) {
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               gctx->base.WindowRenderBuffer =
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  (gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (old_gctx) {
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ok = old_gctx->stapi->make_current(old_gctx->stapi, NULL, NULL, NULL);
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ok)
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         old_gctx->base.WindowRenderBuffer = EGL_NONE;
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ok) {
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (_eglPutContext(old_ctx))
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         destroy_context(dpy, old_ctx);
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (_eglPutSurface(old_draw))
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         destroy_surface(dpy, old_draw);
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (_eglPutSurface(old_read))
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         destroy_surface(dpy, old_read);
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* undo the previous _eglBindContext */
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglBindContext(old_ctx, old_draw, old_read, &ctx, &draw, &read);
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(&gctx->base == ctx &&
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             &gdraw->base == draw &&
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             &gread->base == read);
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglPutSurface(draw);
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglPutSurface(read);
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglPutContext(ctx);
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglPutSurface(old_draw);
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglPutSurface(old_read);
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglPutContext(old_ctx);
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return ok;
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             EGLint num_rects, const EGLint *rects, EGLBoolean preserve)
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLContext *ctx = _eglGetCurrentContext();
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_context *gctx = NULL;
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct native_present_control ctrl;
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* no-op for pixmap or pbuffer surface */
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gsurf->base.Type == EGL_PIXMAP_BIT ||
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       gsurf->base.Type == EGL_PBUFFER_BIT)
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_TRUE;
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* or when the surface is single-buffered */
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gsurf->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT)
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_TRUE;
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx && ctx->DrawSurface == surf)
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gctx = egl_g3d_context(ctx);
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* flush if the surface is current */
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gctx) {
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&ctrl, 0, sizeof(ctrl));
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctrl.natt = NATIVE_ATTACHMENT_BACK_LEFT;
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctrl.preserve = preserve;
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctrl.swap_interval = gsurf->base.SwapInterval;
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctrl.premultiplied_alpha = (gsurf->base.VGAlphaFormat == EGL_VG_ALPHA_FORMAT_PRE);
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctrl.num_rects = num_rects;
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctrl.rects = rects;
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return gsurf->native->present(gsurf->native, &ctrl);
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return swap_buffers(drv, dpy, surf, 0, NULL,
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       (gsurf->base.SwapBehavior == EGL_BUFFER_PRESERVED));
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_NOK_swap_region
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_swap_buffers_region(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            EGLint num_rects, const EGLint *rects)
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Note: y=0=top */
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return swap_buffers(drv, dpy, surf, num_rects, rects, EGL_TRUE);
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* EGL_NOK_swap_region */
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_post_sub_buffer(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        EGLint x, EGLint y, EGLint width, EGLint height)
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLint rect[4];
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (x < 0 || y < 0 || width < 0 || height < 0)
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_PARAMETER, "eglPostSubBufferNV");
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* clamp */
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (x + width > surf->Width)
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      width = surf->Width - x;
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (y + height > surf->Height)
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      height = surf->Height - y;
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (width <= 0 || height <= 0)
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_TRUE;
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rect[0] = x;
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Note: y=0=bottom */
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rect[1] = surf->Height - y - height;
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rect[2] = width;
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   rect[3] = height;
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return swap_buffers(drv, dpy, surf, 1, rect, EGL_TRUE);
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     EGLNativePixmapType target)
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLContext *ctx = _eglGetCurrentContext();
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf->render_texture)
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_TRUE;
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* flush if the surface is current */
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx && ctx->DrawSurface == &gsurf->base) {
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct egl_g3d_context *gctx = egl_g3d_context(ctx);
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return gdpy->native->copy_to_pixmap(gdpy->native,
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         target, gsurf->render_texture);
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_screen *screen = gdpy->native->screen;
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_fence_handle *fence = NULL;
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, &fence);
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fence) {
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      screen->fence_reference(screen, &fence, NULL);
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLContext *ctx = _eglGetCurrentContext();
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (engine != EGL_CORE_NATIVE_ENGINE)
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx && ctx->DrawSurface) {
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct egl_g3d_surface *gsurf = egl_g3d_surface(ctx->DrawSurface);
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (gsurf->native)
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         gsurf->native->wait(gsurf->native);
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       _EGLSurface *surf, EGLint buffer)
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API);
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_context *gctx;
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   enum pipe_format internal_format;
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   enum st_texture_type target;
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (buffer != EGL_BACK_BUFFER)
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gsurf->base.BoundToTexture)
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (gsurf->base.TextureFormat) {
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_TEXTURE_RGB:
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      internal_format = PIPE_FORMAT_R8G8B8_UNORM;
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_TEXTURE_RGBA:
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      internal_format = PIPE_FORMAT_B8G8R8A8_UNORM;
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (gsurf->base.TextureTarget) {
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case EGL_TEXTURE_2D:
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      target = ST_TEXTURE_2D;
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!es1)
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_TRUE;
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf->render_texture)
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* flush properly if the surface is bound */
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gsurf->base.CurrentContext) {
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gctx = egl_g3d_context(gsurf->base.CurrentContext);
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gctx = egl_g3d_context(es1);
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gctx->stctxi->teximage) {
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!gctx->stctxi->teximage(gctx->stctxi, target,
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               gsurf->base.MipmapLevel, internal_format,
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               gsurf->render_texture, gsurf->base.MipmapTexture))
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return EGL_FALSE;
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gsurf->base.BoundToTexture = EGL_TRUE;
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          _EGLSurface *surf, EGLint buffer)
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT ||
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       !gsurf->base.BoundToTexture)
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (buffer != EGL_BACK_BUFFER)
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gsurf->render_texture) {
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct egl_g3d_context *gctx = egl_g3d_context(ctx);
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* what if the context the surface binds to is no longer current? */
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (gctx) {
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         gctx->stctxi->teximage(gctx->stctxi, ST_TEXTURE_2D,
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               gsurf->base.MipmapLevel, PIPE_FORMAT_NONE, NULL, FALSE);
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   gsurf->base.BoundToTexture = EGL_FALSE;
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_MESA_screen_surface
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLSurface *
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              _EGLConfig *conf, const EGLint *attribs)
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_create_surface_arg arg;
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&arg, 0, sizeof(arg));
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   arg.type = EGL_SCREEN_BIT_MESA;
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            _EGLScreen *scr, _EGLSurface *surf,
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            _EGLMode *mode)
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_screen *gscr = egl_g3d_screen(scr);
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct native_surface *nsurf;
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct native_mode *nmode;
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   EGLBoolean changed;
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (gsurf) {
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      EGLint idx;
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!mode)
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (gsurf->base.Type != EGL_SCREEN_BIT_MESA)
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return _eglError(EGL_BAD_SURFACE, "eglShowScreenSurfaceMESA");
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (gsurf->base.Width < mode->Width || gsurf->base.Height < mode->Height)
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return _eglError(EGL_BAD_MATCH,
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               "eglShowSurfaceMESA(surface smaller than mode size)");
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* find the index of the mode */
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (idx = 0; idx < gscr->base.NumModes; idx++)
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (mode == &gscr->base.Modes[idx])
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            break;
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (idx >= gscr->base.NumModes) {
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return _eglError(EGL_BAD_MODE_MESA,
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               "eglShowSurfaceMESA(unknown mode)");
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nsurf = gsurf->native;
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nmode = gscr->native_modes[idx];
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mode)
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* disable the screen */
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nsurf = NULL;
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nmode = NULL;
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* TODO surface panning by CRTC choosing */
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   changed = gdpy->native->modeset->program(gdpy->native, 0, nsurf,
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         gscr->base.OriginX, gscr->base.OriginY, &gscr->native, 1, nmode);
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (changed) {
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gscr->base.CurrentSurface = &gsurf->base;
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      gscr->base.CurrentMode = mode;
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return changed;
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* EGL_MESA_screen_surface */
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_WL_bind_wayland_display
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *dpy,
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                struct wl_display *wl_dpy)
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gdpy->native->wayland_bufmgr)
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return gdpy->native->wayland_bufmgr->bind_display(gdpy->native, wl_dpy);
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_unbind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *dpy,
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  struct wl_display *wl_dpy)
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gdpy->native->wayland_bufmgr)
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return gdpy->native->wayland_bufmgr->unbind_display(gdpy->native, wl_dpy);
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_query_wayland_buffer_wl(_EGLDriver *drv, _EGLDisplay *dpy,
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                struct wl_buffer *buffer,
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                EGLint attribute, EGLint *value)
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!gdpy->native->wayland_bufmgr)
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return gdpy->native->wayland_bufmgr->query_buffer(gdpy->native,
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                     buffer, attribute, value);
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* EGL_WL_bind_wayland_display */
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgegl_g3d_init_driver_api(_EGLDriver *drv)
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _eglInitDriverFallbacks(drv);
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.ChooseConfig = egl_g3d_choose_config;
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CreateContext = egl_g3d_create_context;
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.DestroyContext = egl_g3d_destroy_context;
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CreateWindowSurface = egl_g3d_create_window_surface;
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CreatePixmapSurface = egl_g3d_create_pixmap_surface;
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface;
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CreatePbufferFromClientBuffer = egl_g3d_create_pbuffer_from_client_buffer;
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.DestroySurface = egl_g3d_destroy_surface;
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.MakeCurrent = egl_g3d_make_current;
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.SwapBuffers = egl_g3d_swap_buffers;
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CopyBuffers = egl_g3d_copy_buffers;
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.WaitClient = egl_g3d_wait_client;
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.WaitNative = egl_g3d_wait_native;
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.BindTexImage = egl_g3d_bind_tex_image;
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.ReleaseTexImage = egl_g3d_release_tex_image;
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CreateImageKHR = egl_g3d_create_image;
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.DestroyImageKHR = egl_g3d_destroy_image;
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_MESA_drm_image
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CreateDRMImageMESA = egl_g3d_create_drm_image;
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.ExportDRMImageMESA = egl_g3d_export_drm_image;
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_WL_bind_wayland_display
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.BindWaylandDisplayWL = egl_g3d_bind_wayland_display_wl;
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.UnbindWaylandDisplayWL = egl_g3d_unbind_wayland_display_wl;
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.QueryWaylandBufferWL = egl_g3d_query_wayland_buffer_wl;
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CreateSyncKHR = egl_g3d_create_sync;
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.DestroySyncKHR = egl_g3d_destroy_sync;
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.ClientWaitSyncKHR = egl_g3d_client_wait_sync;
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.SignalSyncKHR = egl_g3d_signal_sync;
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_MESA_screen_surface
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_NOK_swap_region
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.SwapBuffersRegionNOK = egl_g3d_swap_buffers_region;
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drv->API.PostSubBufferNV = egl_g3d_post_sub_buffer;
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
942