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