1 /*
2 * Copyright 2019 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 @file:Suppress("NOTHING_TO_INLINE")
18
19 package androidx.compose.ui.util
20
21 // These two functions are technically identical to Float.fromBits()
22 // and Double.fromBits(). However, since they are declared as top-
23 // level functions, they do not incur the cost of a static fetch
24 // through the Companion class. Using these top-level functions,
25 // the generated arm64 code after dex2oat is exactly a single `fmov`
26
27 /** Returns the [Float] value corresponding to a given bit representation. */
floatFromBitsnull28 expect fun floatFromBits(bits: Int): Float
29
30 /** Returns the [Double] value corresponding to a given bit representation. */
31 expect fun doubleFromBits(bits: Long): Double
32
33 /**
34 * Returns the closest integer to the argument, tying rounding to positive infinity. Some values are
35 * treated differently:
36 * - NaN becomes 0
37 * - -Infinity or any value less than Integer.MIN_VALUE becomes Integer.MIN_VALUE.toFloat()
38 * - +Infinity or any value greater than Integer.MAX_VALUE becomes Integer.MAX_VALUE.toFloat()
39 */
40 expect fun Float.fastRoundToInt(): Int
41
42 /**
43 * Returns the closest integer to the argument, tying rounding to positive infinity. Some values are
44 * treated differently:
45 * - NaN becomes 0
46 * - -Infinity or any value less than Integer.MIN_VALUE becomes Integer.MIN_VALUE.toFloat()
47 * - +Infinity or any value greater than Integer.MAX_VALUE becomes Integer.MAX_VALUE.toFloat()
48 */
49 expect fun Double.fastRoundToInt(): Int
50
51 /** Packs two Float values into one Long value for use in inline classes. */
52 inline fun packFloats(val1: Float, val2: Float): Long {
53 val v1 = val1.toRawBits().toLong()
54 val v2 = val2.toRawBits().toLong()
55 return (v1 shl 32) or (v2 and 0xFFFFFFFF)
56 }
57
58 /** Unpacks the first Float value in [packFloats] from its returned Long. */
unpackFloat1null59 inline fun unpackFloat1(value: Long): Float {
60 return floatFromBits((value shr 32).toInt())
61 }
62
63 /** Unpacks the first absolute Float value in [packFloats] from its returned Long. */
unpackAbsFloat1null64 inline fun unpackAbsFloat1(value: Long): Float {
65 return floatFromBits(((value shr 32) and 0x7FFFFFFF).toInt())
66 }
67
68 /** Unpacks the second Float value in [packFloats] from its returned Long. */
unpackFloat2null69 inline fun unpackFloat2(value: Long): Float {
70 return floatFromBits((value and 0xFFFFFFFF).toInt())
71 }
72
73 /** Unpacks the second absolute Float value in [packFloats] from its returned Long. */
unpackAbsFloat2null74 inline fun unpackAbsFloat2(value: Long): Float {
75 return floatFromBits((value and 0x7FFFFFFF).toInt())
76 }
77
78 /** Packs two Int values into one Long value for use in inline classes. */
packIntsnull79 inline fun packInts(val1: Int, val2: Int): Long {
80 return (val1.toLong() shl 32) or (val2.toLong() and 0xFFFFFFFF)
81 }
82
83 /** Unpacks the first Int value in [packInts] from its returned ULong. */
unpackInt1null84 inline fun unpackInt1(value: Long): Int {
85 return (value shr 32).toInt()
86 }
87
88 /** Unpacks the second Int value in [packInts] from its returned ULong. */
unpackInt2null89 inline fun unpackInt2(value: Long): Int {
90 return (value and 0xFFFFFFFF).toInt()
91 }
92