star-3d

Surface structuring for efficient 3D geometric queries
git clone git://git.meso-star.fr/star-3d.git
Log | Files | Refs | README | LICENSE

s3d_device.c (4329B)


      1 /* Copyright (C) 2015-2023 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #include "s3d.h"
     17 #include "s3d_c.h"
     18 
     19 #include "s3d_backend.h"
     20 #include "s3d_device_c.h"
     21 
     22 #include <rsys/logger.h>
     23 #include <rsys/mem_allocator.h>
     24 
     25 /*******************************************************************************
     26  * Helper functions
     27  ******************************************************************************/
     28 static INLINE void
     29 rtc_error_func(void* context, enum RTCError err, const char* str)
     30 {
     31   (void)str, (void)context;
     32   VFATAL("Embree:error: %s\n", ARG1(rtc_error_string(err)));
     33 }
     34 
     35 static INLINE void
     36 log_msg
     37   (struct s3d_device* dev,
     38    const enum log_type stream,
     39    const char* msg,
     40    va_list vargs)
     41 {
     42   ASSERT(dev && msg);
     43   if(dev->verbose) {
     44     res_T res; (void)res;
     45     res = logger_vprint(dev->logger, stream, msg, vargs);
     46     ASSERT(res == RES_OK);
     47   }
     48 }
     49 
     50 static void
     51 device_release(ref_T* ref)
     52 {
     53   struct s3d_device* dev;
     54   ASSERT(ref);
     55   dev = CONTAINER_OF(ref, struct s3d_device, ref);
     56   ASSERT(flist_name_is_empty(&dev->names) == 1);
     57   flist_name_release(&dev->names);
     58   rtcReleaseDevice(dev->rtc);
     59   MEM_RM(dev->allocator, dev);
     60 }
     61 
     62 /*******************************************************************************
     63  * Exported s3d_device functions
     64  ******************************************************************************/
     65 res_T
     66 s3d_device_create
     67   (struct logger* logger,
     68    struct mem_allocator* mem_allocator,
     69    const int verbose,
     70    struct s3d_device** out_dev)
     71 {
     72   char embree_opts[512];
     73   struct s3d_device* dev = NULL;
     74   struct mem_allocator* allocator;
     75   const int verbosity = MMAX(MMIN(verbose, 3), 0);
     76   int sz;
     77   res_T res = RES_OK;
     78 
     79   if(!out_dev) {
     80     res = RES_BAD_ARG;
     81     goto error;
     82   }
     83 
     84   allocator = mem_allocator ? mem_allocator : &mem_default_allocator;
     85   dev = (struct s3d_device*)MEM_CALLOC(allocator, 1, sizeof(struct s3d_device));
     86   if(!dev) {
     87     res = RES_MEM_ERR;
     88     goto error;
     89   }
     90   dev->logger = logger ? logger : LOGGER_DEFAULT;
     91   dev->allocator = allocator;
     92   dev->verbose = verbose;
     93   flist_name_init(allocator, &dev->names);
     94   ref_init(&dev->ref);
     95 
     96   sz = snprintf(embree_opts, sizeof(embree_opts), "verbose=%d", verbosity);
     97   if((size_t)sz >= sizeof(embree_opts)) {
     98     log_error(dev, "Could not setup the Embree option string.\n");
     99     res = RES_MEM_ERR;
    100     goto error;
    101   }
    102 
    103   dev->rtc = rtcNewDevice(embree_opts);
    104   if(dev->rtc == NULL) {
    105     const enum RTCError err = rtcGetDeviceError(NULL);
    106     log_error(dev, "Could not create the embree device -- %s.\n",
    107       rtc_error_string(err));
    108     res = rtc_error_to_res_T(err);
    109     goto error;
    110   }
    111 
    112 #ifndef NDEBUG
    113   rtcSetDeviceErrorFunction(dev->rtc, rtc_error_func, dev);
    114 #endif
    115 
    116 exit:
    117   if(out_dev) *out_dev = dev;
    118   return res;
    119 error:
    120   if(dev) {
    121     S3D(device_ref_put(dev));
    122     dev = NULL;
    123   }
    124   goto exit;
    125 }
    126 
    127 res_T
    128 s3d_device_ref_get(struct s3d_device* dev)
    129 {
    130   if(!dev) return RES_BAD_ARG;
    131   ref_get(&dev->ref);
    132   return RES_OK;
    133 }
    134 
    135 res_T
    136 s3d_device_ref_put(struct s3d_device* dev)
    137 {
    138   if(!dev) return RES_BAD_ARG;
    139   ref_put(&dev->ref, device_release);
    140   return RES_OK;
    141 }
    142 
    143 /*******************************************************************************
    144  * Local functions
    145  ******************************************************************************/
    146 void
    147 log_error(struct s3d_device* dev, const char* msg, ...)
    148 {
    149   va_list vargs_list;
    150   ASSERT(dev && msg);
    151 
    152   va_start(vargs_list, msg);
    153   log_msg(dev, LOG_ERROR, msg, vargs_list);
    154   va_end(vargs_list);
    155 }
    156 
    157 void
    158 log_warning(struct s3d_device* dev, const char* msg, ...)
    159 {
    160   va_list vargs_list;
    161   ASSERT(dev && msg);
    162 
    163   va_start(vargs_list, msg);
    164   log_msg(dev, LOG_WARNING, msg, vargs_list);
    165   va_end(vargs_list);
    166 }
    167