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
29namespace android {
30
31#else
32
33#include <errno.h>
34typedef int64_t nsecs_t;
35
36enum {
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 */
100typedef std::string C2String;
101typedef const char *C2StringLiteral;
102
103/**
104 * C2Error: status codes used.
105 */
106typedef int32_t C2Error;
107enum {
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
176template<typename... T> struct c2_types;
177
178/** specialization for a single type */
179template<typename T>
180struct 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 */
187template<typename T, typename U>
188struct 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 */
212template<typename T, typename U, typename... V>
213struct 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 */
225template<typename T, typename U>
226inline 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 */
242template<typename T, typename U, typename... V>
243constexpr 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 */
251template<typename T, typename U>
252inline 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 */
271template<typename T, typename U, typename... V>
272constexpr 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