Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2009, VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27. /*
  28.  * Author: Keith Whitwell <keithw@vmware.com>
  29.  * Author: Jakob Bornecrantz <wallbraker@gmail.com>
  30.  */
  31.  
  32. #include "utils.h"
  33.  
  34. #include "dri_screen.h"
  35. #include "dri_drawable.h"
  36. #include "dri_context.h"
  37. #include "state_tracker/drm_driver.h"
  38.  
  39. #include "pipe/p_context.h"
  40. #include "state_tracker/st_context.h"
  41.  
  42. GLboolean
  43. dri_create_context(gl_api api, const struct gl_config * visual,
  44.                    __DRIcontext * cPriv,
  45.                    unsigned major_version,
  46.                    unsigned minor_version,
  47.                    uint32_t flags,
  48.                    bool notify_reset,
  49.                    unsigned *error,
  50.                    void *sharedContextPrivate)
  51. {
  52.    __DRIscreen *sPriv = cPriv->driScreenPriv;
  53.    struct dri_screen *screen = dri_screen(sPriv);
  54.    struct st_api *stapi = screen->st_api;
  55.    struct dri_context *ctx = NULL;
  56.    struct st_context_iface *st_share = NULL;
  57.    struct st_context_attribs attribs;
  58.    enum st_context_error ctx_err = 0;
  59.    unsigned allowed_flags = __DRI_CTX_FLAG_DEBUG |
  60.                             __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
  61.  
  62.    if (screen->has_reset_status_query)
  63.       allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
  64.  
  65.    if (flags & ~allowed_flags) {
  66.       *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
  67.       goto fail;
  68.    }
  69.  
  70.    if (!screen->has_reset_status_query && notify_reset) {
  71.       *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
  72.       goto fail;
  73.    }
  74.  
  75.    memset(&attribs, 0, sizeof(attribs));
  76.    switch (api) {
  77.    case API_OPENGLES:
  78.       attribs.profile = ST_PROFILE_OPENGL_ES1;
  79.       break;
  80.    case API_OPENGLES2:
  81.       attribs.profile = ST_PROFILE_OPENGL_ES2;
  82.       break;
  83.    case API_OPENGL_COMPAT:
  84.    case API_OPENGL_CORE:
  85.       attribs.profile = api == API_OPENGL_COMPAT ? ST_PROFILE_DEFAULT
  86.                                                  : ST_PROFILE_OPENGL_CORE;
  87.       attribs.major = major_version;
  88.       attribs.minor = minor_version;
  89.  
  90.       if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0)
  91.          attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
  92.       break;
  93.    default:
  94.       *error = __DRI_CTX_ERROR_BAD_API;
  95.       goto fail;
  96.    }
  97.  
  98.    if ((flags & __DRI_CTX_FLAG_DEBUG) != 0)
  99.       attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
  100.  
  101.    if (flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)
  102.       attribs.flags |= ST_CONTEXT_FLAG_ROBUST_ACCESS;
  103.  
  104.    if (notify_reset)
  105.       attribs.flags |= ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED;
  106.  
  107.    if (sharedContextPrivate) {
  108.       st_share = ((struct dri_context *)sharedContextPrivate)->st;
  109.    }
  110.  
  111.    ctx = CALLOC_STRUCT(dri_context);
  112.    if (ctx == NULL) {
  113.       *error = __DRI_CTX_ERROR_NO_MEMORY;
  114.       goto fail;
  115.    }
  116.  
  117.    cPriv->driverPrivate = ctx;
  118.    ctx->cPriv = cPriv;
  119.    ctx->sPriv = sPriv;
  120.  
  121.    attribs.options = screen->options;
  122.    dri_fill_st_visual(&attribs.visual, screen, visual);
  123.    ctx->st = stapi->create_context(stapi, &screen->base, &attribs, &ctx_err,
  124.                                    st_share);
  125.    if (ctx->st == NULL) {
  126.       switch (ctx_err) {
  127.       case ST_CONTEXT_SUCCESS:
  128.          *error = __DRI_CTX_ERROR_SUCCESS;
  129.          break;
  130.       case ST_CONTEXT_ERROR_NO_MEMORY:
  131.          *error = __DRI_CTX_ERROR_NO_MEMORY;
  132.          break;
  133.       case ST_CONTEXT_ERROR_BAD_API:
  134.          *error = __DRI_CTX_ERROR_BAD_API;
  135.          break;
  136.       case ST_CONTEXT_ERROR_BAD_VERSION:
  137.          *error = __DRI_CTX_ERROR_BAD_VERSION;
  138.          break;
  139.       case ST_CONTEXT_ERROR_BAD_FLAG:
  140.          *error = __DRI_CTX_ERROR_BAD_FLAG;
  141.          break;
  142.       case ST_CONTEXT_ERROR_UNKNOWN_ATTRIBUTE:
  143.          *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
  144.          break;
  145.       case ST_CONTEXT_ERROR_UNKNOWN_FLAG:
  146.          *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
  147.          break;
  148.       }
  149.       goto fail;
  150.    }
  151.    ctx->st->st_manager_private = (void *) ctx;
  152.    ctx->stapi = stapi;
  153.  
  154.    if (ctx->st->cso_context) {
  155.       ctx->pp = pp_init(ctx->st->pipe, screen->pp_enabled, ctx->st->cso_context);
  156.       ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context);
  157.    }
  158.  
  159.    *error = __DRI_CTX_ERROR_SUCCESS;
  160.    return GL_TRUE;
  161.  
  162.  fail:
  163.    if (ctx && ctx->st)
  164.       ctx->st->destroy(ctx->st);
  165.  
  166.    free(ctx);
  167.    return GL_FALSE;
  168. }
  169.  
  170. void
  171. dri_destroy_context(__DRIcontext * cPriv)
  172. {
  173.    struct dri_context *ctx = dri_context(cPriv);
  174.  
  175.    if (ctx->hud) {
  176.       hud_destroy(ctx->hud);
  177.    }
  178.  
  179.    if (ctx->pp)
  180.       pp_free(ctx->pp);
  181.  
  182.    /* No particular reason to wait for command completion before
  183.     * destroying a context, but we flush the context here
  184.     * to avoid having to add code elsewhere to cope with flushing a
  185.     * partially destroyed context.
  186.     */
  187.    ctx->st->flush(ctx->st, 0, NULL);
  188.    ctx->st->destroy(ctx->st);
  189.    free(ctx);
  190. }
  191.  
  192. GLboolean
  193. dri_unbind_context(__DRIcontext * cPriv)
  194. {
  195.    /* dri_util.c ensures cPriv is not null */
  196.    struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
  197.    struct dri_context *ctx = dri_context(cPriv);
  198.    struct st_api *stapi = screen->st_api;
  199.  
  200.    if (--ctx->bind_count == 0) {
  201.       if (ctx->st == ctx->stapi->get_current(ctx->stapi)) {
  202.          /* For conformance, unbind is supposed to flush the context.
  203.           * However, if we do it here we might end up flushing a partially
  204.           * destroyed context. Instead, we flush in dri_make_current and
  205.           * in dri_destroy_context which should cover all the cases.
  206.           */
  207.          stapi->make_current(stapi, NULL, NULL, NULL);
  208.       }
  209.    }
  210.  
  211.    return GL_TRUE;
  212. }
  213.  
  214. GLboolean
  215. dri_make_current(__DRIcontext * cPriv,
  216.                  __DRIdrawable * driDrawPriv,
  217.                  __DRIdrawable * driReadPriv)
  218. {
  219.    /* dri_util.c ensures cPriv is not null */
  220.    struct dri_context *ctx = dri_context(cPriv);
  221.    struct dri_drawable *draw = dri_drawable(driDrawPriv);
  222.    struct dri_drawable *read = dri_drawable(driReadPriv);
  223.    struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi);
  224.  
  225.    /* Flush the old context here so we don't have to flush on unbind() */
  226.    if (old_st && old_st != ctx->st)
  227.       old_st->flush(old_st, ST_FLUSH_FRONT, NULL);
  228.  
  229.    ++ctx->bind_count;
  230.  
  231.    if (!draw && !read)
  232.       return ctx->stapi->make_current(ctx->stapi, ctx->st, NULL, NULL);
  233.    else if (!draw || !read)
  234.       return GL_FALSE;
  235.  
  236.    if (ctx->dPriv != driDrawPriv) {
  237.       ctx->dPriv = driDrawPriv;
  238.       draw->texture_stamp = driDrawPriv->lastStamp - 1;
  239.    }
  240.    if (ctx->rPriv != driReadPriv) {
  241.       ctx->rPriv = driReadPriv;
  242.       read->texture_stamp = driReadPriv->lastStamp - 1;
  243.    }
  244.  
  245.    ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base);
  246.  
  247.    // This is ok to call here. If they are already init, it's a no-op.
  248.    if (draw->textures[ST_ATTACHMENT_BACK_LEFT] && draw->textures[ST_ATTACHMENT_DEPTH_STENCIL]
  249.       && ctx->pp)
  250.          pp_init_fbos(ctx->pp, draw->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
  251.             draw->textures[ST_ATTACHMENT_BACK_LEFT]->height0);
  252.  
  253.    return GL_TRUE;
  254. }
  255.  
  256. struct dri_context *
  257. dri_get_current(__DRIscreen *sPriv)
  258. {
  259.    struct dri_screen *screen = dri_screen(sPriv);
  260.    struct st_api *stapi = screen->st_api;
  261.    struct st_context_iface *st;
  262.  
  263.    st = stapi->get_current(stapi);
  264.  
  265.    return (struct dri_context *) st ? st->st_manager_private : NULL;
  266. }
  267.  
  268. /* vim: set sw=3 ts=8 sts=3 expandtab: */
  269.