egl: add copyright notices
[mesa.git] / src / egl / main / eglsurface.c
index 394705112762a4cbdbc1f32e7da55b2ba3a6aa52..c9cfb01388e60ff4a82fabb53a6f51c8648bdca0 100644 (file)
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
 /**
  * Surface-related functions.
  */
 #include "egldisplay.h"
 #include "eglcontext.h"
 #include "eglconfig.h"
-#include "egldriver.h"
-#include "eglglobals.h"
-#include "eglhash.h"
+#include "eglcurrent.h"
 #include "egllog.h"
 #include "eglsurface.h"
 
 
-/**
- * Do error check on parameters and initialize the given _EGLSurface object.
- * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
- */
-EGLBoolean
-_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
-                _EGLConfig *conf, const EGLint *attrib_list)
+static void
+_eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
 {
-   const char *func;
-   EGLint width = 0, height = 0, largest = 0;
-   EGLint texFormat = EGL_NO_TEXTURE, texTarget = EGL_NO_TEXTURE;
-   EGLint mipmapTex = EGL_FALSE;
-   EGLint renderBuffer = EGL_BACK_BUFFER;
-#ifdef EGL_VERSION_1_2
-   EGLint colorspace = EGL_COLORSPACE_sRGB;
-   EGLint alphaFormat = EGL_ALPHA_FORMAT_NONPRE;
-#endif
-   EGLint i;
-
-   switch (type) {
-   case EGL_WINDOW_BIT:
-      func = "eglCreateWindowSurface";
-      break;
-   case EGL_PIXMAP_BIT:
-      func = "eglCreatePixmapSurface";
-      renderBuffer = EGL_SINGLE_BUFFER;
-      break;
-   case EGL_PBUFFER_BIT:
-      func = "eglCreatePBufferSurface";
-      break;
-   case EGL_SCREEN_BIT_MESA:
-      func = "eglCreateScreenSurface";
-      renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
-      break;
-   default:
-      _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
-      return EGL_FALSE;
+   EGLint bound = surf->Config->MaxSwapInterval;
+   if (interval >= bound) {
+      interval = bound;
    }
-
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, func);
-      return EGL_FALSE;
+   else {
+      bound = surf->Config->MinSwapInterval;
+      if (interval < bound)
+         interval = bound;
    }
+   surf->SwapInterval = interval;
+}
 
-   if ((GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) & type) == 0) {
-      /* The config can't be used to create a surface of this type */
-      _eglError(EGL_BAD_CONFIG, func);
-      return EGL_FALSE;
-   }
 
