Home | History | Annotate | Download | only in include
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef C2_H_
     18 #define C2_H_
     19 
     20 #include <string>
     21 #include <vector>
     22 #include <list>
     23 
     24 #ifdef __ANDROID__
     25 
     26 #include <utils/Errors.h>       // for status_t
     27 #include <utils/Timers.h>       // for nsecs_t
     28 
     29 namespace android {
     30 
     31 #else
     32 
     33 #include <errno.h>
     34 typedef int64_t nsecs_t;
     35 
     36 enum {
     37     GRALLOC_USAGE_SW_READ_OFTEN,
     38     GRALLOC_USAGE_RENDERSCRIPT,
     39     GRALLOC_USAGE_HW_TEXTURE,
     40     GRALLOC_USAGE_HW_COMPOSER,
     41     GRALLOC_USAGE_HW_VIDEO_ENCODER,
     42     GRALLOC_USAGE_PROTECTED,
     43     GRALLOC_USAGE_SW_WRITE_OFTEN,
     44     GRALLOC_USAGE_HW_RENDER,
     45 };
     46 
     47 #endif
     48 
     49 /** \mainpage Codec2
     50  *
     51  * Codec2 is a frame-based data processing API used by android.
     52  *
     53  * The framework accesses components via the \ref API.
     54  */
     55 
     56 /** \ingroup API
     57  *
     58  * The Codec2 API defines the operation of data processing components and their interaction with
     59  * the rest of the system.
     60  *
     61  * Coding Conventions
     62  *
     63  * Mitigating Binary Compatibility.
     64  *
     65  * While full binary compatibility is not a goal of the API (due to our use of STL), we try to
     66  * mitigate binary breaks by adhering to the following conventions:
     67  *
     68  * - at most one vtable with placeholder virtual methods
     69  * - all optional/placeholder virtual methods returning a status_t, with C2_NOT_IMPLEMENTED not
     70  *   requiring any update to input/output arguments.
     71  * - limiting symbol export of inline methods
     72  * - use of pimpl (or shared-pimpl)
     73  *
     74  * Naming
     75  *
     76  * - all classes and types prefix with C2
     77  * - classes for internal use prefix with _C2
     78  * - enum values in global namespace prefix with C2_ all caps
     79  * - enum values inside classes have no C2_ prefix as class already has it
     80  * - supporting two kinds of enum naming: all-caps and kCamelCase
     81  * \todo revisit kCamelCase for param-type
     82  *
     83  * Aspects
     84  *
     85  * Aspects define certain common behavior across a group of objects.
     86  * - classes whose name matches _C2.*Aspect
     87  * - only protected constructors
     88  * - no desctructor and copiable
     89  * - all methods are inline or static (this is opposite of the interface paradigm where all methods
     90  *   are virtual, which would not work due to the at most one vtable rule.)
     91  * - only private variables (this prevents subclasses interfering with the aspects.)
     92  */
     93 
     94 /// \defgroup types Common Types
     95 /// @{
     96 
     97 /**
     98  * C2String: basic string implementation
     99  */
    100 typedef std::string C2String;
    101 typedef const char *C2StringLiteral;
    102 
    103 /**
    104  * C2Error: status codes used.
    105  */
    106 typedef int32_t C2Error;
    107 enum {
    108 #ifndef __ANDROID__
    109     OK                  = 0,
    110     BAD_VALUE           = -EINVAL,
    111     BAD_INDEX           = -EOVERFLOW,
    112     UNKNOWN_TRANSACTION = -EBADMSG,
    113     ALREADY_EXISTS      = -EEXIST,
    114     NAME_NOT_FOUND      = -ENOENT,
    115     INVALID_OPERATION   = -ENOSYS,
    116     NO_MEMORY           = -ENOMEM,
    117     PERMISSION_DENIED   = -EPERM,
    118     TIMED_OUT           = -ETIMEDOUT,
    119     UNKNOWN_ERROR       = -EINVAL,
    120 #endif
    121 
    122     C2_OK               = OK,                   ///< operation completed successfully
    123 
    124     // bad input
    125     C2_BAD_VALUE        = BAD_VALUE,            ///< argument has invalid value (user error)
    126     C2_BAD_INDEX        = BAD_INDEX,            ///< argument uses invalid index (user error)
    127     C2_UNSUPPORTED      = UNKNOWN_TRANSACTION,  ///< argument/index is value but not supported \todo is this really BAD_INDEX/VALUE?
    128 
    129     // bad sequencing of events
    130     C2_DUPLICATE        = ALREADY_EXISTS,       ///< object already exists
    131     C2_NOT_FOUND        = NAME_NOT_FOUND,       ///< object not found
    132     C2_BAD_STATE        = INVALID_OPERATION,    ///< operation is not permitted in the current state
    133 
    134     // bad environment
    135     C2_NO_MEMORY        = NO_MEMORY,            ///< not enough memory to complete operation
    136     C2_NO_PERMISSION    = PERMISSION_DENIED,    ///< missing permission to complete operation
    137     C2_TIMED_OUT        = TIMED_OUT,            ///< operation did not complete within timeout
    138 
    139     // bad versioning
    140     C2_NOT_IMPLEMENTED  = UNKNOWN_TRANSACTION,  ///< operation is not implemented (optional only) \todo for now reuse error code
    141 
    142     // unknown fatal
    143     C2_CORRUPTED        = UNKNOWN_ERROR,        ///< some unexpected error prevented the operation
    144 };
    145 
    146 /// @}
    147 
    148 /// \defgroup utils Utilities
    149 /// @{
    150 
    151 #define C2_DO_NOT_COPY(type, args...) \
    152     type args& operator=(const type args&) = delete; \
    153     type(const type args&) = delete; \
    154 
    155 #define C2_PURE __attribute__((pure))
    156 #define C2_CONST __attribute__((const))
    157 #define C2_HIDE __attribute__((visibility("hidden")))
    158 #define C2_INTERNAL __attribute__((internal_linkage))
    159 
    160 #define DEFINE_OTHER_COMPARISON_OPERATORS(type) \
    161     inline bool operator!=(const type &other) { return !(*this == other); } \
    162     inline bool operator<=(const type &other) { return (*this == other) || (*this < other); } \
    163     inline bool operator>=(const type &other) { return !(*this < other); } \
    164     inline bool operator>(const type &other) { return !(*this < other) && !(*this == other); }
    165 
    166 #define DEFINE_FIELD_BASED_COMPARISON_OPERATORS(type, field) \
    167     inline bool operator<(const type &other) const { return field < other.field; } \
    168     inline bool operator==(const type &other) const { return field == other.field; } \
    169     DEFINE_OTHER_COMPARISON_OPERATORS(type)
    170 
    171 /// \cond INTERNAL
    172 
    173 /// \defgroup utils_internal
    174 /// @{
    175 
    176 template<typename... T> struct c2_types;
    177 
    178 /** specialization for a single type */
    179 template<typename T>
    180 struct c2_types<T> {
    181     typedef typename std::decay<T>::type wide_type;
    182     typedef wide_type narrow_type;
    183     typedef wide_type mintype;
    184 };
    185 
    186 /** specialization for two types */
    187 template<typename T, typename U>
    188 struct c2_types<T, U> {
    189     static_assert(std::is_floating_point<T>::value == std::is_floating_point<U>::value,
    190                   "mixing floating point and non-floating point types is disallowed");
    191     static_assert(std::is_signed<T>::value == std::is_signed<U>::value,
    192                   "mixing signed and unsigned types is disallowed");
    193 
    194     typedef typename std::decay<
    195             decltype(true ? std::declval<T>() : std::declval<U>())>::type wide_type;
    196     typedef typename std::decay<
    197             typename std::conditional<sizeof(T) < sizeof(U), T, U>::type>::type narrow_type;
    198     typedef typename std::conditional<
    199             std::is_signed<T>::value, wide_type, narrow_type>::type mintype;
    200 };
    201 
    202 /// @}
    203 
    204 /// \endcond
    205 
    206 /**
    207  * Type support utility class. Only supports similar classes, such as:
    208  * - all floating point
    209  * - all unsigned/all signed
    210  * - all pointer
    211  */
    212 template<typename T, typename U, typename... V>
    213 struct c2_types<T, U, V...> {
    214     /** Common type that accommodates all template parameter types. */
    215     typedef typename c2_types<typename c2_types<T, U>::wide_type, V...>::wide_type wide_type;
    216     /** Narrowest type of the template parameter types. */
    217     typedef typename c2_types<typename c2_types<T, U>::narrow_type, V...>::narrow_type narrow_type;
    218     /** Type that accommodates the minimum value for any input for the template parameter types. */
    219     typedef typename c2_types<typename c2_types<T, U>::mintype, V...>::mintype mintype;
    220 };
    221 
    222 /**
    223  *  \ingroup utils_internal
    224  * specialization for two values */
    225 template<typename T, typename U>
    226 inline constexpr typename c2_types<T, U>::wide_type c2_max(const T a, const U b) {
    227     typedef typename c2_types<T, U>::wide_type wide_type;
    228     return ({ wide_type a_(a), b_(b); a_ > b_ ? a_ : b_; });
    229 }
    230 
    231 /**
    232  * Finds the maximum value of a list of "similarly typed" values.
    233  *
    234  * This is an extension to std::max where the types do not have to be identical, and the smallest
    235  * resulting type is used that accommodates the argument types.
    236  *
    237  * \note Value types must be similar, e.g. all floating point, all pointers, all signed, or all
    238  * unsigned.
    239  *
    240  * @return the largest of the input arguments.
    241  */
    242 template<typename T, typename U, typename... V>
    243 constexpr typename c2_types<T, U, V...>::wide_type c2_max(const T a, const U b, const V ... c) {
    244     typedef typename c2_types<T, U, V...>::wide_type wide_type;
    245     return ({ wide_type a_(a), b_(c2_max(b, c...)); a_ > b_ ? a_ : b_; });
    246 }
    247 
    248 /**
    249  *  \ingroup utils_internal
    250  * specialization for two values */
    251 template<typename T, typename U>
    252 inline constexpr typename c2_types<T, U>::mintype c2_min(const T a, const U b) {
    253     typedef typename c2_types<T, U>::wide_type wide_type;
    254     return ({
    255         wide_type a_(a), b_(b);
    256         static_cast<typename c2_types<T, U>::mintype>(a_ < b_ ? a_ : b_);
    257     });
    258 }
    259 
    260 /**
    261  * Finds the minimum value of a list of "similarly typed" values.
    262  *
    263  * This is an extension to std::min where the types do not have to be identical, and the smallest
    264  * resulting type is used that accommodates the argument types.
    265  *
    266  * \note Value types must be similar, e.g. all floating point, all pointers, all signed, or all
    267  * unsigned.
    268  *
    269  * @return the smallest of the input arguments.
    270  */
    271 template<typename T, typename U, typename... V>
    272 constexpr typename c2_types<T, U, V...>::mintype c2_min(const T a, const U b, const V ... c) {
    273     typedef typename c2_types<U, V...>::mintype rest_type;
    274     typedef typename c2_types<T, rest_type>::wide_type wide_type;
    275     return ({
    276         wide_type a_(a), b_(c2_min(b, c...));
    277         static_cast<typename c2_types<T, rest_type>::mintype>(a_ < b_ ? a_ : b_);
    278     });
    279 }
    280 
    281 /// @}
    282 
    283 #ifdef __ANDROID__
    284 } // namespace android
    285 #endif
    286 
    287 #endif  // C2_H_
    288