Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  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. #ifdef EGL_MESA_screen_surface
  65. static EGLint
  66. _eglParseScreenSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
  67. {
  68.    EGLint i, err = EGL_SUCCESS;
  69.  
  70.    if (!attrib_list)
  71.       return EGL_SUCCESS;
  72.  
  73.    for (i = 0; attrib_list[i] != EGL_NONE; i++) {
  74.       EGLint attr = attrib_list[i++];
  75.       EGLint val = attrib_list[i];
  76.  
  77.       switch (attr) {
  78.       case EGL_WIDTH:
  79.          if (val < 0) {
  80.             err = EGL_BAD_PARAMETER;
  81.             break;
  82.          }
  83.          surf->Width = val;
  84.          break;
  85.       case EGL_HEIGHT:
  86.          if (val < 0) {
  87.             err = EGL_BAD_PARAMETER;
  88.             break;
  89.          }
  90.          surf->Height = val;
  91.          break;
  92.       default:
  93.          err = EGL_BAD_ATTRIBUTE;
  94.          break;
  95.       }
  96.  
  97.       if (err != EGL_SUCCESS) {
  98.          _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
  99.          break;
  100.       }
  101.    }
  102.  
  103.    return err;
  104. }
  105. #endif /* EGL_MESA_screen_surface */
  106.  
  107.  
  108. /**
  109.  * Parse the list of surface attributes and return the proper error code.
  110.  */
  111. static EGLint
  112. _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
  113. {
  114.    _EGLDisplay *dpy = surf->Resource.Display;
  115.    EGLint type = surf->Type;
  116.    EGLint texture_type = EGL_PBUFFER_BIT;
  117.    EGLint i, err = EGL_SUCCESS;
  118.  
  119.    if (!attrib_list)
  120.       return EGL_SUCCESS;
  121.  
  122. #ifdef EGL_MESA_screen_surface
  123.    if (type == EGL_SCREEN_BIT_MESA)
  124.       return _eglParseScreenSurfaceAttribList(surf, attrib_list);
  125. #endif
  126.  
  127.    if (dpy->Extensions.NOK_texture_from_pixmap)
  128.       texture_type |= EGL_PIXMAP_BIT;
  129.  
  130.    for (i = 0; attrib_list[i] != EGL_NONE; i++) {
  131.       EGLint attr = attrib_list[i++];
  132.       EGLint val = attrib_list[i];
  133.  
  134.       switch (attr) {
  135.       /* common attributes */
  136.       case EGL_VG_COLORSPACE:
  137.          switch (val) {
  138.          case EGL_VG_COLORSPACE_sRGB:
  139.          case EGL_VG_COLORSPACE_LINEAR:
  140.             break;
  141.          default:
  142.             err = EGL_BAD_ATTRIBUTE;
  143.             break;
  144.          }
  145.          if (err != EGL_SUCCESS)
  146.             break;
  147.          surf->VGColorspace = val;
  148.          break;
  149.       case EGL_VG_ALPHA_FORMAT:
  150.          switch (val) {
  151.          case EGL_VG_ALPHA_FORMAT_NONPRE:
  152.          case EGL_VG_ALPHA_FORMAT_PRE:
  153.             break;
  154.          default:
  155.             err = EGL_BAD_ATTRIBUTE;
  156.             break;
  157.          }
  158.          if (err != EGL_SUCCESS)
  159.             break;
  160.          surf->VGAlphaFormat = val;
  161.          break;
  162.       /* window surface attributes */
  163.       case EGL_RENDER_BUFFER:
  164.          if (type != EGL_WINDOW_BIT) {
  165.             err = EGL_BAD_ATTRIBUTE;
  166.             break;
  167.          }
  168.          if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) {
  169.             err = EGL_BAD_ATTRIBUTE;
  170.             break;
  171.          }
  172.          surf->RenderBuffer = val;
  173.          break;
  174.       case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
  175.          if (!dpy->Extensions.NV_post_sub_buffer ||
  176.              type != EGL_WINDOW_BIT) {
  177.             err = EGL_BAD_ATTRIBUTE;
  178.             break;
  179.          }
  180.          if (val != EGL_TRUE && val != EGL_FALSE) {
  181.             err = EGL_BAD_PARAMETER;
  182.             break;
  183.          }
  184.          surf->PostSubBufferSupportedNV = val;
  185.          break;
  186.       /* pbuffer surface attributes */
  187.       case EGL_WIDTH:
  188.          if (type != EGL_PBUFFER_BIT) {
  189.             err = EGL_BAD_ATTRIBUTE;
  190.             break;
  191.          }
  192.          if (val < 0) {
  193.             err = EGL_BAD_PARAMETER;
  194.             break;
  195.          }
  196.          surf->Width = val;
  197.          break;
  198.       case EGL_HEIGHT:
  199.          if (type != EGL_PBUFFER_BIT) {
  200.             err = EGL_BAD_ATTRIBUTE;
  201.             break;
  202.          }
  203.          if (val < 0) {
  204.             err = EGL_BAD_PARAMETER;
  205.             break;
  206.          }
  207.          surf->Height = val;
  208.          break;
  209.       case EGL_LARGEST_PBUFFER:
  210.          if (type != EGL_PBUFFER_BIT) {
  211.             err = EGL_BAD_ATTRIBUTE;
  212.             break;
  213.          }
  214.          surf->LargestPbuffer = !!val;
  215.          break;
  216.       /* for eglBindTexImage */
  217.       case EGL_TEXTURE_FORMAT:
  218.          if (!(type & texture_type)) {
  219.             err = EGL_BAD_ATTRIBUTE;
  220.             break;
  221.          }
  222.          switch (val) {
  223.          case EGL_TEXTURE_RGB:
  224.          case EGL_TEXTURE_RGBA:
  225.          case EGL_NO_TEXTURE:
  226.             break;
  227.          default:
  228.             err = EGL_BAD_ATTRIBUTE;
  229.             break;
  230.          }
  231.          if (err != EGL_SUCCESS)
  232.             break;
  233.          surf->TextureFormat = val;
  234.          break;
  235.       case EGL_TEXTURE_TARGET:
  236.          if (!(type & texture_type)) {
  237.             err = EGL_BAD_ATTRIBUTE;
  238.             break;
  239.          }
  240.          switch (val) {
  241.          case EGL_TEXTURE_2D:
  242.          case EGL_NO_TEXTURE:
  243.             break;
  244.          default:
  245.             err = EGL_BAD_ATTRIBUTE;
  246.             break;
  247.          }
  248.          if (err != EGL_SUCCESS)
  249.             break;
  250.          surf->TextureTarget = val;
  251.          break;
  252.       case EGL_MIPMAP_TEXTURE:
  253.          if (!(type & texture_type)) {
  254.             err = EGL_BAD_ATTRIBUTE;
  255.             break;
  256.          }
  257.          surf->MipmapTexture = !!val;
  258.          break;
  259.       /* no pixmap surface specific attributes */
  260.       default:
  261.          err = EGL_BAD_ATTRIBUTE;
  262.          break;
  263.       }
  264.  
  265.       if (err != EGL_SUCCESS) {
  266.          _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
  267.          break;
  268.       }
  269.    }
  270.  
  271.    return err;
  272. }
  273.  
  274.  
  275. /**
  276.  * Do error check on parameters and initialize the given _EGLSurface object.
  277.  * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
  278.  */
  279. EGLBoolean
  280. _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
  281.                 _EGLConfig *conf, const EGLint *attrib_list)
  282. {
  283.    const char *func;
  284.    EGLint renderBuffer = EGL_BACK_BUFFER;
  285.    EGLint swapBehavior = EGL_BUFFER_PRESERVED;
  286.    EGLint err;
  287.  
  288.    printf("%s\n",__FUNCTION__);
  289.  
  290.    switch (type) {
  291.    case EGL_WINDOW_BIT:
  292.       func = "eglCreateWindowSurface";
  293.       swapBehavior = EGL_BUFFER_DESTROYED;
  294.       break;
  295.    case EGL_PIXMAP_BIT:
  296.       func = "eglCreatePixmapSurface";
  297.       renderBuffer = EGL_SINGLE_BUFFER;
  298.       break;
  299.    case EGL_PBUFFER_BIT:
  300.       func = "eglCreatePBufferSurface";
  301.       break;
  302. #ifdef EGL_MESA_screen_surface
  303.    case EGL_SCREEN_BIT_MESA:
  304.       func = "eglCreateScreenSurface";
  305.       renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
  306.       break;
  307. #endif
  308.    default:
  309.       _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
  310.       return EGL_FALSE;
  311.    }
  312.  
  313.    if ((conf->SurfaceType & type) == 0) {
  314.       /* The config can't be used to create a surface of this type */
  315.       _eglError(EGL_BAD_CONFIG, func);
  316.       return EGL_FALSE;
  317.    }
  318.  
  319.    _eglInitResource(&surf->Resource, sizeof(*surf), dpy);
  320.    surf->Type = type;
  321.    surf->Config = conf;
  322.  
  323.    surf->Width = 0;
  324.    surf->Height = 0;
  325.    surf->TextureFormat = EGL_NO_TEXTURE;
  326.    surf->TextureTarget = EGL_NO_TEXTURE;
  327.    surf->MipmapTexture = EGL_FALSE;
  328.    surf->LargestPbuffer = EGL_FALSE;
  329.    surf->RenderBuffer = renderBuffer;
  330.    surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
  331.    surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
  332.  
  333.    surf->MipmapLevel = 0;
  334.    surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
  335.    surf->SwapBehavior = swapBehavior;
  336.  
  337.    surf->HorizontalResolution = EGL_UNKNOWN;
  338.    surf->VerticalResolution = EGL_UNKNOWN;
  339.    surf->AspectRatio = EGL_UNKNOWN;
  340.  
  341.    surf->PostSubBufferSupportedNV = EGL_FALSE;
  342.  
  343.    /* the default swap interval is 1 */
  344.    _eglClampSwapInterval(surf, 1);
  345.  
  346.    err = _eglParseSurfaceAttribList(surf, attrib_list);
  347.    if (err != EGL_SUCCESS)
  348.       return _eglError(err, func);
  349.  
  350.    return EGL_TRUE;
  351. }
  352.  
  353.  
  354. EGLBoolean
  355. _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
  356.                  EGLint attribute, EGLint *value)
  357. {
  358.    switch (attribute) {
  359.    case EGL_WIDTH:
  360.       *value = surface->Width;
  361.       break;
  362.    case EGL_HEIGHT:
  363.       *value = surface->Height;
  364.       break;
  365.    case EGL_CONFIG_ID:
  366.       *value = surface->Config->ConfigID;
  367.       break;
  368.    case EGL_LARGEST_PBUFFER:
  369.       *value = surface->LargestPbuffer;
  370.       break;
  371.    case EGL_TEXTURE_FORMAT:
  372.       /* texture attributes: only for pbuffers, no error otherwise */
  373.       if (surface->Type == EGL_PBUFFER_BIT)
  374.          *value = surface->TextureFormat;
  375.       break;
  376.    case EGL_TEXTURE_TARGET:
  377.       if (surface->Type == EGL_PBUFFER_BIT)
  378.          *value = surface->TextureTarget;
  379.       break;
  380.    case EGL_MIPMAP_TEXTURE:
  381.       if (surface->Type == EGL_PBUFFER_BIT)
  382.          *value = surface->MipmapTexture;
  383.       break;
  384.    case EGL_MIPMAP_LEVEL:
  385.       if (surface->Type == EGL_PBUFFER_BIT)
  386.          *value = surface->MipmapLevel;
  387.       break;
  388.    case EGL_SWAP_BEHAVIOR:
  389.       *value = surface->SwapBehavior;
  390.       break;
  391.    case EGL_RENDER_BUFFER:
  392.       *value = surface->RenderBuffer;
  393.       break;
  394.    case EGL_PIXEL_ASPECT_RATIO:
  395.       *value = surface->AspectRatio;
  396.       break;
  397.    case EGL_HORIZONTAL_RESOLUTION:
  398.       *value = surface->HorizontalResolution;
  399.       break;
  400.    case EGL_VERTICAL_RESOLUTION:
  401.       *value = surface->VerticalResolution;
  402.       break;
  403.    case EGL_MULTISAMPLE_RESOLVE:
  404.       *value = surface->MultisampleResolve;
  405.       break;
  406.    case EGL_VG_ALPHA_FORMAT:
  407.       *value = surface->VGAlphaFormat;
  408.       break;
  409.    case EGL_VG_COLORSPACE:
  410.       *value = surface->VGColorspace;
  411.       break;
  412.    case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
  413.       *value = surface->PostSubBufferSupportedNV;
  414.       break;
  415.    case EGL_BUFFER_AGE_EXT:
  416.       if (!dpy->Extensions.EXT_buffer_age) {
  417.          _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
  418.          return EGL_FALSE;
  419.       }
  420.       *value = drv->API.QueryBufferAge(drv, dpy, surface);
  421.       break;
  422.    default:
  423.       _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
  424.       return EGL_FALSE;
  425.    }
  426.  
  427.    return EGL_TRUE;
  428. }
  429.  
  430.  
  431. /**
  432.  * Default fallback routine - drivers might override this.
  433.  */
  434. EGLBoolean
  435. _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
  436.                   EGLint attribute, EGLint value)
  437. {
  438.    EGLint confval;
  439.    EGLint err = EGL_SUCCESS;
  440.    EGLint all_es_bits = EGL_OPENGL_ES_BIT |
  441.                         EGL_OPENGL_ES2_BIT |
  442.                         EGL_OPENGL_ES3_BIT_KHR;
  443.  
  444.    switch (attribute) {
  445.    case EGL_MIPMAP_LEVEL:
  446.       confval = surface->Config->RenderableType;
  447.       if (!(confval & all_es_bits)) {
  448.          err = EGL_BAD_PARAMETER;
  449.          break;
  450.       }
  451.       surface->MipmapLevel = value;
  452.       break;
  453.    case EGL_MULTISAMPLE_RESOLVE:
  454.       switch (value) {
  455.       case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
  456.          break;
  457.       case EGL_MULTISAMPLE_RESOLVE_BOX:
  458.          confval = surface->Config->SurfaceType;
  459.          if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
  460.             err = EGL_BAD_MATCH;
  461.          break;
  462.       default:
  463.          err = EGL_BAD_ATTRIBUTE;
  464.          break;
  465.       }
  466.       if (err != EGL_SUCCESS)
  467.          break;
  468.       surface->MultisampleResolve = value;
  469.       break;
  470.    case EGL_SWAP_BEHAVIOR:
  471.       switch (value) {
  472.       case EGL_BUFFER_DESTROYED:
  473.          break;
  474.       case EGL_BUFFER_PRESERVED:
  475.          confval = surface->Config->SurfaceType;
  476.          if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
  477.             err = EGL_BAD_MATCH;
  478.          break;
  479.       default:
  480.          err = EGL_BAD_ATTRIBUTE;
  481.          break;
  482.       }
  483.       if (err != EGL_SUCCESS)
  484.          break;
  485.       surface->SwapBehavior = value;
  486.       break;
  487.    default:
  488.       err = EGL_BAD_ATTRIBUTE;
  489.       break;
  490.    }
  491.  
  492.    if (err != EGL_SUCCESS)
  493.       return _eglError(err, "eglSurfaceAttrib");
  494.    return EGL_TRUE;
  495. }
  496.  
  497.  
  498. EGLBoolean
  499. _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
  500.                  EGLint buffer)
  501. {
  502.    EGLint texture_type = EGL_PBUFFER_BIT;
  503.  
  504.    /* Just do basic error checking and return success/fail.
  505.     * Drivers must implement the real stuff.
  506.     */
  507.  
  508.    if (dpy->Extensions.NOK_texture_from_pixmap)
  509.       texture_type |= EGL_PIXMAP_BIT;
  510.  
  511.    if (!(surface->Type & texture_type)) {
  512.       _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
  513.       return EGL_FALSE;
  514.    }
  515.  
  516.    if (surface->TextureFormat == EGL_NO_TEXTURE) {
  517.       _eglError(EGL_BAD_MATCH, "eglBindTexImage");
  518.       return EGL_FALSE;
  519.    }
  520.  
  521.    if (surface->TextureTarget == EGL_NO_TEXTURE) {
  522.       _eglError(EGL_BAD_MATCH, "eglBindTexImage");
  523.       return EGL_FALSE;
  524.    }
  525.  
  526.    if (buffer != EGL_BACK_BUFFER) {
  527.       _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
  528.       return EGL_FALSE;
  529.    }
  530.  
  531.    surface->BoundToTexture = EGL_TRUE;
  532.  
  533.    return EGL_TRUE;
  534. }
  535.  
  536.  
  537. EGLBoolean
  538. _eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
  539.                  EGLint interval)
  540. {
  541.    _eglClampSwapInterval(surf, interval);
  542.    return EGL_TRUE;
  543. }
  544.