-   /*
-    * Parse attribute list.  Different kinds of surfaces support different
-    * attributes.
-    */
-   for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
-      switch (attrib_list[i]) {
+#ifdef EGL_MESA_screen_surface
+static EGLint
+_eglParseScreenSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
+{
+   EGLint i, err = EGL_SUCCESS;
+
+   if (!attrib_list)
+      return EGL_SUCCESS;
+
+   for (i = 0; attrib_list[i] != EGL_NONE; i++) {
+      EGLint attr = attrib_list[i++];
+      EGLint val = attrib_list[i];
+
+      switch (attr) {
       case EGL_WIDTH:
-         if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) {
-            width = attrib_list[++i];
-         }
-         else {
-            _eglError(EGL_BAD_ATTRIBUTE, func);
-            return EGL_FALSE;
+         if (val < 0) {
+            err = EGL_BAD_PARAMETER;
+            break;
          }
+         surf->Width = val;
          break;
       case EGL_HEIGHT:
-         if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) {
-            height = attrib_list[++i];
-         }
-         else {
-            _eglError(EGL_BAD_ATTRIBUTE, func);
-            return EGL_FALSE;
+         if (val < 0) {
+            err = EGL_BAD_PARAMETER;
+            break;
          }
+         surf->Height = val;
          break;
-      case EGL_LARGEST_PBUFFER:
-         if (type == EGL_PBUFFER_BIT) {
-            largest = attrib_list[++i];
+      default:
+         err = EGL_BAD_ATTRIBUTE;
+         break;
+      }
+
+      if (err != EGL_SUCCESS) {
+         _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
+         break;
+      }
+   }
+
+   return err;
+}
+#endif /* EGL_MESA_screen_surface */
+
+
+/**
+ * Parse the list of surface attributes and return the proper error code.
+ */
+static EGLint
+_eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
+{
+   _EGLDisplay *dpy = surf->Resource.Display;
+   EGLint type = surf->Type;
+   EGLint texture_type = EGL_PBUFFER_BIT;
+   EGLint i, err = EGL_SUCCESS;
+
+   if (!attrib_list)
+      return EGL_SUCCESS;
+
+#ifdef EGL_MESA_screen_surface
+   if (type == EGL_SCREEN_BIT_MESA)
+      return _eglParseScreenSurfaceAttribList(surf, attrib_list);
+#endif
+
+   if (dpy->Extensions.NOK_texture_from_pixmap)
+      texture_type |= EGL_PIXMAP_BIT;
+
+   for (i = 0; attrib_list[i] != EGL_NONE; i++) {
+      EGLint attr = attrib_list[i++];
+      EGLint val = attrib_list[i];
+
+      switch (attr) {
+      /* common attributes */
+      case EGL_VG_COLORSPACE:
+         switch (val) {
+         case EGL_VG_COLORSPACE_sRGB:
+         case EGL_VG_COLORSPACE_LINEAR:
+            break;
+         default:
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
-         else {
-            _eglError(EGL_BAD_ATTRIBUTE, func);
-            return EGL_FALSE;
+         if (err != EGL_SUCCESS)
+            break;
+         surf->VGColorspace = val;
+         break;
+      case EGL_VG_ALPHA_FORMAT:
+         switch (val) {
+         case EGL_VG_ALPHA_FORMAT_NONPRE:
+         case EGL_VG_ALPHA_FORMAT_PRE:
+            break;
+         default:
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
+         if (err != EGL_SUCCESS)
+            break;
+         surf->VGAlphaFormat = val;
          break;
-      case EGL_TEXTURE_FORMAT:
-         if (type == EGL_PBUFFER_BIT) {
-            texFormat = attrib_list[++i];
+      /* window surface attributes */
+      case EGL_RENDER_BUFFER:
+         if (type != EGL_WINDOW_BIT) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
-         else {
-            _eglError(EGL_BAD_ATTRIBUTE, func);
-            return EGL_FALSE;
+         if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
+         surf->RenderBuffer = val;
          break;
-      case EGL_TEXTURE_TARGET:
-         if (type == EGL_PBUFFER_BIT) {
-            texTarget = attrib_list[++i];
+      /* pbuffer surface attributes */
+      case EGL_WIDTH:
+         if (type != EGL_PBUFFER_BIT) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
-         else {
-            _eglError(EGL_BAD_ATTRIBUTE, func);
-            return EGL_FALSE;
+         if (val < 0) {
+            err = EGL_BAD_PARAMETER;
+            break;
          }
+         surf->Width = val;
          break;
-      case EGL_MIPMAP_TEXTURE:
-         if (type == EGL_PBUFFER_BIT) {
-            mipmapTex = attrib_list[++i];
+      case EGL_HEIGHT:
+         if (type != EGL_PBUFFER_BIT) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
-         else {
-            _eglError(EGL_BAD_ATTRIBUTE, func);
-            return EGL_FALSE;
+         if (val < 0) {
+            err = EGL_BAD_PARAMETER;
+            break;
          }
+         surf->Height = val;
          break;
-#ifdef EGL_VERSION_1_2
-      case EGL_RENDER_BUFFER:
-         if (type == EGL_WINDOW_BIT) {
-            renderBuffer = attrib_list[++i];
-            if (renderBuffer != EGL_BACK_BUFFER &&
-                renderBuffer != EGL_SINGLE_BUFFER) {
-               _eglError(EGL_BAD_ATTRIBUTE, func);
-               return EGL_FALSE;
-            }
-         }
-         else {
-            _eglError(EGL_BAD_ATTRIBUTE, func);
-            return EGL_FALSE;
+      case EGL_LARGEST_PBUFFER:
+         if (type != EGL_PBUFFER_BIT) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
+         surf->LargestPbuffer = !!val;
          break;
-      case EGL_COLORSPACE:
-         if (type == EGL_WINDOW_BIT ||
-             type == EGL_PBUFFER_BIT ||
-             type == EGL_PIXMAP_BIT) {
-            colorspace = attrib_list[++i];
-            if (colorspace != EGL_COLORSPACE_sRGB &&
-                colorspace != EGL_COLORSPACE_LINEAR) {
-               _eglError(EGL_BAD_ATTRIBUTE, func);
-               return EGL_FALSE;
-            }
+      /* for eglBindTexImage */
+      case EGL_TEXTURE_FORMAT:
+         if (!(type & texture_type)) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
-         else {
-            _eglError(EGL_BAD_ATTRIBUTE, func);
-            return EGL_FALSE;
+         switch (val) {
+         case EGL_TEXTURE_RGB:
+         case EGL_TEXTURE_RGBA:
+         case EGL_NO_TEXTURE:
+            break;
+         default:
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
+         if (err != EGL_SUCCESS)
+            break;
+         surf->TextureFormat = val;
          break;
-      case EGL_ALPHA_FORMAT:
-         if (type == EGL_WINDOW_BIT ||
-             type == EGL_PBUFFER_BIT ||
-             type == EGL_PIXMAP_BIT) {
-            alphaFormat = attrib_list[++i];
-            if (alphaFormat != EGL_ALPHA_FORMAT_NONPRE &&
-                alphaFormat != EGL_ALPHA_FORMAT_PRE) {
-               _eglError(EGL_BAD_ATTRIBUTE, func);
-               return EGL_FALSE;
-            }
+      case EGL_TEXTURE_TARGET:
+         if (!(type & texture_type)) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
-         else {
-            _eglError(EGL_BAD_ATTRIBUTE, func);
-            return EGL_FALSE;
+         switch (val) {
+         case EGL_TEXTURE_2D:
+         case EGL_NO_TEXTURE:
+            break;
+         default:
+            err = EGL_BAD_ATTRIBUTE;
+            break;
          }
+         if (err != EGL_SUCCESS)
+            break;
+         surf->TextureTarget = val;
          break;
-
-#endif /* EGL_VERSION_1_2 */
+      case EGL_MIPMAP_TEXTURE:
+         if (!(type & texture_type)) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
+         }
+         surf->MipmapTexture = !!val;
+         break;
+      /* no pixmap surface specific attributes */
       default:
-         _eglError(EGL_BAD_ATTRIBUTE, func);
-         return EGL_FALSE;
+         err = EGL_BAD_ATTRIBUTE;
+         break;
       }
-   }
 
-   if (width < 0 || height < 0) {
-      _eglError(EGL_BAD_ATTRIBUTE, func);
-      return EGL_FALSE;
+      if (err != EGL_SUCCESS) {
+         _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
+         break;
+      }
    }
 
-   memset(surf, 0, sizeof(_EGLSurface));
-   surf->Config = conf;
-   surf->Type = type;
-   surf->Width = width;
-   surf->Height = height;
-   surf->TextureFormat = texFormat;
-   surf->TextureTarget = texTarget;
-   surf->MipmapTexture = mipmapTex;
-   surf->MipmapLevel = 0;
-   surf->SwapInterval = 0;
-#ifdef EGL_VERSION_1_2
-   surf->SwapBehavior = EGL_BUFFER_DESTROYED; /* XXX ok? */
-   surf->HorizontalResolution = EGL_UNKNOWN; /* set by caller */
-   surf->VerticalResolution = EGL_UNKNOWN; /* set by caller */
-   surf->AspectRatio = EGL_UNKNOWN; /* set by caller */
-   surf->RenderBuffer = renderBuffer;
-   surf->AlphaFormat = alphaFormat;
-   surf->Colorspace = colorspace;
-#endif
-
-   return EGL_TRUE;
+   return err;
 }
 
 
+/**
+ * Do error check on parameters and initialize the given _EGLSurface object.
+ * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
+ */
 EGLBoolean
-_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+_eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
+                _EGLConfig *conf, const EGLint *attrib_list)
 {
-   /* Basically just do error checking here.  Drivers have to do the
-    * actual buffer swap.
-    */
-   _EGLSurface *surface = _eglLookupSurface(draw);
-   if (surface == NULL) {
-      _eglError(EGL_BAD_SURFACE, "eglSwapBuffers");
+   const char *func;
+   EGLint renderBuffer = EGL_BACK_BUFFER;
+   EGLint err;
+
+   switch (type) {
+   case EGL_WINDOW_BIT:
+      func = "eglCreateWindowSurface";
+      break;
+   case EGL_PIXMAP_BIT:
+      func = "eglCreatePixmapSurface";
+      renderBuffer = EGL_SINGLE_BUFFER;
+      break;
+   case EGL_PBUFFER_BIT:
+      func = "eglCreatePBufferSurface";
+      break;
+#ifdef EGL_MESA_screen_surface
+   case EGL_SCREEN_BIT_MESA:
+      func = "eglCreateScreenSurface";
+      renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
+      break;
+#endif
+   default:
+      _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
+      return EGL_FALSE;
+   }
+
+   if ((conf->SurfaceType & type) == 0) {
+      /* The config can't be used to create a surface of this type */
+      _eglError(EGL_BAD_CONFIG, func);
       return EGL_FALSE;
    }
-   return EGL_TRUE;
-}
 
+   _eglInitResource(&surf->Resource, sizeof(*surf), dpy);
+   surf->Type = type;
+   surf->Config = conf;
 
-EGLBoolean
-_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
-                NativePixmapType target)
-{
-   /* copy surface to native pixmap */
-   /* All implementation burdon for this is in the device driver */
-   return EGL_FALSE;
+   surf->Width = 0;
+   surf->Height = 0;
+   surf->TextureFormat = EGL_NO_TEXTURE;
+   surf->TextureTarget = EGL_NO_TEXTURE;
+   surf->MipmapTexture = EGL_FALSE;
+   surf->LargestPbuffer = EGL_FALSE;
+   surf->RenderBuffer = renderBuffer;
+   surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
+   surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
+
+   surf->MipmapLevel = 0;
+   surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
+   surf->SwapBehavior = EGL_BUFFER_DESTROYED;
+
+   surf->HorizontalResolution = EGL_UNKNOWN;
+   surf->VerticalResolution = EGL_UNKNOWN;
+   surf->AspectRatio = EGL_UNKNOWN;
+
+   /* the default swap interval is 1 */
+   _eglClampSwapInterval(surf, 1);
+
+   err = _eglParseSurfaceAttribList(surf, attrib_list);
+   if (err != EGL_SUCCESS)
+      return _eglError(err, func);
+
+   return EGL_TRUE;
 }
 
 
 EGLBoolean
-_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
                  EGLint attribute, EGLint *value)
 {
-   _EGLSurface *surface = _eglLookupSurface(surf);
-   if (surface == NULL) {
-      _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
-      return EGL_FALSE;
-   }
    switch (attribute) {
    case EGL_WIDTH:
       *value = surface->Width;
-      return EGL_TRUE;
+      break;
    case EGL_HEIGHT:
       *value = surface->Height;
-      return EGL_TRUE;
+      break;
    case EGL_CONFIG_ID:
-      *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
-      return EGL_TRUE;
+      *value = surface->Config->ConfigID;
+      break;
    case EGL_LARGEST_PBUFFER:
-      *value = drv->LargestPbuffer;
-      return EGL_TRUE;
-   case EGL_SURFACE_TYPE:
-      *value = surface->Type;
-      return EGL_TRUE;
-#ifdef EGL_VERSION_1_1
+      *value = surface->LargestPbuffer;
+      break;
    case EGL_TEXTURE_FORMAT:
       /* texture attributes: only for pbuffers, no error otherwise */
       if (surface->Type == EGL_PBUFFER_BIT)
          *value = surface->TextureFormat;
-      return EGL_TRUE;
+      break;
    case EGL_TEXTURE_TARGET:
       if (surface->Type == EGL_PBUFFER_BIT)
          *value = surface->TextureTarget;
-      return EGL_TRUE;
+      break;
    case EGL_MIPMAP_TEXTURE:
       if (surface->Type == EGL_PBUFFER_BIT)
          *value = surface->MipmapTexture;
-      return EGL_TRUE;
+      break;
    case EGL_MIPMAP_LEVEL:
       if (surface->Type == EGL_PBUFFER_BIT)
          *value = surface->MipmapLevel;
-      return EGL_TRUE;
-#endif /* EGL_VERSION_1_1 */
-#ifdef EGL_VERSION_1_2
+      break;
    case EGL_SWAP_BEHAVIOR:
       *value = surface->SwapBehavior;
-      return EGL_TRUE;
+      break;
    case EGL_RENDER_BUFFER:
       *value = surface->RenderBuffer;
-      return EGL_TRUE;
+      break;
    case EGL_PIXEL_ASPECT_RATIO:
       *value = surface->AspectRatio;
-      return EGL_TRUE;
+      break;
    case EGL_HORIZONTAL_RESOLUTION:
       *value = surface->HorizontalResolution;
-      return EGL_TRUE;
+      break;
    case EGL_VERTICAL_RESOLUTION:
       *value = surface->VerticalResolution;
-      return EGL_TRUE;
-   case EGL_ALPHA_FORMAT:
-      *value = surface->AlphaFormat;
-      return EGL_TRUE;
-   case EGL_COLORSPACE:
-      *value = surface->Colorspace;
-      return EGL_TRUE;
-#endif /* EGL_VERSION_1_2 */
+      break;
+   case EGL_MULTISAMPLE_RESOLVE:
+      *value = surface->MultisampleResolve;
+      break;
+   case EGL_VG_ALPHA_FORMAT:
+      *value = surface->VGAlphaFormat;
+      break;
+   case EGL_VG_COLORSPACE:
+      *value = surface->VGColorspace;
+      break;
    default:
       _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
       return EGL_FALSE;
    }
-}
-
-
-/**
- * Example function - drivers should do a proper implementation.
- */
-EGLSurface
-_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
-                        NativeWindowType window, const EGLint *attrib_list)
-{
-#if 0 /* THIS IS JUST EXAMPLE CODE */
-   _EGLSurface *surf;
-   _EGLConfig *conf;
-
-   conf = _eglLookupConfig(drv, dpy, config);
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, "eglCreateWindowSurface");
-      return EGL_NO_SURFACE;
-   }
-
-   surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
-   if (!surf)
-      return EGL_NO_SURFACE;
-
-   if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) {
-      free(surf);
-      return EGL_NO_SURFACE;
-   }
-
-   return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
-#endif
-   return EGL_NO_SURFACE;
-}
-
-
-/**
- * Example function - drivers should do a proper implementation.
- */
-EGLSurface
-_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
-                        NativePixmapType pixmap, const EGLint *attrib_list)
-{
-#if 0 /* THIS IS JUST EXAMPLE CODE */
-   _EGLSurface *surf;
-   _EGLConfig *conf;
-
-   conf = _eglLookupConfig(drv, dpy, config);
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
-      return EGL_NO_SURFACE;
-   }
-
-   surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
-   if (!surf)
-      return EGL_NO_SURFACE;
-
-   if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) {
-      free(surf);
-      return EGL_NO_SURFACE;
-   }
-
-   return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
-#endif
-   return EGL_NO_SURFACE;
-}
-
-
-/**
- * Example function - drivers should do a proper implementation.
- */
-EGLSurface
-_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
-                         const EGLint *attrib_list)
-{
-#if 0 /* THIS IS JUST EXAMPLE CODE */
-   _EGLSurface *surf;
-   _EGLConfig *conf;
-
-   conf = _eglLookupConfig(drv, dpy, config);
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
-      return EGL_NO_SURFACE;
-   }
-
-   surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
-   if (!surf)
-      return EGL_NO_SURFACE;
-
-   if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) {
-      free(surf);
-      return EGL_NO_SURFACE;
-   }
-
-   return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
-#endif
-   return EGL_NO_SURFACE;
-}
 
-
-/**
- * Default fallback routine - drivers should usually override this.
- */
-EGLBoolean
-_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
-{
-   _EGLSurface *surf = _eglLookupSurface(surface);
-   if (surf) {
-      _eglUnlinkSurface(surf);
-      if (!_eglIsSurfaceBound(surf))
-         free(surf);
-      return EGL_TRUE;
-   }
-   else {
-      _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
-      return EGL_FALSE;
-   }
+   return EGL_TRUE;
 }
 
 
@@ -429,38 +403,80 @@ _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
  * Default fallback routine - drivers might override this.
  */
 EGLBoolean
-_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
                   EGLint attribute, EGLint value)
 {
-   _EGLSurface *surface = _eglLookupSurface(surf);
-
-   if (surface == NULL) {
-      _eglError(EGL_BAD_SURFACE, "eglSurfaceAttrib");
-      return EGL_FALSE;
-   }
+   EGLint confval;
+   EGLint err = EGL_SUCCESS;
 
    switch (attribute) {
    case EGL_MIPMAP_LEVEL:
+      confval = surface->Config->RenderableType;
+      if (!(confval & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT))) {
+         err = EGL_BAD_PARAMETER;
+         break;
+      }
       surface->MipmapLevel = value;
       break;
+   case EGL_MULTISAMPLE_RESOLVE:
+      switch (value) {
+      case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
+         break;
+      case EGL_MULTISAMPLE_RESOLVE_BOX:
+         confval = surface->Config->SurfaceType;
+         if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
+            err = EGL_BAD_MATCH;
+         break;
+      default:
+         err = EGL_BAD_ATTRIBUTE;
+         break;
+      }
+      if (err != EGL_SUCCESS)
+         break;
+      surface->MultisampleResolve = value;
+      break;
+   case EGL_SWAP_BEHAVIOR:
+      switch (value) {
+      case EGL_BUFFER_DESTROYED:
+         break;
+      case EGL_BUFFER_PRESERVED:
+         confval = surface->Config->SurfaceType;
+         if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
+            err = EGL_BAD_MATCH;
+         break;
+      default:
+         err = EGL_BAD_ATTRIBUTE;
+         break;
+      }
+      if (err != EGL_SUCCESS)
+         break;
+      surface->SwapBehavior = value;
+      break;
    default:
-      _eglError(EGL_BAD_ATTRIBUTE, "eglSurfaceAttrib");
-      return EGL_FALSE;
+      err = EGL_BAD_ATTRIBUTE;
+      break;
    }
+
+   if (err != EGL_SUCCESS)
+      return _eglError(err, "eglSurfaceAttrib");
    return EGL_TRUE;
 }
 
 
 EGLBoolean
-_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
                  EGLint buffer)
 {
+   EGLint texture_type = EGL_PBUFFER_BIT;
+
    /* Just do basic error checking and return success/fail.
     * Drivers must implement the real stuff.
     */
-   _EGLSurface *surface = _eglLookupSurface(surf);
 
-   if (!surface || surface->Type != EGL_PBUFFER_BIT) {
+   if (dpy->Extensions.NOK_texture_from_pixmap)
+      texture_type |= EGL_PIXMAP_BIT;
+
+   if (!(surface->Type & texture_type)) {
       _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
       return EGL_FALSE;
    }
@@ -470,81 +486,26 @@ _eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
       return EGL_FALSE;
    }
 
-   if (buffer != EGL_BACK_BUFFER) {
-      _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
-      return EGL_FALSE;
-   }
-
-   surface->BoundToTexture = EGL_TRUE;
-
-   return EGL_TRUE;
-}
-
-
-EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
-                    EGLint buffer)
-{
-   /* Just do basic error checking and return success/fail.
-    * Drivers must implement the real stuff.
-    */
-   _EGLSurface *surface = _eglLookupSurface(surf);
-
-   if (!surface || surface->Type != EGL_PBUFFER_BIT) {
-      _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
-      return EGL_FALSE;
-   }
-
-   if (surface->TextureFormat == EGL_NO_TEXTURE) {
+   if (surface->TextureTarget == EGL_NO_TEXTURE) {
       _eglError(EGL_BAD_MATCH, "eglBindTexImage");
       return EGL_FALSE;
    }
 
    if (buffer != EGL_BACK_BUFFER) {
-      _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
-      return EGL_FALSE;
-   }
-
-   if (!surface->BoundToTexture) {
-      _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
+      _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
       return EGL_FALSE;
    }
 
-   surface->BoundToTexture = EGL_FALSE;
+   surface->BoundToTexture = EGL_TRUE;
 
    return EGL_TRUE;
 }
 
 
 EGLBoolean
-_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
+_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
+                 EGLint interval)
 {
-   _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
-   if (surf == NULL) {
-      _eglError(EGL_BAD_SURFACE, "eglSwapInterval");
-      return EGL_FALSE;
-   }
-   surf->SwapInterval = interval;
+   _eglClampSwapInterval(surf, interval);
    return EGL_TRUE;
 }
-
-
-#ifdef EGL_VERSION_1_2
-
-/**
- * Example function - drivers should do a proper implementation.
- */
-EGLSurface
-_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
-                                  EGLenum buftype, EGLClientBuffer buffer,
-                                  EGLConfig config, const EGLint *attrib_list)
-{
-   if (buftype != EGL_OPENVG_IMAGE) {
-      _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
-      return EGL_NO_SURFACE;
-   }
-
-   return EGL_NO_SURFACE;
-}
-
-#endif /* EGL_VERSION_1_2 */