1 /*
2  * Copyright (C) 2021 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 ANDROID_RENDERSCRIPT_TOOLKIT_UTILS_H
18 #define ANDROID_RENDERSCRIPT_TOOLKIT_UTILS_H
19 
20 #include <android/log.h>
21 
22 namespace android {
23 namespace renderscript {
24 
25 /* The Toolkit does not support floating point buffers but the original RenderScript Intrinsics
26  * did for some operations. That code was preserved and protected by
27  * ANDROID_RENDERSCRIPT_TOOLKIT_SUPPORTS_FLOAT.
28  */
29 // TODO: On final packaging, decide whether this should be define in the build file, and for which
30 // config. #define ANDROID_RENDERSCRIPT_TOOLKIT_SUPPORTS_FLOAT
31 
32 /* If we release the Toolkit as a C++ API, we'll want to enable validation at the C++ level
33  * by uncommenting this define.
34  *
35  * If we only have a Java/Kotlin API, the Kotlin layer does validation. We don't need to duplicate
36  * this effort.
37  */
38 #define ANDROID_RENDERSCRIPT_TOOLKIT_VALIDATE
39 
40 #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
41 #define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
42 #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
43 
44 using uchar = unsigned char;
45 using uint = unsigned int;
46 using ushort = unsigned short;
47 
48 using uint8_t = uchar;
49 using uint16_t = ushort;
50 using uint32_t = uint;
51 
52 typedef float float2 __attribute__((ext_vector_type(2)));
53 typedef float float3 __attribute__((ext_vector_type(3)));
54 typedef float float4 __attribute__((ext_vector_type(4)));
55 typedef uchar uchar2 __attribute__((ext_vector_type(2)));
56 typedef uchar uchar3 __attribute__((ext_vector_type(3)));
57 typedef uchar uchar4 __attribute__((ext_vector_type(4)));
58 typedef ushort ushort2 __attribute__((ext_vector_type(2)));
59 typedef ushort ushort3 __attribute__((ext_vector_type(3)));
60 typedef ushort ushort4 __attribute__((ext_vector_type(4)));
61 typedef uint uint2 __attribute__((ext_vector_type(2)));
62 typedef uint uint3 __attribute__((ext_vector_type(3)));
63 typedef uint uint4 __attribute__((ext_vector_type(4)));
64 typedef short short2 __attribute__((ext_vector_type(2)));
65 typedef short short3 __attribute__((ext_vector_type(3)));
66 typedef short short4 __attribute__((ext_vector_type(4)));
67 typedef int int2 __attribute__((ext_vector_type(2)));
68 typedef int int3 __attribute__((ext_vector_type(3)));
69 typedef int int4 __attribute__((ext_vector_type(4)));
70 
71 template <typename TO, typename TI>
convert(TI i)72 inline TO convert(TI i) {
73     // assert(i.x >= 0 && i.y >= 0 && i.z >= 0 && i.w >= 0);
74     // assert(i.x <= 255 && i.y <= 255 && i.z <= 255 && i.w <= 255);
75     return __builtin_convertvector(i, TO);
76 }
77 
78 template <>
convert(float i)79 inline uchar convert(float i) {
80     // assert(i.x >= 0 && i.y >= 0 && i.z >= 0 && i.w >= 0);
81     // assert(i.x <= 255 && i.y <= 255 && i.z <= 255 && i.w <= 255);
82     return (uchar)i;
83 }
84 
85 template <>
convert(uchar i)86 inline float convert(uchar i) {
87     // assert(i.x >= 0 && i.y >= 0 && i.z >= 0 && i.w >= 0);
88     // assert(i.x <= 255 && i.y <= 255 && i.z <= 255 && i.w <= 255);
89     return (float)i;
90 }
91 
clamp(int4 amount,int low,int high)92 inline int4 clamp(int4 amount, int low, int high) {
93     int4 r;
94     r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
95     r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
96     r.z = amount.z < low ? low : (amount.z > high ? high : amount.z);
97     r.w = amount.w < low ? low : (amount.w > high ? high : amount.w);
98     return r;
99 }
100 
clamp(float4 amount,float low,float high)101 inline float4 clamp(float4 amount, float low, float high) {
102     float4 r;
103     r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
104     r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
105     r.z = amount.z < low ? low : (amount.z > high ? high : amount.z);
106     r.w = amount.w < low ? low : (amount.w > high ? high : amount.w);
107     return r;
108 }
109 
clamp(int2 amount,int low,int high)110 inline int2 clamp(int2 amount, int low, int high) {
111     int2 r;
112     r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
113     r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
114     return r;
115 }
116 
clamp(float2 amount,float low,float high)117 inline float2 clamp(float2 amount, float low, float high) {
118     float2 r;
119     r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
120     r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
121     return r;
122 }
123 
clamp(int amount,int low,int high)124 inline int clamp(int amount, int low, int high) {
125     return amount < low ? low : (amount > high ? high : amount);
126 }
127 
clamp(float amount,float low,float high)128 inline float clamp(float amount, float low, float high) {
129     return amount < low ? low : (amount > high ? high : amount);
130 }
131 
132 #ifdef ANDROID_RENDERSCRIPT_TOOLKIT_VALIDATE
133 struct Restriction;
134 
135 bool validRestriction(const char* tag, size_t sizeX, size_t sizeY, const Restriction* restriction);
136 #endif
137 
138 /**
139  * Returns true if the processor we're running on supports the SIMD instructions that are
140  * used in our assembly code.
141  */
142 bool cpuSupportsSimd();
143 
divideRoundingUp(size_t a,size_t b)144 inline size_t divideRoundingUp(size_t a, size_t b) {
145     return a / b + (a % b == 0 ? 0 : 1);
146 }
147 
paddedSize(size_t size)148 inline size_t paddedSize(size_t size) {
149     return size == 3 ? 4 : size;
150 }
151 
152 }  // namespace renderscript
153 }  // namespace android
154 
155 #endif  // ANDROID_RENDERSCRIPT_TOOLKIT_UTILS_H
156