Home | History | Annotate | Download | only in util
      1 /**************************************************************************
      2  *
      3  * Copyright 2010 Luca Barbieri
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial
     15  * portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  **************************************************************************/
     26 
     27 #include "u_surfaces.h"
     28 #include "util/u_hash_table.h"
     29 #include "util/u_inlines.h"
     30 #include "util/u_memory.h"
     31 
     32 boolean
     33 util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size,
     34                      struct pipe_context *ctx, struct pipe_resource *pt,
     35                      unsigned level, unsigned layer, unsigned flags,
     36                      struct pipe_surface **res)
     37 {
     38    struct pipe_surface *ps;
     39 
     40    if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
     41    {    /* or 2D array */
     42       if(!us->u.hash)
     43          us->u.hash = cso_hash_create();
     44 
     45       ps = cso_hash_iter_data(cso_hash_find(us->u.hash, (layer << 8) | level));
     46    }
     47    else
     48    {
     49       if(!us->u.array)
     50          us->u.array = CALLOC(pt->last_level + 1, sizeof(struct pipe_surface *));
     51       ps = us->u.array[level];
     52    }
     53 
     54    if(ps && ps->context == ctx)
     55    {
     56       p_atomic_inc(&ps->reference.count);
     57       *res = ps;
     58       return FALSE;
     59    }
     60 
     61    ps = (struct pipe_surface *)CALLOC(1, surface_struct_size);
     62    if(!ps)
     63    {
     64       *res = NULL;
     65       return FALSE;
     66    }
     67 
     68    pipe_surface_init(ctx, ps, pt, level, layer, flags);
     69 
     70    if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
     71       cso_hash_insert(us->u.hash, (layer << 8) | level, ps);
     72    else
     73       us->u.array[level] = ps;
     74 
     75    *res = ps;
     76    return TRUE;
     77 }
     78 
     79 void
     80 util_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps)
     81 {
     82    struct pipe_resource *pt = ps->texture;
     83    if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
     84    {    /* or 2D array */
     85       cso_hash_erase(us->u.hash, cso_hash_find(us->u.hash, (ps->u.tex.first_layer << 8) | ps->u.tex.level));
     86    }
     87    else
     88       us->u.array[ps->u.tex.level] = 0;
     89 }
     90 
     91 void
     92 util_surfaces_destroy(struct util_surfaces *us, struct pipe_resource *pt, void (*destroy_surface) (struct pipe_surface *))
     93 {
     94    if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
     95    {    /* or 2D array */
     96       if(us->u.hash)
     97       {
     98          struct cso_hash_iter iter;
     99          iter = cso_hash_first_node(us->u.hash);
    100          while (!cso_hash_iter_is_null(iter)) {
    101             destroy_surface(cso_hash_iter_data(iter));
    102             iter = cso_hash_iter_next(iter);
    103          }
    104 
    105          cso_hash_delete(us->u.hash);
    106          us->u.hash = NULL;
    107       }
    108    }
    109    else
    110    {
    111       if(us->u.array)
    112       {
    113          unsigned i;
    114          for(i = 0; i <= pt->last_level; ++i)
    115          {
    116             struct pipe_surface *ps = us->u.array[i];
    117             if(ps)
    118                destroy_surface(ps);
    119          }
    120          FREE(us->u.array);
    121          us->u.array = NULL;
    122       }
    123    }
    124 }
    125