star-2d

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

s2d_device.c (4011B)


      1 /* Copyright (C) 2016-2021, 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 "s2d.h"
     17 #include "s2d_c.h"
     18 #include "s2d_device_c.h"
     19 
     20 #include <rsys/logger.h>
     21 #include <rsys/mem_allocator.h>
     22 
     23 /*******************************************************************************
     24  * Helper functions
     25  ******************************************************************************/
     26 static INLINE void
     27 rtc_error_func(void* context, enum RTCError err, const char* str)
     28 {
     29   (void)str, (void)context;
     30   VFATAL("Embree:error: %s\n", ARG1(rtc_error_string(err)));
     31 }
     32 
     33 static INLINE void
     34 log_msg
     35   (struct s2d_device* dev,
     36    const enum log_type stream,
     37    const char* msg,
     38    va_list vargs)
     39 {
     40   ASSERT(dev && msg);
     41   if(dev->verbose) {
     42     res_T res; (void)res;
     43     res = logger_vprint(dev->logger, stream, msg, vargs);
     44     ASSERT(res == RES_OK);
     45   }
     46 }
     47 
     48 static void
     49 device_release(ref_T* ref)
     50 {
     51   struct s2d_device* dev;
     52   ASSERT(ref);
     53   dev = CONTAINER_OF(ref, struct s2d_device, ref);
     54   ASSERT(flist_name_is_empty(&dev->names) == 1);
     55   flist_name_release(&dev->names);
     56   rtcReleaseDevice(dev->rtc);
     57   MEM_RM(dev->allocator, dev);
     58 }
     59 
     60 /*******************************************************************************
     61  * Exported s2d_device functions
     62  ******************************************************************************/
     63 res_T
     64 s2d_device_create
     65   (struct logger* logger,
     66    struct mem_allocator* mem_allocator,
     67    const int verbose,
     68    struct s2d_device** out_dev)
     69 {
     70   struct s2d_device* dev = NULL;
     71   struct mem_allocator* allocator;
     72   res_T res = RES_OK;
     73 
     74   if(!out_dev) {
     75     res = RES_BAD_ARG;
     76     goto error;
     77   }
     78 
     79   allocator = mem_allocator ? mem_allocator : &mem_default_allocator;
     80   dev = (struct s2d_device*)MEM_CALLOC(allocator, 1, sizeof(struct s2d_device));
     81   if(!dev) {
     82     res = RES_MEM_ERR;
     83     goto error;
     84   }
     85   dev->logger = logger ? logger : LOGGER_DEFAULT;
     86   dev->allocator = allocator;
     87   dev->verbose = verbose;
     88   flist_name_init(allocator, &dev->names);
     89   ref_init(&dev->ref);
     90 
     91   dev->rtc = rtcNewDevice(verbose ? "verbose=1" : NULL);
     92   if(dev->rtc == NULL) {
     93     const enum RTCError err = rtcGetDeviceError(NULL);
     94     log_error(dev, "Could not create the embree device -- %s.\n",
     95       rtc_error_string(err));
     96     res = rtc_error_to_res_T(err);
     97     goto error;
     98   }
     99 
    100 #ifndef NDEBUG
    101   rtcSetDeviceErrorFunction(dev->rtc, rtc_error_func, dev);
    102 #endif
    103 
    104 exit:
    105   if(out_dev) *out_dev = dev;
    106   return res;
    107 error:
    108   if(dev) {
    109     S2D(device_ref_put(dev));
    110     dev = NULL;
    111   }
    112   goto exit;
    113 }
    114 
    115 res_T
    116 s2d_device_ref_get(struct s2d_device* dev)
    117 {
    118   if(!dev) return RES_BAD_ARG;
    119   ref_get(&dev->ref);
    120   return RES_OK;
    121 }
    122 
    123 res_T
    124 s2d_device_ref_put(struct s2d_device* dev)
    125 {
    126   if(!dev) return RES_BAD_ARG;
    127   ref_put(&dev->ref, device_release);
    128   return RES_OK;
    129 }
    130 
    131 /*******************************************************************************
    132  * Local functions
    133  ******************************************************************************/
    134 void
    135 log_error(struct s2d_device* dev, const char* msg, ...)
    136 {
    137   va_list vargs_list;
    138   ASSERT(dev && msg);
    139 
    140   va_start(vargs_list, msg);
    141   log_msg(dev, LOG_ERROR, msg, vargs_list);
    142   va_end(vargs_list);
    143 }
    144 
    145 void
    146 log_warning(struct s2d_device* dev, const char* msg, ...)
    147 {
    148   va_list vargs_list;
    149   ASSERT(dev && msg);
    150 
    151   va_start(vargs_list, msg);
    152   log_msg(dev, LOG_WARNING, msg, vargs_list);
    153   va_end(vargs_list);
    154 }
    155