LCOV - code coverage report
Current view: top level - src - common.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 15 16 93.8 %
Date: 2025-03-29 09:04:10 Functions: 2 2 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 30 38 78.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * This file is part of libplacebo.
       3                 :            :  *
       4                 :            :  * libplacebo is free software; you can redistribute it and/or
       5                 :            :  * modify it under the terms of the GNU Lesser General Public
       6                 :            :  * License as published by the Free Software Foundation; either
       7                 :            :  * version 2.1 of the License, or (at your option) any later version.
       8                 :            :  *
       9                 :            :  * libplacebo is distributed in the hope that it will be useful,
      10                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12                 :            :  * GNU Lesser General Public License for more details.
      13                 :            :  *
      14                 :            :  * You should have received a copy of the GNU Lesser General Public
      15                 :            :  * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>.
      16                 :            :  */
      17                 :            : 
      18                 :            : #pragma once
      19                 :            : 
      20                 :            : #define __STDC_FORMAT_MACROS
      21                 :            : 
      22                 :            : #ifdef __cplusplus
      23                 :            : #include <version>
      24                 :            : #endif
      25                 :            : 
      26                 :            : #if !defined(__cplusplus) || defined(__cpp_lib_stdatomic_h)
      27                 :            : #define PL_HAVE_STDATOMIC
      28                 :            : #endif
      29                 :            : 
      30                 :            : #ifdef PL_HAVE_STDATOMIC
      31                 :            : #include <stdatomic.h>
      32                 :            : #endif
      33                 :            : #include <stdbool.h>
      34                 :            : #include <stddef.h>
      35                 :            : #include <stdint.h>
      36                 :            : #include <stdlib.h>
      37                 :            : #include <inttypes.h>
      38                 :            : 
      39                 :            : #if defined(__MINGW32__) && !defined(__clang__)
      40                 :            : #define PL_PRINTF(fmt, va) __attribute__ ((format(gnu_printf, fmt, va))) \
      41                 :            :                            __attribute__ ((nonnull(fmt)))
      42                 :            : #elif defined(__GNUC__)
      43                 :            : #define PL_PRINTF(fmt, va) __attribute__ ((format(printf, fmt, va))) \
      44                 :            :                            __attribute__ ((nonnull(fmt)))
      45                 :            : #else
      46                 :            : #define PL_PRINTF(fmt, va)
      47                 :            : #endif
      48                 :            : 
      49                 :            : #define PL_NOINLINE __attribute__((noinline))
      50                 :            : 
      51                 :            : #include "os.h"
      52                 :            : 
      53                 :            : #include "config_internal.h"
      54                 :            : 
      55                 :            : #define PL_DEPRECATED_IN(VER)
      56                 :            : 
      57                 :            : #include <libplacebo/config.h>
      58                 :            : 
      59                 :            : #include "pl_assert.h"
      60                 :            : #include "pl_alloc.h"
      61                 :            : #include "pl_clock.h"
      62                 :            : #include "pl_string.h"
      63                 :            : 
      64                 :            : #if PL_API_VER != BUILD_API_VER
      65                 :            : #error Header mismatch? <libplacebo/config.h> pulled from elsewhere!
      66                 :            : #endif
      67                 :            : 
      68                 :            : // Divide a number while rounding up (careful: double-eval)
      69                 :            : #define PL_DIV_UP(x, y) (((x) + (y) - 1) / (y))
      70                 :            : 
      71                 :            : // Align up to the nearest multiple of an arbitrary alignment, which may also
      72                 :            : // be 0 to signal no alignment requirements.
      73                 :            : #define PL_ALIGN(x, align) ((align) ? PL_DIV_UP(x, align) * (align) : (x))
      74                 :            : 
      75                 :            : // This is faster but must only be called on positive powers of two.
      76                 :            : #define PL_ALIGN2(x, align) (((x) + (align) - 1) & ~((align) - 1))
      77                 :            : 
      78                 :            : // Returns the log base 2 of an unsigned long long
      79                 :            : #define PL_LOG2(x) ((unsigned) (8*sizeof (unsigned long long) - __builtin_clzll((x)) - 1))
      80                 :            : 
      81                 :            : // Rounds a number up to the nearest power of two
      82                 :            : #define PL_ALIGN_POT(x) (0x1LLU << (PL_LOG2((x) - 1) + 1))
      83                 :            : 
      84                 :            : // Right shift a number while rounding up
      85                 :            : #define PL_RSHIFT_UP(x, s) -((-(x)) >> (s))
      86                 :            : 
      87                 :            : // Returns whether or not a number is a power of two (or zero)
      88                 :            : #define PL_ISPOT(x) (((x) & ((x) - 1)) == 0)
      89                 :            : 
      90                 :            : // Returns the size of a static array with known size.
      91                 :            : #define PL_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
      92                 :            : 
      93                 :            : // Swaps two variables
      94                 :            : #define PL_SWAP(a, b)              \
      95                 :            :     do {                           \
      96                 :            :         __typeof__ (a) _tmp = (a); \
      97                 :            :         (a) = (b);                 \
      98                 :            :         (b) = _tmp;                \
      99                 :            :     } while (0)
     100                 :            : 
     101                 :            : // Helper functions for transposing a matrix in-place.
     102                 :            : #define PL_TRANSPOSE_DIM(d, m) \
     103                 :            :     pl_transpose((d), (float[(d)*(d)]){0}, (const float *)(m))
     104                 :            : 
     105                 :            : #define PL_TRANSPOSE_2X2(m) PL_TRANSPOSE_DIM(2, m)
     106                 :            : #define PL_TRANSPOSE_3X3(m) PL_TRANSPOSE_DIM(3, m)
     107                 :            : #define PL_TRANSPOSE_4X4(m) PL_TRANSPOSE_DIM(4, m)
     108                 :            : 
     109                 :            : static inline float *pl_transpose(int dim, float *out, const float *in)
     110                 :            : {
     111   [ +  +  +  +  :       6016 :     for (int i = 0; i < dim; i++) {
             +  +  +  + ]
     112   [ +  +  +  +  :      16128 :         for (int j = 0; j < dim; j++)
             +  +  +  + ]
     113                 :      11776 :             out[i * dim + j] = in[j * dim + i];
     114                 :            :     }
     115                 :            : 
     116                 :            :     return out;
     117                 :            : }
     118                 :            : 
     119                 :            : // Helper functions for some common numeric operations (careful: double-eval)
     120                 :            : #define PL_MAX(x, y) ((x) > (y) ? (x) : (y))
     121                 :            : #define PL_MAX3(x, y, z) PL_MAX(PL_MAX(x, y), z)
     122                 :            : #define PL_MIN(x, y) ((x) < (y) ? (x) : (y))
     123                 :            : #define PL_CLAMP(x, l, h) ((x) < (l) ? (l) : (x) > (h) ? (h) : (x))
     124                 :            : #define PL_CMP(a, b) (((a) > (b)) - ((a) < (b)))
     125                 :            : #define PL_DEF(x, d) ((x) ? (x) : (d))
     126                 :            : #define PL_SQUARE(x) ((x) * (x))
     127                 :            : #define PL_CUBE(x) ((x) * (x) * (x))
     128                 :            : #define PL_MIX(a, b, x) ((x) * (b) + (1 - (x)) * (a))
     129                 :            : 
     130                 :            : static inline float pl_smoothstep(float edge0, float edge1, float x)
     131                 :            : {
     132   [ -  +  -  + ]:    6566133 :     if (edge0 == edge1)
     133   [ #  #  #  # ]:          0 :         return x >= edge0;
     134                 :    6566133 :     x = (x - edge0) / (edge1 - edge0);
     135   [ +  +  +  +  :    6566133 :     x = PL_CLAMP(x, 0.0f, 1.0f);
             +  +  +  + ]
     136                 :    6566133 :     return x * x * (3.0f - 2.0f * x);
     137                 :            : }
     138                 :            : 
     139                 :            : // Helpers for doing alignment calculations
     140                 :       5391 : static inline size_t pl_gcd(size_t x, size_t y)
     141                 :            : {
     142         [ +  - ]:       5391 :     assert(x && y);
     143         [ +  + ]:      14119 :     while (y) {
     144                 :            :         size_t tmp = y;
     145                 :       8728 :         y = x % y;
     146                 :            :         x = tmp;
     147                 :            :     }
     148                 :            : 
     149                 :       5391 :     return x;
     150                 :            : }
     151                 :            : 
     152                 :       5391 : static inline size_t pl_lcm(size_t x, size_t y)
     153                 :            : {
     154         [ -  + ]:       5391 :     assert(x && y);
     155                 :       5391 :     return x * (y / pl_gcd(x, y));
     156                 :            : }
     157                 :            : 
     158                 :            : // Conditional abort() macro that depends on the configuration option
     159                 :            : #ifdef PL_DEBUG_ABORT
     160                 :            : # define pl_debug_abort() do {                          \
     161                 :            :     fprintf(stderr, "pl_debug_abort() triggered!\n");   \
     162                 :            :     abort();                                            \
     163                 :            : } while (0)
     164                 :            : #else
     165                 :            : # define pl_debug_abort() do {} while (0)
     166                 :            : #endif
     167                 :            : 
     168                 :            : #ifdef PL_HAVE_STDATOMIC
     169                 :            : 
     170                 :            : // Refcounting helpers
     171                 :            : typedef atomic_uint_fast32_t pl_rc_t;
     172                 :            : #define pl_rc_init(rc)  atomic_init(rc, 1)
     173                 :            : #define pl_rc_ref(rc)   ((void) atomic_fetch_add_explicit(rc, 1, memory_order_acquire))
     174                 :            : #define pl_rc_deref(rc) (atomic_fetch_sub_explicit(rc, 1, memory_order_release) == 1)
     175                 :            : #define pl_rc_count(rc)  atomic_load(rc)
     176                 :            : 
     177                 :            : #endif
     178                 :            : 
     179                 :            : #define pl_unreachable() (assert(!"unreachable"), __builtin_unreachable())
     180                 :            : 
     181                 :            : // Helper for parameter validation
     182                 :            : #define pl_require(ctx, expr)                                   \
     183                 :            :   do {                                                          \
     184                 :            :       if (!(expr)) {                                            \
     185                 :            :           PL_ERR(ctx, "Validation failed: %s (%s:%d)",          \
     186                 :            :                   #expr, __FILE__, __LINE__);                   \
     187                 :            :           pl_log_stack_trace(ctx->log, PL_LOG_ERR);             \
     188                 :            :           pl_debug_abort();                                     \
     189                 :            :           goto error;                                           \
     190                 :            :       }                                                         \
     191                 :            :   } while (0)

Generated by: LCOV version 1.16