Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 VMware, Inc.
  4.  * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
  5.  * Copyright 2010 LunarG, Inc.
  6.  * All Rights Reserved.
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the
  10.  * "Software"), to deal in the Software without restriction, including
  11.  * without limitation the rights to use, copy, modify, merge, publish,
  12.  * distribute, sub license, and/or sell copies of the Software, and to
  13.  * permit persons to whom the Software is furnished to do so, subject to
  14.  * the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice (including the
  17.  * next paragraph) shall be included in all copies or substantial portions
  18.  * of the Software.
  19.  *
  20.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  23.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  25.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  26.  * DEALINGS IN THE SOFTWARE.
  27.  *
  28.  **************************************************************************/
  29.  
  30.  
  31. /**
  32.  * Surface-related functions.
  33.  */
  34.  
  35.  
  36. #include <assert.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include "egldisplay.h"
  40. #include "egldriver.h"
  41. #include "eglcontext.h"
  42. #include "eglconfig.h"
  43. #include "eglcurrent.h"
  44. #include "egllog.h"
  45. #include "eglsurface.h"
  46.  
  47.  
  48. static void
  49. _eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
  50. {
  51.    EGLint bound = surf->Config->MaxSwapInterval;
  52.    if (interval >= bound) {
  53.       interval = bound;
  54.    }
  55.    else {
  56.       bound = surf->Config->MinSwapInterval;
  57.       if (interval < bound)
  58.          interval = bound;
  59.    }
  60.    surf->SwapInterval = interval;
  61. }
  62.  
  63.  
  64. /**
  65.  * Parse the list of surface attributes and return the proper error code.
  66.  */
  67. static EGLint
  68. _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
  69. {
  70.    _EGLDisplay *dpy = surf->Resource.Display;
  71.    EGLint type = surf->Type;
  72.    EGLint texture_type = EGL_PBUFFER_BIT;
  73.    EGLint i, err = EGL_SUCCESS;
  74.  
  75.    if (!attrib_list)
  76.       return EGL_SUCCESS;
  77.  
  78.    if (dpy->Extensions.NOK_texture_from_pixmap)
  79.       texture_type |= EGL_PIXMAP_BIT;
  80.  
  81.    for (i = 0; attrib_list[i] != EGL_NONE; i++) {
  82.       EGLint attr = attrib_list[i++];
  83.       EGLint val = attrib_list[i];
  84.  
  85.       switch (attr) {
  86.       /* common attributes */
  87.       case EGL_VG_COLORSPACE:
  88.          switch (val) {
  89.          case EGL_VG_COLORSPACE_sRGB:
  90.          case EGL_VG_COLORSPACE_LINEAR:
  91.             break;
  92.          default:
  93.             err = EGL_BAD_ATTRIBUTE;
  94.             break;
  95.          }
  96.          if (err != EGL_SUCCESS)
  97.             break;
  98.          surf->VGColorspace = val;
  99.          break;
  100.       case EGL_VG_ALPHA_FORMAT:
  101.          switch (val) {
  102.          case EGL_VG_ALPHA_FORMAT_NONPRE:
  103.          case EGL_VG_ALPHA_FORMAT_PRE:
  104.             break;
  105.          default:
  106.             err = EGL_BAD_ATTRIBUTE;
  107.             break;
  108.          }
  109.          if (err != EGL_SUCCESS)
  110.             break;
  111.          surf->VGAlphaFormat = val;
  112.          break;
  113.       /* window surface attributes */
  114.       case EGL_RENDER_BUFFER:
  115.          if (type != EGL_WINDOW_BIT) {
  116.             err = EGL_BAD_ATTRIBUTE;
  117.             break;
  118.          }
  119.          if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) {
  120.             err = EGL_BAD_ATTRIBUTE;
  121.             break;
  122.          }
  123.          surf->RenderBuffer = val;
  124.          break;
  125.       case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
  126.          if (!dpy->Extensions.NV_post_sub_buffer ||
  127.              type != EGL_WINDOW_BIT) {
  128.             err = EGL_BAD_ATTRIBUTE;
  129.             break;
  130.          }
  131.          if (val != EGL_TRUE && val != EGL_FALSE) {
  132.             err = EGL_BAD_PARAMETER;
  133.             break;
  134.          }
  135.          surf->PostSubBufferSupportedNV = val;
  136.          break;
  137.       /* pbuffer surface attributes */
  138.       case EGL_WIDTH:
  139.          if (type != EGL_PBUFFER_BIT) {
  140.             err = EGL_BAD_ATTRIBUTE;
  141.             break;
  142.          }
  143.          if (val < 0) {
  144.             err = EGL_BAD_PARAMETER;
  145.             break;
  146.          }
  147.          surf->Width = val;
  148.          break;
  149.       case EGL_HEIGHT:
  150.          if (type != EGL_PBUFFER_BIT) {
  151.             err = EGL_BAD_ATTRIBUTE;
  152.             break;
  153.          }
  154.          if (val < 0) {
  155.             err = EGL_BAD_PARAMETER;
  156.             break;
  157.          }
  158.          surf->Height = val;
  159.          break;
  160.       case EGL_LARGEST_PBUFFER:
  161.          if (type != EGL_PBUFFER_BIT) {
  162.             err = EGL_BAD_ATTRIBUTE;
  163.             break;
  164.          }
  165.          surf->LargestPbuffer = !!val;
  166.          break;
  167.       /* for eglBindTexImage */
  168.       case EGL_TEXTURE_FORMAT:
  169.          if (!(type & texture_type)) {
  170.             err = EGL_BAD_ATTRIBUTE;
  171.             break;
  172.          }
  173.          switch (val) {
  174.          case EGL_TEXTURE_RGB:
  175.          case EGL_TEXTURE_RGBA:
  176.          case EGL_NO_TEXTURE:
  177.             break;
  178.          default:
  179.             err = EGL_BAD_ATTRIBUTE;
  180.             break;
  181.          }
  182.          if (err != EGL_SUCCESS)
  183.             break;
  184.          surf->TextureFormat = val;
  185.          break;
  186.       case EGL_TEXTURE_TARGET:
  187.          if (!(type & texture_type)) {
  188.             err = EGL_BAD_ATTRIBUTE;
  189.             break;
  190.          }
  191.          switch (val) {
  192.          case EGL_TEXTURE_2D:
  193.          case EGL_NO_TEXTURE:
  194.             break;
  195.          default:
  196.             err = EGL_BAD_ATTRIBUTE;
  197.             break;
  198.          }
  199.          if (err != EGL_SUCCESS)
  200.             break;
  201.          surf->TextureTarget = val;
  202.          break;
  203.       case EGL_MIPMAP_TEXTURE:
  204.          if (!(type & texture_type)) {
  205.             err = EGL_BAD_ATTRIBUTE;
  206.             break;
  207.          }
  208.          surf->MipmapTexture = !!val;
  209.          break;
  210.       /* no pixmap surface specific attributes */
  211.       default:
  212.          err = EGL_BAD_ATTRIBUTE;
  213.          break;
  214.       }
  215.  
  216.       if (err != EGL_SUCCESS) {
  217.          _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
  218.          break;
  219.       }
  220.    }
  221.  
  222.    return err;
  223. }
  224.  
  225.  
  226. /**
  227.  * Do error check on parameters and initialize the given _EGLSurface object.
  228.  * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
  229.  */
  230. EGLBoolean
  231. _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
  232.                 _EGLConfig *conf, const EGLint *attrib_list)
  233. {
  234.    const char *func;
  235.    EGLint renderBuffer = EGL_BACK_BUFFER;
  236.    EGLint swapBehavior = EGL_BUFFER_PRESERVED;
  237.    EGLint err;
  238.  
  239.    switch (type) {
  240.    case EGL_WINDOW_BIT:
  241.       func = "eglCreateWindowSurface";
  242.       swapBehavior = EGL_BUFFER_DESTROYED;
  243.       break;
  244.    case EGL_PIXMAP_BIT:
  245.       func = "eglCreatePixmapSurface";
  246.       renderBuffer = EGL_SINGLE_BUFFER;
  247.       break;
  248.    case EGL_PBUFFER_BIT:
  249.       func = "eglCreatePBufferSurface";
  250.       break;
  251.    default:
  252.       _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
  253.       return EGL_FALSE;
  254.    }
  255.  
  256.    if ((conf->SurfaceType & type) == 0) {
  257.       /* The config can't be used to create a surface of this type */
  258.       _eglError(EGL_BAD_CONFIG, func);
  259.       return EGL_FALSE;
  260.    }
  261.  
  262.    _eglInitResource(&surf->Resource, sizeof(*surf), dpy);
  263.    surf->Type = type;
  264.    surf->Config = conf;
  265.  
  266.    surf->Width = 0;
  267.    surf->Height = 0;
  268.    surf->TextureFormat = EGL_NO_TEXTURE;
  269.    surf->TextureTarget = EGL_NO_TEXTURE;
  270.    surf->MipmapTexture = EGL_FALSE;
  271.    surf->LargestPbuffer = EGL_FALSE;
  272.    surf->RenderBuffer = renderBuffer;
  273.    surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
  274.    surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
  275.  
  276.    surf->MipmapLevel = 0;
  277.    surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
  278.    surf->SwapBehavior = swapBehavior;
  279.  
  280.    surf->HorizontalResolution = EGL_UNKNOWN;
  281.    surf->VerticalResolution = EGL_UNKNOWN;
  282.    surf->AspectRatio = EGL_UNKNOWN;
  283.  
  284.    surf->PostSubBufferSupportedNV = EGL_FALSE;
  285.  
  286.    /* the default swap interval is 1 */
  287.    _eglClampSwapInterval(surf, 1);
  288.  
  289.    err = _eglParseSurfaceAttribList(surf, attrib_list);
  290.    if (err != EGL_SUCCESS)
  291.       return _eglError(err, func);
  292.  
  293.    return EGL_TRUE;
  294. }
  295.  
  296.  
  297. EGLBoolean
  298. _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
  299.                  EGLint attribute, EGLint *value)
  300. {
  301.    switch (attribute) {
  302.    case EGL_WIDTH:
  303.       *value = surface->Width;
  304.       break;
  305.    case EGL_HEIGHT:
  306.       *value = surface->Height;
  307.       break;
  308.    case EGL_CONFIG_ID:
  309.       *value = surface->Config->ConfigID;
  310.       break;
  311.    case EGL_LARGEST_PBUFFER:
  312.       *value = surface->LargestPbuffer;
  313.       break;
  314.    case EGL_TEXTURE_FORMAT:
  315.       /* texture attributes: only for pbuffers, no error otherwise */
  316.       if (surface->Type == EGL_PBUFFER_BIT)
  317.          *value = surface->TextureFormat;
  318.       break;
  319.    case EGL_TEXTURE_TARGET:
  320.       if (surface->Type == EGL_PBUFFER_BIT)
  321.          *value = surface->TextureTarget;
  322.       break;
  323.    case EGL_MIPMAP_TEXTURE:
  324.       if (surface->Type == EGL_PBUFFER_BIT)
  325.          *value = surface->MipmapTexture;
  326.       break;
  327.    case EGL_MIPMAP_LEVEL:
  328.       if (surface->Type == EGL_PBUFFER_BIT)
  329.          *value = surface->MipmapLevel;
  330.       break;
  331.    case EGL_SWAP_BEHAVIOR:
  332.       *value = surface->SwapBehavior;
  333.       break;
  334.    case EGL_RENDER_BUFFER:
  335.       *value = surface->RenderBuffer;
  336.       break;
  337.    case EGL_PIXEL_ASPECT_RATIO:
  338.       *value = surface->AspectRatio;
  339.       break;
  340.    case EGL_HORIZONTAL_RESOLUTION:
  341.       *value = surface->HorizontalResolution;
  342.       break;
  343.    case EGL_VERTICAL_RESOLUTION:
  344.       *value = surface->VerticalResolution;
  345.       break;
  346.    case EGL_MULTISAMPLE_RESOLVE:
  347.       *value = surface->MultisampleResolve;
  348.       break;
  349.    case EGL_VG_ALPHA_FORMAT:
  350.       *value = surface->VGAlphaFormat;
  351.       break;
  352.    case EGL_VG_COLORSPACE:
  353.       *value = surface->VGColorspace;
  354.       break;
  355.    case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
  356.       *value = surface->PostSubBufferSupportedNV;
  357.       break;
  358.    case EGL_BUFFER_AGE_EXT:
  359.       if (!dpy->Extensions.EXT_buffer_age) {
  360.          _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
  361.          return EGL_FALSE;
  362.       }
  363.       *value = drv->API.QueryBufferAge(drv, dpy, surface);
  364.       break;
  365.    default:
  366.       _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
  367.       return EGL_FALSE;
  368.    }
  369.  
  370.    return EGL_TRUE;
  371. }
  372.  
  373.  
  374. /**
  375.  * Default fallback routine - drivers might override this.
  376.  */
  377. EGLBoolean
  378. _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
  379.                   EGLint attribute, EGLint value)
  380. {
  381.    EGLint confval;
  382.    EGLint err = EGL_SUCCESS;
  383.    EGLint all_es_bits = EGL_OPENGL_ES_BIT |
  384.                         EGL_OPENGL_ES2_BIT |
  385.                         EGL_OPENGL_ES3_BIT_KHR;
  386.  
  387.    switch (attribute) {
  388.    case EGL_MIPMAP_LEVEL:
  389.       confval = surface->Config->RenderableType;
  390.       if (!(confval & all_es_bits)) {
  391.          err = EGL_BAD_PARAMETER;
  392.          break;
  393.       }
  394.       surface->MipmapLevel = value;
  395.       break;
  396.    case EGL_MULTISAMPLE_RESOLVE:
  397.       switch (value) {
  398.       case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
  399.          break;
  400.       case EGL_MULTISAMPLE_RESOLVE_BOX:
  401.          confval = surface->Config->SurfaceType;
  402.          if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
  403.             err = EGL_BAD_MATCH;
  404.          break;
  405.       default:
  406.          err = EGL_BAD_ATTRIBUTE;
  407.          break;
  408.       }
  409.       if (err != EGL_SUCCESS)
  410.          break;
  411.       surface->MultisampleResolve = value;
  412.       break;
  413.    case EGL_SWAP_BEHAVIOR:
  414.       switch (value) {
  415.       case EGL_BUFFER_DESTROYED:
  416.          break;
  417.       case EGL_BUFFER_PRESERVED:
  418.          confval = surface->Config->SurfaceType;
  419.          if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
  420.             err = EGL_BAD_MATCH;
  421.          break;
  422.       default:
  423.          err = EGL_BAD_ATTRIBUTE;
  424.          break;
  425.       }
  426.       if (err != EGL_SUCCESS)
  427.          break;
  428.       surface->SwapBehavior = value;
  429.       break;
  430.    default:
  431.       err = EGL_BAD_ATTRIBUTE;
  432.       break;
  433.    }
  434.  
  435.    if (err != EGL_SUCCESS)
  436.       return _eglError(err, "eglSurfaceAttrib");
  437.    return EGL_TRUE;
  438. }
  439.  
  440.  
  441. EGLBoolean
  442. _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
  443.                  EGLint buffer)
  444. {
  445.    EGLint texture_type = EGL_PBUFFER_BIT;
  446.  
  447.    /* Just do basic error checking and return success/fail.
  448.     * Drivers must implement the real stuff.
  449.     */
  450.  
  451.    if (dpy->Extensions.NOK_texture_from_pixmap)
  452.       texture_type |= EGL_PIXMAP_BIT;
  453.  
  454.    if (!(surface->Type & texture_type)) {
  455.       _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
  456.       return EGL_FALSE;
  457.    }
  458.  
  459.    if (surface->TextureFormat == EGL_NO_TEXTURE) {
  460.       _eglError(EGL_BAD_MATCH, "eglBindTexImage");
  461.       return EGL_FALSE;
  462.    }
  463.  
  464.    if (surface->TextureTarget == EGL_NO_TEXTURE) {
  465.       _eglError(EGL_BAD_MATCH, "eglBindTexImage");
  466.       return EGL_FALSE;
  467.    }
  468.  
  469.    if (buffer != EGL_BACK_BUFFER) {
  470.       _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
  471.       return EGL_FALSE;
  472.    }
  473.  
  474.    surface->BoundToTexture = EGL_TRUE;
  475.  
  476.    return EGL_TRUE;
  477. }
  478.  
  479. EGLBoolean
  480. _eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
  481.                     EGLint buffer)
  482. {
  483.    /* TODO: do basic error checking and return success/fail.
  484.     * Drivers must implement the real stuff.
  485.     */
  486.  
  487.   return EGL_TRUE;
  488. }
  489.  
  490.  
  491. EGLBoolean
  492. _eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
  493.                  EGLint interval)
  494. {
  495.    _eglClampSwapInterval(surf, interval);
  496.    return EGL_TRUE;
  497. }
  498.