egl: deduplicate swap interval clamping logic
[mesa.git] / src / egl / main / eglsurface.c
index 231a5f01435bb66a97ae93fd31c70e62df958d3d..3bd14a8cd034e1c2d1583c4ef758cac6d65dafb1 100644 (file)
 #include "eglsurface.h"
 
 
-static void
-_eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
-{
-   EGLint bound = surf->Config->MaxSwapInterval;
-   if (interval >= bound) {
-      interval = bound;
-   }
-   else {
-      bound = surf->Config->MinSwapInterval;
-      if (interval < bound)
-         interval = bound;
-   }
-   surf->SwapInterval = interval;
-}
-
-
 /**
  * Parse the list of surface attributes and return the proper error code.
  */
@@ -262,9 +246,13 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
 {
    const char *func;
    EGLint renderBuffer = EGL_BACK_BUFFER;
-   EGLint swapBehavior = EGL_BUFFER_PRESERVED;
+   EGLint swapBehavior = EGL_BUFFER_DESTROYED;
    EGLint err;
 
+   /* Swap behavior can be preserved only if config supports this. */
+   if (conf->SurfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
+      swapBehavior = EGL_BUFFER_PRESERVED;
+
    switch (type) {
    case EGL_WINDOW_BIT:
       func = "eglCreateWindowSurface";
@@ -282,15 +270,14 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
       return EGL_FALSE;
    }
 
-   if ((conf->SurfaceType & type) == 0) {
+   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 _eglError(EGL_BAD_MATCH, func);
 
    _eglInitResource(&surf->Resource, sizeof(*surf), dpy);
    surf->Type = type;
    surf->Config = conf;
+   surf->Lost = EGL_FALSE;
 
    surf->Width = 0;
    surf->Height = 0;
@@ -312,9 +299,11 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
    surf->AspectRatio = EGL_UNKNOWN;
 
    surf->PostSubBufferSupportedNV = EGL_FALSE;
+   surf->SetDamageRegionCalled = EGL_FALSE;
+   surf->BufferAgeRead = EGL_FALSE;
 
    /* the default swap interval is 1 */
-   _eglClampSwapInterval(surf, 1);
+   surf->SwapInterval = 1;
 
    err = _eglParseSurfaceAttribList(surf, attrib_list);
    if (err != EGL_SUCCESS)
@@ -390,25 +379,32 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
       *value = surface->VGColorspace;
       break;
    case EGL_GL_COLORSPACE_KHR:
-      if (!dpy->Extensions.KHR_gl_colorspace) {
-         _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
-         return EGL_FALSE;
-      }
+      if (!dpy->Extensions.KHR_gl_colorspace)
+         return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
+
       *value = surface->GLColorspace;
       break;
    case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
       *value = surface->PostSubBufferSupportedNV;
       break;
    case EGL_BUFFER_AGE_EXT:
-      if (!dpy->Extensions.EXT_buffer_age) {
-         _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
+      if (!dpy->Extensions.EXT_buffer_age)
+         return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
+
+      _EGLContext *ctx = _eglGetCurrentContext();
+      EGLint result = drv->API.QueryBufferAge(drv, dpy, surface);
+      /* error happened */
+      if (result < 0)
          return EGL_FALSE;
-      }
-      *value = drv->API.QueryBufferAge(drv, dpy, surface);
+      if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+          ctx->DrawSurface != surface)
+         return _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
+
+      *value = result;
+      surface->BufferAgeRead = EGL_TRUE;
       break;
    default:
-      _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
-      return EGL_FALSE;
+      return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
    }
 
    return EGL_TRUE;
@@ -495,25 +491,17 @@ _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
    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;
-   }
+   if (!(surface->Type & texture_type))
+      return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
 
-   if (surface->TextureFormat == EGL_NO_TEXTURE) {
-      _eglError(EGL_BAD_MATCH, "eglBindTexImage");
-      return EGL_FALSE;
-   }
+   if (surface->TextureFormat == EGL_NO_TEXTURE)
+      return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
 
-   if (surface->TextureTarget == EGL_NO_TEXTURE) {
-      _eglError(EGL_BAD_MATCH, "eglBindTexImage");
-      return EGL_FALSE;
-   }
+   if (surface->TextureTarget == EGL_NO_TEXTURE)
+      return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
 
-   if (buffer != EGL_BACK_BUFFER) {
-      _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
-      return EGL_FALSE;
-   }
+   if (buffer != EGL_BACK_BUFFER)
+      return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
 
    surface->BoundToTexture = EGL_TRUE;
 
@@ -521,14 +509,39 @@ _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
 }
 
 EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
+_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
                     EGLint buffer)
 {
-   /* TODO: do basic error checking and return success/fail.
+   /* Just do basic error checking and return success/fail.
     * Drivers must implement the real stuff.
     */
 
-  return EGL_TRUE;
+   EGLint texture_type = EGL_PBUFFER_BIT;
+
+   if (surf == EGL_NO_SURFACE)
+      return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
+
+   if (!surf->BoundToTexture)
+   {
+      /* Not an error, simply nothing to do */
+      return EGL_TRUE;
+   }
+
+   if (surf->TextureFormat == EGL_NO_TEXTURE)
+      return _eglError(EGL_BAD_MATCH, "eglReleaseTexImage");
+
+   if (buffer != EGL_BACK_BUFFER)
+      return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
+
+   if (dpy->Extensions.NOK_texture_from_pixmap)
+      texture_type |= EGL_PIXMAP_BIT;
+
+   if (!(surf->Type & texture_type))
+      return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
+
+   surf->BoundToTexture = EGL_FALSE;
+
+   return EGL_TRUE;
 }
 
 
@@ -536,6 +549,5 @@ EGLBoolean
 _eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
                  EGLint interval)
 {
-   _eglClampSwapInterval(surf, interval);
    return EGL_TRUE;
 }