xref: /aosp_15_r20/frameworks/rs/toolkit/test/IntrinsicConvolve.kt (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
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 package com.example.testapp
18 
19 import android.graphics.Bitmap
20 import android.renderscript.Allocation
21 import android.renderscript.Element
22 import android.renderscript.RenderScript
23 import android.renderscript.Script
24 import android.renderscript.ScriptIntrinsicConvolve3x3
25 import android.renderscript.ScriptIntrinsicConvolve5x5
26 import android.renderscript.Type
27 import android.renderscript.toolkit.Range2d
28 
29 /**
30  * Does a Convolve operation using the RenderScript Intrinsics.
31  */
intrinsicConvolvenull32 fun intrinsicConvolve(
33     context: RenderScript,
34     inputArray: ByteArray,
35     vectorSize: Int,
36     sizeX: Int,
37     sizeY: Int,
38     coefficients: FloatArray,
39     restriction: Range2d?
40 ): ByteArray {
41     val baseElement = renderScriptVectorElementForU8(context, vectorSize)
42     val builder = Type.Builder(context, baseElement)
43     builder.setX(sizeX)
44     builder.setY(sizeY)
45     val arrayType = builder.create()
46     val inputAllocation = Allocation.createTyped(context, arrayType)
47     val outAllocation = Allocation.createTyped(context, arrayType)
48     inputAllocation.copyFrom(inputArray)
49     val intrinsicOutArray = ByteArray(sizeX * sizeY * paddedSize(vectorSize))
50     if (restriction != null) {
51         outAllocation.copyFrom(intrinsicOutArray) // To initialize to zero
52     }
53     invokeConvolveKernel(
54         coefficients,
55         context,
56         baseElement,
57         inputAllocation,
58         restriction,
59         outAllocation
60     )
61     outAllocation.copyTo(intrinsicOutArray)
62     inputAllocation.destroy()
63     outAllocation.destroy()
64     arrayType.destroy()
65     return intrinsicOutArray
66 }
67 
intrinsicConvolvenull68 fun intrinsicConvolve(
69     context: RenderScript,
70     bitmap: Bitmap,
71     coefficients: FloatArray,
72     restriction: Range2d?
73 ): ByteArray {
74     val baseElement = renderScriptElementForBitmap(context, bitmap)
75 
76     val inputAllocation = Allocation.createFromBitmap(context, bitmap)
77     val outAllocation = Allocation.createTyped(context, inputAllocation.type)
78     val intrinsicOutArray = ByteArray(bitmap.byteCount)
79     inputAllocation.copyFrom(bitmap)
80     if (restriction != null) {
81         outAllocation.copyFrom(intrinsicOutArray) // To initialize to zero
82     }
83     invokeConvolveKernel(
84         coefficients,
85         context,
86         baseElement,
87         inputAllocation,
88         restriction,
89         outAllocation
90     )
91     outAllocation.copyTo(intrinsicOutArray)
92     inputAllocation.destroy()
93     outAllocation.destroy()
94     return intrinsicOutArray
95 }
96 
invokeConvolveKernelnull97 private fun invokeConvolveKernel(
98     coefficients: FloatArray,
99     context: RenderScript,
100     baseElement: Element,
101     inputAllocation: Allocation?,
102     restriction: Range2d?,
103     outAllocation: Allocation?
104 ) {
105     when (coefficients.size) {
106         9 -> {
107             val scriptConvolve3x3 =
108                 ScriptIntrinsicConvolve3x3.create(context, baseElement)
109             scriptConvolve3x3.setCoefficients(coefficients)
110             scriptConvolve3x3.setInput(inputAllocation)
111             if (restriction != null) {
112                 val options = Script.LaunchOptions()
113                 options.setX(restriction.startX, restriction.endX)
114                 options.setY(restriction.startY, restriction.endY)
115                 scriptConvolve3x3.forEach(outAllocation, options)
116             } else {
117                 scriptConvolve3x3.forEach(outAllocation)
118             }
119             scriptConvolve3x3.destroy()
120         }
121         25 -> {
122             val scriptConvolve5x5 =
123                 ScriptIntrinsicConvolve5x5.create(context, baseElement)
124             scriptConvolve5x5.setCoefficients(coefficients)
125             scriptConvolve5x5.setInput(inputAllocation)
126             if (restriction != null) {
127                 val options = Script.LaunchOptions()
128                 options.setX(restriction.startX, restriction.endX)
129                 options.setY(restriction.startY, restriction.endY)
130                 scriptConvolve5x5.forEach(outAllocation, options)
131             } else {
132                 scriptConvolve5x5.forEach(outAllocation)
133             }
134             scriptConvolve5x5.destroy()
135         }
136         else -> {
137             throw IllegalArgumentException("RenderScriptToolkit tests. Only 3x3 and 5x5 convolutions are supported. ${coefficients.size} coefficients provided.")
138         }
139     }
140 }
141