star-3d

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

s3d_device.c (4356B)


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