Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
  3.  * All Rights Reserved.
  4.  * Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. /**
  26.  * \file drisw_util.c
  27.  *
  28.  * DRISW utility functions, i.e. dri_util.c stripped from drm-specific bits.
  29.  */
  30.  
  31. #include "dri_util.h"
  32. #include "utils.h"
  33.  
  34.  
  35. /**
  36.  * Screen functions
  37.  */
  38.  
  39. static void
  40. setupLoaderExtensions(__DRIscreen *psp,
  41.                       const __DRIextension **extensions)
  42. {
  43.     int i;
  44.  
  45.     for (i = 0; extensions[i]; i++) {
  46.         if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0)
  47.             psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
  48.     }
  49. }
  50.  
  51. static __DRIscreen *
  52. driCreateNewScreen(int scrn, const __DRIextension **extensions,
  53.                    const __DRIconfig ***driver_configs, void *data)
  54. {
  55.     static const __DRIextension *emptyExtensionList[] = { NULL };
  56.     __DRIscreen *psp;
  57.  
  58.     psp = CALLOC_STRUCT(__DRIscreenRec);
  59.     if (!psp)
  60.         return NULL;
  61.  
  62.     setupLoaderExtensions(psp, extensions);
  63.  
  64.     psp->loaderPrivate = data;
  65.  
  66.     psp->extensions = emptyExtensionList;
  67.     psp->fd = -1;
  68.     psp->myNum = scrn;
  69.  
  70.     *driver_configs = driDriverAPI.InitScreen(psp);
  71.     if (*driver_configs == NULL) {
  72.         free(psp);
  73.         return NULL;
  74.     }
  75.  
  76.     return psp;
  77. }
  78.  
  79. static void driDestroyScreen(__DRIscreen *psp)
  80. {
  81.     if (psp) {
  82.         driDriverAPI.DestroyScreen(psp);
  83.         free(psp);
  84.     }
  85. }
  86.  
  87. static const __DRIextension **driGetExtensions(__DRIscreen *psp)
  88. {
  89.     return psp->extensions;
  90. }
  91.  
  92.  
  93. /**
  94.  * Context functions
  95.  */
  96.  
  97. static __DRIcontext *
  98. driCreateContextAttribs(__DRIscreen *screen, int api,
  99.                         const __DRIconfig *config,
  100.                         __DRIcontext *shared,
  101.                         unsigned num_attribs,
  102.                         const uint32_t *attribs,
  103.                         unsigned *error,
  104.                         void *data)
  105. {
  106.     __DRIcontext *pcp;
  107.     const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
  108.     void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
  109.     gl_api mesa_api;
  110.     unsigned major_version = 1;
  111.     unsigned minor_version = 0;
  112.     uint32_t flags = 0;
  113.  
  114.     /* Either num_attribs is zero and attribs is NULL, or num_attribs is not
  115.      * zero and attribs is not NULL.
  116.      */
  117.     assert((num_attribs == 0) == (attribs == NULL));
  118.  
  119.     switch (api) {
  120.     case __DRI_API_OPENGL:
  121.             mesa_api = API_OPENGL_COMPAT;
  122.             break;
  123.     case __DRI_API_GLES:
  124.             mesa_api = API_OPENGLES;
  125.             break;
  126.     case __DRI_API_GLES2:
  127.     case __DRI_API_GLES3:
  128.             mesa_api = API_OPENGLES2;
  129.             break;
  130.     case __DRI_API_OPENGL_CORE:
  131.             mesa_api = API_OPENGL_CORE;
  132.             break;
  133.     default:
  134.             *error = __DRI_CTX_ERROR_BAD_API;
  135.             return NULL;
  136.     }
  137.  
  138.     for (unsigned i = 0; i < num_attribs; i++) {
  139.         switch (attribs[i * 2]) {
  140.         case __DRI_CTX_ATTRIB_MAJOR_VERSION:
  141.             major_version = attribs[i * 2 + 1];
  142.             break;
  143.         case __DRI_CTX_ATTRIB_MINOR_VERSION:
  144.             minor_version = attribs[i * 2 + 1];
  145.             break;
  146.         case __DRI_CTX_ATTRIB_FLAGS:
  147.             flags = attribs[i * 2 + 1];
  148.             break;
  149.         default:
  150.             /* We can't create a context that satisfies the requirements of an
  151.              * attribute that we don't understand.  Return failure.
  152.              */
  153.             return NULL;
  154.         }
  155.     }
  156.  
  157.     /* Mesa does not support the GL_ARB_compatibilty extension or the
  158.      * compatibility profile.  This means that we treat a API_OPENGL_COMPAT 3.1 as
  159.      * API_OPENGL_CORE and reject API_OPENGL_COMPAT 3.2+.
  160.      */
  161.     if (mesa_api == API_OPENGL_COMPAT && major_version == 3 && minor_version == 1)
  162.        mesa_api = API_OPENGL_CORE;
  163.  
  164.     if (mesa_api == API_OPENGL_COMPAT
  165.         && ((major_version > 3)
  166.             || (major_version == 3 && minor_version >= 2))) {
  167.        *error = __DRI_CTX_ERROR_BAD_API;
  168.        return NULL;
  169.     }
  170.     /* There are no forward-compatible contexts before OpenGL 3.0.  The
  171.      * GLX_ARB_create_context spec says:
  172.      *
  173.      *     "Forward-compatible contexts are defined only for OpenGL versions
  174.      *     3.0 and later."
  175.      *
  176.      * Moreover, Mesa can't fulfill the requirements of a forward-looking
  177.      * context.  Return failure if a forward-looking context is requested.
  178.      *
  179.      * In Mesa, a debug context is the same as a regular context.
  180.      */
  181.     if (major_version >= 3) {
  182.         if ((flags & ~__DRI_CTX_FLAG_DEBUG) != 0)
  183.             return NULL;
  184.     }
  185.  
  186.     pcp = CALLOC_STRUCT(__DRIcontextRec);
  187.     if (!pcp)
  188.         return NULL;
  189.  
  190.     pcp->loaderPrivate = data;
  191.  
  192.     pcp->driScreenPriv = screen;
  193.     pcp->driDrawablePriv = NULL;
  194.     pcp->driReadablePriv = NULL;
  195.  
  196.     if (!driDriverAPI.CreateContext(mesa_api, modes, pcp,
  197.                                     major_version, minor_version,
  198.                                     flags, error, shareCtx)) {
  199.         free(pcp);
  200.         return NULL;
  201.     }
  202.  
  203.     return pcp;
  204. }
  205.  
  206. static __DRIcontext *
  207. driCreateNewContextForAPI(__DRIscreen *psp, int api,
  208.                           const __DRIconfig *config,
  209.                           __DRIcontext *shared, void *data)
  210. {
  211.     unsigned error;
  212.  
  213.     return driCreateContextAttribs(psp, api, config, shared, 0, NULL,
  214.                                    &error, data);
  215. }
  216.  
  217. static __DRIcontext *
  218. driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
  219.                     __DRIcontext *shared, void *data)
  220. {
  221.     return driCreateNewContextForAPI(psp, __DRI_API_OPENGL,
  222.                                      config, shared, data);
  223. }
  224.  
  225. static void
  226. driDestroyContext(__DRIcontext *pcp)
  227. {
  228.     if (pcp) {
  229.         driDriverAPI.DestroyContext(pcp);
  230.         free(pcp);
  231.     }
  232. }
  233.  
  234. static int
  235. driCopyContext(__DRIcontext *dst, __DRIcontext *src, unsigned long mask)
  236. {
  237.     return GL_FALSE;
  238. }
  239.  
  240. static void dri_get_drawable(__DRIdrawable *pdp);
  241. static void dri_put_drawable(__DRIdrawable *pdp);
  242.  
  243. static int driBindContext(__DRIcontext *pcp,
  244.                           __DRIdrawable *pdp,
  245.                           __DRIdrawable *prp)
  246. {
  247.     /* Bind the drawable to the context */
  248.     if (pcp) {
  249.         pcp->driDrawablePriv = pdp;
  250.         pcp->driReadablePriv = prp;
  251.         if (pdp) {
  252.             pdp->driContextPriv = pcp;
  253.             dri_get_drawable(pdp);
  254.         }
  255.         if (prp && pdp != prp) {
  256.             dri_get_drawable(prp);
  257.         }
  258.     }
  259.  
  260.     return driDriverAPI.MakeCurrent(pcp, pdp, prp);
  261. }
  262.  
  263. static int driUnbindContext(__DRIcontext *pcp)
  264. {
  265.     __DRIdrawable *pdp;
  266.     __DRIdrawable *prp;
  267.  
  268.     if (pcp == NULL)
  269.         return GL_FALSE;
  270.  
  271.     pdp = pcp->driDrawablePriv;
  272.     prp = pcp->driReadablePriv;
  273.  
  274.     /* already unbound */
  275.     if (!pdp && !prp)
  276.         return GL_TRUE;
  277.  
  278.     driDriverAPI.UnbindContext(pcp);
  279.  
  280.     dri_put_drawable(pdp);
  281.  
  282.     if (prp != pdp) {
  283.         dri_put_drawable(prp);
  284.     }
  285.  
  286.     pcp->driDrawablePriv = NULL;
  287.     pcp->driReadablePriv = NULL;
  288.  
  289.     return GL_TRUE;
  290. }
  291.  
  292.  
  293. /**
  294.  * Drawable functions
  295.  */
  296.  
  297. static void dri_get_drawable(__DRIdrawable *pdp)
  298. {
  299.     pdp->refcount++;
  300. }
  301.  
  302. static void dri_put_drawable(__DRIdrawable *pdp)
  303. {
  304.     if (pdp) {
  305.         pdp->refcount--;
  306.         if (pdp->refcount)
  307.             return;
  308.  
  309.         driDriverAPI.DestroyBuffer(pdp);
  310.         free(pdp);
  311.     }
  312. }
  313.  
  314. static __DRIdrawable *
  315. driCreateNewDrawable(__DRIscreen *psp,
  316.                      const __DRIconfig *config, void *data)
  317. {
  318.     __DRIdrawable *pdp;
  319.  
  320.     pdp = CALLOC_STRUCT(__DRIdrawableRec);
  321.     if (!pdp)
  322.         return NULL;
  323.  
  324.     pdp->loaderPrivate = data;
  325.  
  326.     pdp->driScreenPriv = psp;
  327.     pdp->driContextPriv = NULL;
  328.  
  329.     dri_get_drawable(pdp);
  330.  
  331.     if (!driDriverAPI.CreateBuffer(psp, pdp, &config->modes, GL_FALSE)) {
  332.         free(pdp);
  333.         return NULL;
  334.     }
  335.  
  336.     pdp->lastStamp = 1; /* const */
  337.  
  338.     return pdp;
  339. }
  340.  
  341. static void
  342. driDestroyDrawable(__DRIdrawable *pdp)
  343. {
  344.     dri_put_drawable(pdp);
  345. }
  346.  
  347. static void driSwapBuffers(__DRIdrawable *pdp)
  348. {
  349.     driDriverAPI.SwapBuffers(pdp);
  350. }
  351.  
  352. const __DRIcoreExtension driCoreExtension = {
  353.     { __DRI_CORE, __DRI_CORE_VERSION },
  354.     NULL, /* driCreateNewScreen */
  355.     driDestroyScreen,
  356.     driGetExtensions,
  357.     driGetConfigAttrib,
  358.     driIndexConfigAttrib,
  359.     NULL, /* driCreateNewDrawable */
  360.     driDestroyDrawable,
  361.     driSwapBuffers,
  362.     driCreateNewContext,
  363.     driCopyContext,
  364.     driDestroyContext,
  365.     driBindContext,
  366.     driUnbindContext
  367. };
  368.  
  369. const __DRIswrastExtension driSWRastExtension = {
  370.     { __DRI_SWRAST, __DRI_SWRAST_VERSION },
  371.     driCreateNewScreen,
  372.     driCreateNewDrawable,
  373.     driCreateNewContextForAPI,
  374.     driCreateContextAttribs
  375. };
  376.