Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  7.5
  4.  *
  5.  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. /**
  26.  * \file shared.c
  27.  * Shared-context state
  28.  */
  29.  
  30.  
  31.  
  32. #include "imports.h"
  33. #include "mtypes.h"
  34. #include "hash.h"
  35. #if FEATURE_ATI_fragment_shader
  36. #include "atifragshader.h"
  37. #endif
  38. #include "bufferobj.h"
  39. #include "shared.h"
  40. #include "program/program.h"
  41. #include "dlist.h"
  42. #include "shaderobj.h"
  43. #include "syncobj.h"
  44.  
  45. /**
  46.  * Allocate and initialize a shared context state structure.
  47.  * Initializes the display list, texture objects and vertex programs hash
  48.  * tables, allocates the texture objects. If it runs out of memory, frees
  49.  * everything already allocated before returning NULL.
  50.  *
  51.  * \return pointer to a gl_shared_state structure on success, or NULL on
  52.  * failure.
  53.  */
  54. struct gl_shared_state *
  55. _mesa_alloc_shared_state(struct gl_context *ctx)
  56. {
  57.    struct gl_shared_state *shared;
  58.    GLuint i;
  59.  
  60.    shared = CALLOC_STRUCT(gl_shared_state);
  61.    if (!shared)
  62.       return NULL;
  63.  
  64.    _glthread_INIT_MUTEX(shared->Mutex);
  65.  
  66.    shared->DisplayList = _mesa_NewHashTable();
  67.    shared->TexObjects = _mesa_NewHashTable();
  68.    shared->Programs = _mesa_NewHashTable();
  69.  
  70. #if FEATURE_ARB_vertex_program
  71.    shared->DefaultVertexProgram = (struct gl_vertex_program *)
  72.       ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
  73. #endif
  74.  
  75. #if FEATURE_ARB_fragment_program
  76.    shared->DefaultFragmentProgram = (struct gl_fragment_program *)
  77.       ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
  78. #endif
  79.  
  80. #if FEATURE_ATI_fragment_shader
  81.    shared->ATIShaders = _mesa_NewHashTable();
  82.    shared->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
  83. #endif
  84.  
  85. #if FEATURE_ARB_shader_objects
  86.    shared->ShaderObjects = _mesa_NewHashTable();
  87. #endif
  88.  
  89. #if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
  90.    shared->BufferObjects = _mesa_NewHashTable();
  91. #endif
  92.  
  93.    /* Allocate the default buffer object */
  94.    shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0, 0);
  95.  
  96.    /* Create default texture objects */
  97.    for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
  98.       /* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */
  99.       static const GLenum targets[NUM_TEXTURE_TARGETS] = {
  100.          GL_TEXTURE_2D_ARRAY_EXT,
  101.          GL_TEXTURE_1D_ARRAY_EXT,
  102.          GL_TEXTURE_CUBE_MAP,
  103.          GL_TEXTURE_3D,
  104.          GL_TEXTURE_RECTANGLE_NV,
  105.          GL_TEXTURE_2D,
  106.          GL_TEXTURE_1D
  107.       };
  108.       shared->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]);
  109.    }
  110.  
  111.    /* sanity check */
  112.    assert(shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1);
  113.  
  114.    /* Mutex and timestamp for texobj state validation */
  115.    _glthread_INIT_MUTEX(shared->TexMutex);
  116.    shared->TextureStateStamp = 0;
  117.  
  118. #if FEATURE_EXT_framebuffer_object
  119.    shared->FrameBuffers = _mesa_NewHashTable();
  120.    shared->RenderBuffers = _mesa_NewHashTable();
  121. #endif
  122.  
  123.    make_empty_list(& shared->SyncObjects);
  124.  
  125.    return shared;
  126. }
  127.  
  128.  
  129. /**
  130.  * Callback for deleting a display list.  Called by _mesa_HashDeleteAll().
  131.  */
  132. static void
  133. delete_displaylist_cb(GLuint id, void *data, void *userData)
  134. {
  135.    struct gl_display_list *list = (struct gl_display_list *) data;
  136.    struct gl_context *ctx = (struct gl_context *) userData;
  137.    _mesa_delete_list(ctx, list);
  138. }
  139.  
  140.  
  141. /**
  142.  * Callback for deleting a texture object.  Called by _mesa_HashDeleteAll().
  143.  */
  144. static void
  145. delete_texture_cb(GLuint id, void *data, void *userData)
  146. {
  147.    struct gl_texture_object *texObj = (struct gl_texture_object *) data;
  148.    struct gl_context *ctx = (struct gl_context *) userData;
  149.    ctx->Driver.DeleteTexture(ctx, texObj);
  150. }
  151.  
  152.  
  153. /**
  154.  * Callback for deleting a program object.  Called by _mesa_HashDeleteAll().
  155.  */
  156. static void
  157. delete_program_cb(GLuint id, void *data, void *userData)
  158. {
  159.    struct gl_program *prog = (struct gl_program *) data;
  160.    struct gl_context *ctx = (struct gl_context *) userData;
  161.    if(prog != &_mesa_DummyProgram) {
  162.       ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */
  163.       prog->RefCount = 0;  /* now going away */
  164.       ctx->Driver.DeleteProgram(ctx, prog);
  165.    }
  166. }
  167.  
  168.  
  169. #if FEATURE_ATI_fragment_shader
  170. /**
  171.  * Callback for deleting an ATI fragment shader object.
  172.  * Called by _mesa_HashDeleteAll().
  173.  */
  174. static void
  175. delete_fragshader_cb(GLuint id, void *data, void *userData)
  176. {
  177.    struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
  178.    struct gl_context *ctx = (struct gl_context *) userData;
  179.    _mesa_delete_ati_fragment_shader(ctx, shader);
  180. }
  181. #endif
  182.  
  183.  
  184. /**
  185.  * Callback for deleting a buffer object.  Called by _mesa_HashDeleteAll().
  186.  */
  187. static void
  188. delete_bufferobj_cb(GLuint id, void *data, void *userData)
  189. {
  190.    struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
  191.    struct gl_context *ctx = (struct gl_context *) userData;
  192.    if (_mesa_bufferobj_mapped(bufObj)) {
  193.       ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
  194.       bufObj->Pointer = NULL;
  195.    }
  196.    _mesa_reference_buffer_object(ctx, &bufObj, NULL);
  197. }
  198.  
  199.  
  200. /**
  201.  * Callback for freeing shader program data. Call it before delete_shader_cb
  202.  * to avoid memory access error.
  203.  */
  204. static void
  205. free_shader_program_data_cb(GLuint id, void *data, void *userData)
  206. {
  207.    struct gl_context *ctx = (struct gl_context *) userData;
  208.    struct gl_shader_program *shProg = (struct gl_shader_program *) data;
  209.  
  210.    if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
  211.        _mesa_free_shader_program_data(ctx, shProg);
  212.    }
  213. }
  214.  
  215.  
  216. /**
  217.  * Callback for deleting shader and shader programs objects.
  218.  * Called by _mesa_HashDeleteAll().
  219.  */
  220. static void
  221. delete_shader_cb(GLuint id, void *data, void *userData)
  222. {
  223.    struct gl_context *ctx = (struct gl_context *) userData;
  224.    struct gl_shader *sh = (struct gl_shader *) data;
  225.    if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
  226.       ctx->Driver.DeleteShader(ctx, sh);
  227.    }
  228.    else {
  229.       struct gl_shader_program *shProg = (struct gl_shader_program *) data;
  230.       ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
  231.       ctx->Driver.DeleteShaderProgram(ctx, shProg);
  232.    }
  233. }
  234.  
  235.  
  236. /**
  237.  * Callback for deleting a framebuffer object.  Called by _mesa_HashDeleteAll()
  238.  */
  239. static void
  240. delete_framebuffer_cb(GLuint id, void *data, void *userData)
  241. {
  242.    struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
  243.    /* The fact that the framebuffer is in the hashtable means its refcount
  244.     * is one, but we're removing from the hashtable now.  So clear refcount.
  245.     */
  246.    /*assert(fb->RefCount == 1);*/
  247.    fb->RefCount = 0;
  248.  
  249.    /* NOTE: Delete should always be defined but there are two reports
  250.     * of it being NULL (bugs 13507, 14293).  Work-around for now.
  251.     */
  252.    if (fb->Delete)
  253.       fb->Delete(fb);
  254. }
  255.  
  256.  
  257. /**
  258.  * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll()
  259.  */
  260. static void
  261. delete_renderbuffer_cb(GLuint id, void *data, void *userData)
  262. {
  263.    struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
  264.    rb->RefCount = 0;  /* see comment for FBOs above */
  265.    if (rb->Delete)
  266.       rb->Delete(rb);
  267. }
  268.  
  269.  
  270. /**
  271.  * Deallocate a shared state object and all children structures.
  272.  *
  273.  * \param ctx GL context.
  274.  * \param shared shared state pointer.
  275.  *
  276.  * Frees the display lists, the texture objects (calling the driver texture
  277.  * deletion callback to free its private data) and the vertex programs, as well
  278.  * as their hash tables.
  279.  *
  280.  * \sa alloc_shared_state().
  281.  */
  282. static void
  283. free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
  284. {
  285.    GLuint i;
  286.  
  287.    /* Free the dummy/fallback texture object */
  288.    if (shared->FallbackTex)
  289.       ctx->Driver.DeleteTexture(ctx, shared->FallbackTex);
  290.  
  291.    /*
  292.     * Free display lists
  293.     */
  294.    _mesa_HashDeleteAll(shared->DisplayList, delete_displaylist_cb, ctx);
  295.    _mesa_DeleteHashTable(shared->DisplayList);
  296.  
  297. #if FEATURE_ARB_shader_objects
  298.    _mesa_HashWalk(shared->ShaderObjects, free_shader_program_data_cb, ctx);
  299.    _mesa_HashDeleteAll(shared->ShaderObjects, delete_shader_cb, ctx);
  300.    _mesa_DeleteHashTable(shared->ShaderObjects);
  301. #endif
  302.  
  303.    _mesa_HashDeleteAll(shared->Programs, delete_program_cb, ctx);
  304.    _mesa_DeleteHashTable(shared->Programs);
  305.  
  306. #if FEATURE_ARB_vertex_program
  307.    _mesa_reference_vertprog(ctx, &shared->DefaultVertexProgram, NULL);
  308. #endif
  309.  
  310. #if FEATURE_ARB_fragment_program
  311.    _mesa_reference_fragprog(ctx, &shared->DefaultFragmentProgram, NULL);
  312. #endif
  313.  
  314. #if FEATURE_ATI_fragment_shader
  315.    _mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx);
  316.    _mesa_DeleteHashTable(shared->ATIShaders);
  317.    _mesa_delete_ati_fragment_shader(ctx, shared->DefaultFragmentShader);
  318. #endif
  319.  
  320. #if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
  321.    _mesa_HashDeleteAll(shared->BufferObjects, delete_bufferobj_cb, ctx);
  322.    _mesa_DeleteHashTable(shared->BufferObjects);
  323. #endif
  324.  
  325. #if FEATURE_EXT_framebuffer_object
  326.    _mesa_HashDeleteAll(shared->FrameBuffers, delete_framebuffer_cb, ctx);
  327.    _mesa_DeleteHashTable(shared->FrameBuffers);
  328.    _mesa_HashDeleteAll(shared->RenderBuffers, delete_renderbuffer_cb, ctx);
  329.    _mesa_DeleteHashTable(shared->RenderBuffers);
  330. #endif
  331.  
  332. #if FEATURE_ARB_vertex_buffer_object
  333.    _mesa_reference_buffer_object(ctx, &shared->NullBufferObj, NULL);
  334. #endif
  335.  
  336.    {
  337.       struct simple_node *node;
  338.       struct simple_node *temp;
  339.  
  340.       foreach_s(node, temp, & shared->SyncObjects) {
  341.          _mesa_unref_sync_object(ctx, (struct gl_sync_object *) node);
  342.       }
  343.    }
  344.  
  345.    /*
  346.     * Free texture objects (after FBOs since some textures might have
  347.     * been bound to FBOs).
  348.     */
  349.    ASSERT(ctx->Driver.DeleteTexture);
  350.    /* the default textures */
  351.    for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
  352.       ctx->Driver.DeleteTexture(ctx, shared->DefaultTex[i]);
  353.    }
  354.  
  355.    /* all other textures */
  356.    _mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx);
  357.    _mesa_DeleteHashTable(shared->TexObjects);
  358.  
  359.    _glthread_DESTROY_MUTEX(shared->Mutex);
  360.    _glthread_DESTROY_MUTEX(shared->TexMutex);
  361.  
  362.    free(shared);
  363. }
  364.  
  365.  
  366. /**
  367.  * Decrement shared state object reference count and potentially free it
  368.  * and all children structures.
  369.  *
  370.  * \param ctx GL context.
  371.  * \param shared shared state pointer.
  372.  *
  373.  * \sa free_shared_state().
  374.  */
  375. void
  376. _mesa_release_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
  377. {
  378.    GLint RefCount;
  379.  
  380.    _glthread_LOCK_MUTEX(shared->Mutex);
  381.    RefCount = --shared->RefCount;
  382.    _glthread_UNLOCK_MUTEX(shared->Mutex);
  383.  
  384.    assert(RefCount >= 0);
  385.  
  386.    if (RefCount == 0) {
  387.       /* free shared state */
  388.       free_shared_state( ctx, shared );
  389.    }
  390. }
  391.