eglcontext.c revision cf7634d9665b26a321a9d8542d50c76693141b52
145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/**************************************************************************
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright 2010-2011 LunarG, Inc.
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * All Rights Reserved.
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * copy of this software and associated documentation files (the
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * "Software"), to deal in the Software without restriction, including
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * permit persons to whom the Software is furnished to do so, subject to
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the following conditions:
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The above copyright notice and this permission notice (including the
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * next paragraph) shall be included in all copies or substantial portions
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * of the Software.
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * DEALINGS IN THE SOFTWARE.
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org **************************************************************************/
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <assert.h>
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <stdlib.h>
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <string.h>
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "eglconfig.h"
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "eglcontext.h"
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "egldisplay.h"
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "eglcurrent.h"
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "eglsurface.h"
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "egllog.h"
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/**
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Return the API bit (one of EGL_xxx_BIT) of the context.
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic EGLint
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org_eglGetContextAPIBit(_EGLContext *ctx)
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   EGLint bit = 0;
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   switch (ctx->ClientAPI) {
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   case EGL_OPENGL_ES_API:
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      switch (ctx->ClientMajorVersion) {
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case 1:
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         bit = EGL_OPENGL_ES_BIT;
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case 2:
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case 3:
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         bit = EGL_OPENGL_ES2_BIT;
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      default:
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      }
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      break;
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   case EGL_OPENVG_API:
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      bit = EGL_OPENVG_BIT;
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      break;
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   case EGL_OPENGL_API:
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      bit = EGL_OPENGL_BIT;
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      break;
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   default:
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      break;
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   return bit;
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/**
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Parse the list of context attributes and return the proper error code.
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic EGLint
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org_eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *dpy,
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                           const EGLint *attrib_list)
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   EGLenum api = ctx->ClientAPI;
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   EGLint i, err = EGL_SUCCESS;
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (!attrib_list)
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return EGL_SUCCESS;
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (api == EGL_OPENVG_API && attrib_list[0] != EGL_NONE) {
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attrib_list[0]);
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return EGL_BAD_ATTRIBUTE;
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   for (i = 0; attrib_list[i] != EGL_NONE; i++) {
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      EGLint attr = attrib_list[i++];
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      EGLint val = attrib_list[i];
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      switch (attr) {
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case EGL_CONTEXT_CLIENT_VERSION:
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         ctx->ClientMajorVersion = val;
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case EGL_CONTEXT_MINOR_VERSION_KHR:
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (!dpy->Extensions.KHR_create_context) {
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_ATTRIBUTE;
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         }
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         ctx->ClientMinorVersion = val;
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case EGL_CONTEXT_FLAGS_KHR:
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (!dpy->Extensions.KHR_create_context) {
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_ATTRIBUTE;
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         }
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         /* The EGL_KHR_create_context spec says:
121d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org          *
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     "Flags are only defined for OpenGL context creation, and
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     specifying a flags value other than zero for other types of
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     contexts, including OpenGL ES contexts, will generate an
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     error."
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          */
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (api != EGL_OPENGL_API && val != 0) {
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_ATTRIBUTE;
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         }
131d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         ctx->Flags = val;
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (!dpy->Extensions.KHR_create_context) {
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_ATTRIBUTE;
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         }
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         /* The EGL_KHR_create_context spec says:
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     "[EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR] is only meaningful for
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     OpenGL contexts, and specifying it for other types of
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     contexts, including OpenGL ES contexts, will generate an
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     error."
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          */
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (api != EGL_OPENGL_API) {
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_ATTRIBUTE;
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         }
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         ctx->Profile = val;
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         /* The EGL_KHR_create_context spec says:
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR] is only
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     meaningful for OpenGL contexts, and specifying it for other
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     types of contexts, including OpenGL ES contexts, will generate
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     an error."
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          */
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org           if (!dpy->Extensions.KHR_create_context
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org               || api != EGL_OPENGL_API) {
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_ATTRIBUTE;
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         }
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         ctx->ResetNotificationStrategy = val;
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         /* The EGL_EXT_create_context_robustness spec says:
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT] is only
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     meaningful for OpenGL ES contexts, and specifying it for other
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          *     types of contexts will generate an EGL_BAD_ATTRIBUTE error."
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          */
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (!dpy->Extensions.EXT_create_context_robustness
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             || api != EGL_OPENGL_ES_API) {
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_ATTRIBUTE;
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         }
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         ctx->ResetNotificationStrategy = val;
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (!dpy->Extensions.EXT_create_context_robustness) {
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_ATTRIBUTE;
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         }
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         ctx->Flags = EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      default:
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         err = EGL_BAD_ATTRIBUTE;
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      }
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if (err != EGL_SUCCESS) {
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attr);
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      }
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (api == EGL_OPENGL_API) {
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      /* The EGL_KHR_create_context spec says:
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *     "If the requested OpenGL version is less than 3.2,
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *     EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR is ignored and the
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *     functionality of the context is determined solely by the
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *     requested version."
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       * Since the value is ignored, only validate the setting if the version
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       * is >= 3.2.
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       */
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if (ctx->ClientMajorVersion >= 4
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          || (ctx->ClientMajorVersion == 3 && ctx->ClientMinorVersion >= 2)) {
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         switch (ctx->Profile) {
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR:
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR:
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         default:
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            /* The EGL_KHR_create_context spec says:
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             *
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             *     "* If an OpenGL context is requested, the requested version
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             *        is greater than 3.2, and the value for attribute
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             *        EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             *        any bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             *        and EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             *        more than one of these bits set; or if the implementation does
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             *        not support the requested profile, then an EGL_BAD_MATCH error
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             *        is generated."
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             */
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_MATCH;
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         }
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      }
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      /* The EGL_KHR_create_context spec says:
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *     "* If an OpenGL context is requested and the values for
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        EGL_CONTEXT_MINOR_VERSION_KHR, when considered together with
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        the value for attribute
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        EGL_CONTEXT_FORWARD_COMPATIBLE_BIT_KHR, specify an OpenGL
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        version and feature set that are not defined, than an
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        EGL_BAD_MATCH error is generated.
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *
25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        ... Thus, examples of invalid combinations of attributes
25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        include:
25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *
25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *          - Major version < 1 or > 4
25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *          - Major version == 1 and minor version < 0 or > 5
25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *          - Major version == 2 and minor version < 0 or > 1
26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *          - Major version == 3 and minor version < 0 or > 2
26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *          - Major version == 4 and minor version < 0 or > 2
26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *          - Forward-compatible flag set and major version < 3"
26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       */
26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0)
26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         err = EGL_BAD_MATCH;
26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      switch (ctx->ClientMajorVersion) {
26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case 1:
26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (ctx->ClientMinorVersion > 5
27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             || (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0)
27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_MATCH;
27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case 2:
27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (ctx->ClientMinorVersion > 1
27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             || (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0)
27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_MATCH;
27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case 3:
28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         /* Note: The text above is incorrect.  There *is* an OpenGL 3.3!
28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          */
28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (ctx->ClientMinorVersion > 3)
28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_MATCH;
28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case 4:
28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      default:
28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         /* Don't put additional version checks here.  We don't know that
29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          * there won't be versions > 4.2.
29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          */
29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      }
29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   } else if (api == EGL_OPENGL_ES_API) {
29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      /* The EGL_KHR_create_context spec says:
29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *
29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *     "* If an OpenGL ES context is requested and the values for
29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that
30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        is not defined, than an EGL_BAD_MATCH error is generated.
30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *
30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *        ... Examples of invalid combinations of attributes include:
30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *
30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *          - Major version < 1 or > 2
30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *          - Major version == 1 and minor version < 0 or > 1
30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       *          - Major version == 2 and minor version != 0
30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       */
30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0)
30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         err = EGL_BAD_MATCH;
31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      switch (ctx->ClientMajorVersion) {
31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case 1:
31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (ctx->ClientMinorVersion > 1)
31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_MATCH;
31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case 2:
31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         if (ctx->ClientMinorVersion > 0)
31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            err = EGL_BAD_MATCH;
32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      case 3:
32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      default:
32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         /* Don't put additional version checks here.  We don't know that
32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          * there won't be versions > 3.0.
32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org          */
32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         break;
32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      }
32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   switch (ctx->ResetNotificationStrategy) {
33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   case EGL_NO_RESET_NOTIFICATION_KHR:
33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   case EGL_LOSE_CONTEXT_ON_RESET_KHR:
33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      break;
33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   default:
33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      err = EGL_BAD_ATTRIBUTE;
33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      break;
33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if ((ctx->Flags & ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                      | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                      | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) != 0) {
34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      err = EGL_BAD_ATTRIBUTE;
34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   return err;
34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/**
35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Initialize the given _EGLContext object to defaults and/or the values
35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * in the attrib_list.
35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgEGLBoolean
35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org_eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                const EGLint *attrib_list)
35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   const EGLenum api = eglQueryAPI();
36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   EGLint err;
36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (api == EGL_NONE) {
36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return EGL_FALSE;
36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   _eglInitResource(&ctx->Resource, sizeof(*ctx), dpy);
36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   ctx->ClientAPI = api;
36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   ctx->Config = conf;
37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   ctx->WindowRenderBuffer = EGL_NONE;
37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   ctx->ClientMajorVersion = 1; /* the default, per EGL spec */
37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   ctx->ClientMinorVersion = 0;
37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   ctx->Flags = 0;
37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   ctx->ResetNotificationStrategy = EGL_NO_RESET_NOTIFICATION_KHR;
37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   err = _eglParseContextAttribList(ctx, dpy, attrib_list);
38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (err == EGL_SUCCESS && ctx->Config) {
38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      EGLint api_bit;
38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      api_bit = _eglGetContextAPIBit(ctx);
38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if (!(ctx->Config->RenderableType & api_bit)) {
38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         _eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x",
38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org               api_bit, ctx->Config->RenderableType);
38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         err = EGL_BAD_CONFIG;
38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      }
38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (err != EGL_SUCCESS)
39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return _eglError(err, "eglCreateContext");
39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   return EGL_TRUE;
39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic EGLint
39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org_eglQueryContextRenderBuffer(_EGLContext *ctx)
39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   _EGLSurface *surf = ctx->DrawSurface;
40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   EGLint rb;
40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (!surf)
40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return EGL_NONE;
40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (surf->Type == EGL_WINDOW_BIT && ctx->WindowRenderBuffer != EGL_NONE)
40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      rb = ctx->WindowRenderBuffer;
407d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org   else
408d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org      rb = surf->RenderBuffer;
40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   return rb;
41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgEGLBoolean
41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c,
41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                 EGLint attribute, EGLint *value)
41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   (void) drv;
41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   (void) dpy;
41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (!value)
42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return _eglError(EGL_BAD_PARAMETER, "eglQueryContext");
42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   switch (attribute) {
42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   case EGL_CONFIG_ID:
42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if (!c->Config)
42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      *value = c->Config->ConfigID;
42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      break;
42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   case EGL_CONTEXT_CLIENT_VERSION:
43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      *value = c->ClientMajorVersion;
43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      break;
43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   case EGL_CONTEXT_CLIENT_TYPE:
43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      *value = c->ClientAPI;
43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      break;
43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   case EGL_RENDER_BUFFER:
43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      *value = _eglQueryContextRenderBuffer(c);
43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      break;
43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   default:
43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
442d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org   return EGL_TRUE;
443d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org}
44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/**
44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Bind the context to the thread and return the previous context.
44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Note that the context may be NULL.
45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic _EGLContext *
45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org_eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t)
45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   EGLint apiIndex;
45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   _EGLContext *oldCtx;
45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   apiIndex = (ctx) ?
45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      _eglConvertApiToIndex(ctx->ClientAPI) : t->CurrentAPIIndex;
45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   oldCtx = t->CurrentContexts[apiIndex];
46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (ctx != oldCtx) {
46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if (oldCtx)
46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         oldCtx->Binding = NULL;
46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if (ctx)
46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         ctx->Binding = t;
46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      t->CurrentContexts[apiIndex] = ctx;
46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   return oldCtx;
47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/**
47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Return true if the given context and surfaces can be made current.
47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic EGLBoolean
47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org_eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   _EGLThreadInfo *t = _eglGetCurrentThread();
48145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   _EGLDisplay *dpy;
48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   EGLint conflict_api;
48345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
48445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (_eglIsCurrentThreadDummy())
48545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
48645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
48745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   /* this is easy */
48845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (!ctx) {
48945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      if (draw || read)
49045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org         return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return EGL_TRUE;
49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   }
49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   dpy = ctx->Resource.Display;
49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (!dpy->Extensions.KHR_surfaceless_context
49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org       && (draw == NULL || read == NULL))
49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org      return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
49845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
49945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   /*
50045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    * The spec says
50145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *
50245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    * "If ctx is current to some other thread, or if either draw or read are
50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    * bound to contexts in another thread, an EGL_BAD_ACCESS error is
50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    * generated."
50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *
50645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    * and
50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *
50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    * "at most one context may be bound to a particular surface at a given
50945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    * time"
51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    */
51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org   if (ctx->Binding && ctx->Binding != t)
512      return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
513   if (draw && draw->CurrentContext && draw->CurrentContext != ctx) {
514      if (draw->CurrentContext->Binding != t ||
515          draw->CurrentContext->ClientAPI != ctx->ClientAPI)
516         return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
517   }
518   if (read && read->CurrentContext && read->CurrentContext != ctx) {
519      if (read->CurrentContext->Binding != t ||
520          read->CurrentContext->ClientAPI != ctx->ClientAPI)
521         return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
522   }
523
524   /* simply require the configs to be equal */
525   if ((draw && draw->Config != ctx->Config) ||
526       (read && read->Config != ctx->Config))
527      return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
528
529   switch (ctx->ClientAPI) {
530   /* OpenGL and OpenGL ES are conflicting */
531   case EGL_OPENGL_ES_API:
532      conflict_api = EGL_OPENGL_API;
533      break;
534   case EGL_OPENGL_API:
535      conflict_api = EGL_OPENGL_ES_API;
536      break;
537   default:
538      conflict_api = -1;
539      break;
540   }
541
542   if (conflict_api >= 0 && _eglGetAPIContext(conflict_api))
543      return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
544
545   return EGL_TRUE;
546}
547
548
549/**
550 * Bind the context to the current thread and given surfaces.  Return the
551 * previous bound context and surfaces.  The caller should unreference the
552 * returned context and surfaces.
553 *
554 * Making a second call with the resources returned by the first call
555 * unsurprisingly undoes the first call, except for the resouce reference
556 * counts.
557 */
558EGLBoolean
559_eglBindContext(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read,
560                _EGLContext **old_ctx,
561                _EGLSurface **old_draw, _EGLSurface **old_read)
562{
563   _EGLThreadInfo *t = _eglGetCurrentThread();
564   _EGLContext *prev_ctx;
565   _EGLSurface *prev_draw, *prev_read;
566
567   if (!_eglCheckMakeCurrent(ctx, draw, read))
568      return EGL_FALSE;
569
570   /* increment refcounts before binding */
571   _eglGetContext(ctx);
572   _eglGetSurface(draw);
573   _eglGetSurface(read);
574
575   /* bind the new context */
576   prev_ctx = _eglBindContextToThread(ctx, t);
577
578   /* break previous bindings */
579   if (prev_ctx) {
580      prev_draw = prev_ctx->DrawSurface;
581      prev_read = prev_ctx->ReadSurface;
582
583      if (prev_draw)
584         prev_draw->CurrentContext = NULL;
585      if (prev_read)
586         prev_read->CurrentContext = NULL;
587
588      prev_ctx->DrawSurface = NULL;
589      prev_ctx->ReadSurface = NULL;
590   }
591   else {
592      prev_draw = prev_read = NULL;
593   }
594
595   /* establish new bindings */
596   if (ctx) {
597      if (draw)
598         draw->CurrentContext = ctx;
599      if (read)
600         read->CurrentContext = ctx;
601
602      ctx->DrawSurface = draw;
603      ctx->ReadSurface = read;
604   }
605
606   assert(old_ctx && old_draw && old_read);
607   *old_ctx = prev_ctx;
608   *old_draw = prev_draw;
609   *old_read = prev_read;
610
611   return EGL_TRUE;
612}
613