blob: da587c429ca0417c3e83cc53192f6fffbd12da28 [file] [log] [blame]
Tim Murray7f0d5682012-11-08 16:35:24 -08001/*
2 * Copyright (C) 2008-2012 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
Tim Murray7f0d5682012-11-08 16:35:24 -080017#include <malloc.h>
18
19#include "RenderScript.h"
Tim Murrayfa77db82013-08-29 11:07:17 -070020#include "rsCppInternal.h"
Tim Murray7f0d5682012-11-08 16:35:24 -080021
Chih-Hung Hsiehdfcfabf2016-11-04 15:55:18 -070022using android::RSC::ScriptIntrinsic;
23using android::RSC::ScriptIntrinsic3DLUT;
24using android::RSC::ScriptIntrinsicBlend;
25using android::RSC::ScriptIntrinsicBlur;
26using android::RSC::ScriptIntrinsicColorMatrix;
27using android::RSC::ScriptIntrinsicConvolve3x3;
28using android::RSC::ScriptIntrinsicConvolve5x5;
29using android::RSC::ScriptIntrinsicHistogram;
30using android::RSC::ScriptIntrinsicLUT;
31using android::RSC::ScriptIntrinsicResize;
32using android::RSC::ScriptIntrinsicYuvToRGB;
33using android::RSC::sp;
Tim Murray7f0d5682012-11-08 16:35:24 -080034
Tim Murray3cd44af2012-11-14 11:25:27 -080035ScriptIntrinsic::ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e)
Chris Wailes44bef6f2014-08-12 13:51:10 -070036 : Script(nullptr, rs) {
Miao Wange5428e62015-03-10 15:29:40 -070037 mID = createDispatch(rs, RS::dispatch->ScriptIntrinsicCreate(rs->getContext(), id,
38 e != nullptr ? e->getID() : 0));
Tim Murray10913a52013-08-20 17:19:47 -070039 mElement = e;
Tim Murray7f0d5682012-11-08 16:35:24 -080040}
41
Tim Murrayb27b1812013-08-05 14:00:40 -070042ScriptIntrinsic::~ScriptIntrinsic() {
43
44}
45
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -070046sp<ScriptIntrinsic3DLUT> ScriptIntrinsic3DLUT::create(const sp<RS>& rs, const sp<const Element>& e) {
Tim Murray10913a52013-08-20 17:19:47 -070047 if (e->isCompatible(Element::U8_4(rs)) == false) {
48 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
Chris Wailes44bef6f2014-08-12 13:51:10 -070049 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -070050 }
Tim Murray21fa7a02013-08-15 16:25:03 -070051 return new ScriptIntrinsic3DLUT(rs, e);
52}
53
Tim Murray89daad62013-07-29 14:30:02 -070054ScriptIntrinsic3DLUT::ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e)
55 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_3DLUT, e) {
56
57}
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -070058void ScriptIntrinsic3DLUT::forEach(const sp<Allocation>& ain, const sp<Allocation>& aout) {
Tim Murray10913a52013-08-20 17:19:47 -070059 if (ain->getType()->getElement()->isCompatible(mElement) == false ||
60 aout->getType()->getElement()->isCompatible(mElement) == false) {
61 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "3DLUT forEach element mismatch");
62 return;
63 }
Chris Wailes44bef6f2014-08-12 13:51:10 -070064 Script::forEach(0, ain, aout, nullptr, 0);
Tim Murray89daad62013-07-29 14:30:02 -070065}
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -070066void ScriptIntrinsic3DLUT::setLUT(const sp<Allocation>& lut) {
Tim Murray10913a52013-08-20 17:19:47 -070067 sp<const Type> t = lut->getType();
68 if (!t->getElement()->isCompatible(mElement)) {
69 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "setLUT element does not match");
70 return;
71 }
72 if (t->getZ() == 0) {
73 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "setLUT Allocation must be 3D");
74 return;
75 }
76
Tim Murray89daad62013-07-29 14:30:02 -070077 Script::setVar(0, lut);
78}
79
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -070080sp<ScriptIntrinsicBlend> ScriptIntrinsicBlend::create(const sp<RS>& rs, const sp<const Element>& e) {
Tim Murray10913a52013-08-20 17:19:47 -070081 if (e->isCompatible(Element::U8_4(rs)) == false) {
82 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
Chris Wailes44bef6f2014-08-12 13:51:10 -070083 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -070084 }
Tim Murray21fa7a02013-08-15 16:25:03 -070085 return new ScriptIntrinsicBlend(rs, e);
86}
87
Tim Murray3cd44af2012-11-14 11:25:27 -080088ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e)
Tim Murray7f0d5682012-11-08 16:35:24 -080089 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) {
Tim Murray7f0d5682012-11-08 16:35:24 -080090}
91
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -070092void ScriptIntrinsicBlend::forEachClear(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -070093 if (in->getType()->getElement()->isCompatible(mElement) == false ||
94 out->getType()->getElement()->isCompatible(mElement) == false) {
95 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
96 }
Chris Wailes44bef6f2014-08-12 13:51:10 -070097 Script::forEach(0, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -080098}
99
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700100void ScriptIntrinsicBlend::forEachSrc(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700101 if (in->getType()->getElement()->isCompatible(mElement) == false ||
102 out->getType()->getElement()->isCompatible(mElement) == false) {
103 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
104 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700105 Script::forEach(1, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800106}
107
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700108void ScriptIntrinsicBlend::forEachDst(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700109 if (in->getType()->getElement()->isCompatible(mElement) == false ||
110 out->getType()->getElement()->isCompatible(mElement) == false) {
111 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
112 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700113 Script::forEach(2, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800114}
115
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700116void ScriptIntrinsicBlend::forEachSrcOver(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700117 if (in->getType()->getElement()->isCompatible(mElement) == false ||
118 out->getType()->getElement()->isCompatible(mElement) == false) {
119 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
120 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700121 Script::forEach(3, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800122}
123
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700124void ScriptIntrinsicBlend::forEachDstOver(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700125 if (in->getType()->getElement()->isCompatible(mElement) == false ||
126 out->getType()->getElement()->isCompatible(mElement) == false) {
127 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
128 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700129 Script::forEach(4, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800130}
131
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700132void ScriptIntrinsicBlend::forEachSrcIn(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700133 if (in->getType()->getElement()->isCompatible(mElement) == false ||
134 out->getType()->getElement()->isCompatible(mElement) == false) {
135 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
136 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700137 Script::forEach(5, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800138}
139
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700140void ScriptIntrinsicBlend::forEachDstIn(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700141 if (in->getType()->getElement()->isCompatible(mElement) == false ||
142 out->getType()->getElement()->isCompatible(mElement) == false) {
143 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
144 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700145 Script::forEach(6, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800146}
147
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700148void ScriptIntrinsicBlend::forEachSrcOut(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700149 if (in->getType()->getElement()->isCompatible(mElement) == false ||
150 out->getType()->getElement()->isCompatible(mElement) == false) {
151 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
152 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700153 Script::forEach(7, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800154}
155
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700156void ScriptIntrinsicBlend::forEachDstOut(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700157 if (in->getType()->getElement()->isCompatible(mElement) == false ||
158 out->getType()->getElement()->isCompatible(mElement) == false) {
159 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
160 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700161 Script::forEach(8, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800162}
163
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700164void ScriptIntrinsicBlend::forEachSrcAtop(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700165 if (in->getType()->getElement()->isCompatible(mElement) == false ||
166 out->getType()->getElement()->isCompatible(mElement) == false) {
167 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
168 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700169 Script::forEach(9, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800170}
171
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700172void ScriptIntrinsicBlend::forEachDstAtop(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700173 if (in->getType()->getElement()->isCompatible(mElement) == false ||
174 out->getType()->getElement()->isCompatible(mElement) == false) {
175 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
176 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700177 Script::forEach(10, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800178}
179
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700180void ScriptIntrinsicBlend::forEachXor(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700181 if (in->getType()->getElement()->isCompatible(mElement) == false ||
182 out->getType()->getElement()->isCompatible(mElement) == false) {
183 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
184 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700185 Script::forEach(11, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800186}
187
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700188void ScriptIntrinsicBlend::forEachMultiply(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700189 if (in->getType()->getElement()->isCompatible(mElement) == false ||
190 out->getType()->getElement()->isCompatible(mElement) == false) {
191 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
192 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700193 Script::forEach(14, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800194}
195
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700196void ScriptIntrinsicBlend::forEachAdd(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700197 if (in->getType()->getElement()->isCompatible(mElement) == false ||
198 out->getType()->getElement()->isCompatible(mElement) == false) {
199 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
200 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700201 Script::forEach(34, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800202}
203
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700204void ScriptIntrinsicBlend::forEachSubtract(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700205 if (in->getType()->getElement()->isCompatible(mElement) == false ||
206 out->getType()->getElement()->isCompatible(mElement) == false) {
207 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
208 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700209 Script::forEach(35, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800210}
211
Tim Murray89daad62013-07-29 14:30:02 -0700212
213
214
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700215sp<ScriptIntrinsicBlur> ScriptIntrinsicBlur::create(const sp<RS>& rs, const sp<const Element>& e) {
Tim Murray10913a52013-08-20 17:19:47 -0700216 if ((e->isCompatible(Element::U8_4(rs)) == false) &&
217 (e->isCompatible(Element::U8(rs)) == false)) {
218 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700219 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -0700220 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700221 return new ScriptIntrinsicBlur(rs, e);
222}
223
Tim Murray3cd44af2012-11-14 11:25:27 -0800224ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e)
Tim Murray8f1e60c2012-11-13 12:25:11 -0800225 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) {
Tim Murray7f0d5682012-11-08 16:35:24 -0800226
Tim Murray8f1e60c2012-11-13 12:25:11 -0800227}
Tim Murray7f0d5682012-11-08 16:35:24 -0800228
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700229void ScriptIntrinsicBlur::setInput(const sp<Allocation>& in) {
Tim Murray10913a52013-08-20 17:19:47 -0700230 if (in->getType()->getElement()->isCompatible(mElement) == false) {
231 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur input");
232 return;
233 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800234 Script::setVar(1, in);
Tim Murray21fa7a02013-08-15 16:25:03 -0700235}
236
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700237void ScriptIntrinsicBlur::forEach(const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700238 if (out->getType()->getElement()->isCompatible(mElement) == false) {
239 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur output");
240 return;
241 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700242 Script::forEach(0, nullptr, out, nullptr, 0);
Tim Murray8f1e60c2012-11-13 12:25:11 -0800243}
Tim Murray7f0d5682012-11-08 16:35:24 -0800244
Tim Murray8f1e60c2012-11-13 12:25:11 -0800245void ScriptIntrinsicBlur::setRadius(float radius) {
Tim Murray10913a52013-08-20 17:19:47 -0700246 if (radius > 0.f && radius <= 25.f) {
247 Script::setVar(0, &radius, sizeof(float));
248 } else {
249 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Blur radius out of 0-25 pixel bound");
250 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800251}
Tim Murray89daad62013-07-29 14:30:02 -0700252
253
254
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700255sp<ScriptIntrinsicColorMatrix> ScriptIntrinsicColorMatrix::create(const sp<RS>& rs) {
Tim Murrayaae73c92013-09-03 17:05:46 -0700256 return new ScriptIntrinsicColorMatrix(rs, Element::RGBA_8888(rs));
Tim Murray21fa7a02013-08-15 16:25:03 -0700257}
258
Tim Murray89daad62013-07-29 14:30:02 -0700259ScriptIntrinsicColorMatrix::ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e)
260 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_COLOR_MATRIX, e) {
Tim Murrayaae73c92013-09-03 17:05:46 -0700261 float add[4] = {0.f, 0.f, 0.f, 0.f};
262 setAdd(add);
Tim Murray89daad62013-07-29 14:30:02 -0700263
264}
265
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700266void ScriptIntrinsicColorMatrix::forEach(const sp<Allocation>& in, const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700267 if (!(in->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
268 !(in->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
269 !(in->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
270 !(in->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
271 !(in->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
272 !(in->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
273 !(in->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
274 !(in->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
275 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
276 return;
277 }
278
279 if (!(out->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
280 !(out->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
281 !(out->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
282 !(out->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
283 !(out->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
284 !(out->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
285 !(out->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
286 !(out->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
287 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
288 return;
289 }
290
Chris Wailes44bef6f2014-08-12 13:51:10 -0700291 Script::forEach(0, in, out, nullptr, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700292}
293
Tim Murray10913a52013-08-20 17:19:47 -0700294void ScriptIntrinsicColorMatrix::setAdd(float* add) {
295 Script::setVar(1, (void*)add, sizeof(float) * 4);
296}
Tim Murray89daad62013-07-29 14:30:02 -0700297
298void ScriptIntrinsicColorMatrix::setColorMatrix3(float* m) {
Tim Murrayaae73c92013-09-03 17:05:46 -0700299 float temp[16];
300 temp[0] = m[0];
301 temp[1] = m[1];
302 temp[2] = m[2];
303 temp[3] = 0.f;
304
305 temp[4] = m[3];
306 temp[5] = m[4];
307 temp[6] = m[5];
308 temp[7] = 0.f;
309
310 temp[8] = m[6];
311 temp[9] = m[7];
312 temp[10] = m[8];
313 temp[11] = 0.f;
314
315 temp[12] = 0.f;
316 temp[13] = 0.f;
317 temp[14] = 0.f;
318 temp[15] = 1.f;
319
320 setColorMatrix4(temp);
Tim Murray89daad62013-07-29 14:30:02 -0700321}
322
323
324void ScriptIntrinsicColorMatrix::setColorMatrix4(float* m) {
325 Script::setVar(0, (void*)m, sizeof(float) * 16);
326}
327
328
329void ScriptIntrinsicColorMatrix::setGreyscale() {
Tim Murrayaae73c92013-09-03 17:05:46 -0700330 float matrix[] = {0.299f, 0.299f, 0.299f,0.587f,0.587f,0.587f,0.114f,0.114f, 0.114f};
Tim Murray89daad62013-07-29 14:30:02 -0700331 setColorMatrix3(matrix);
332}
333
334
335void ScriptIntrinsicColorMatrix::setRGBtoYUV() {
Tim Murrayaae73c92013-09-03 17:05:46 -0700336 float matrix[] = { 0.299f, -0.14713f, 0.615f, 0.587f, -0.28886f, -0.51499f, 0.114f, 0.436f, -0.10001f};
Tim Murray89daad62013-07-29 14:30:02 -0700337 setColorMatrix3(matrix);
338}
339
340
341void ScriptIntrinsicColorMatrix::setYUVtoRGB() {
Tim Murrayaae73c92013-09-03 17:05:46 -0700342 float matrix[] = {1.f, 1.f, 1.f, 0.f, -0.39465f, 2.03211f, 1.13983f, -0.5806f, 0.f};
Tim Murray89daad62013-07-29 14:30:02 -0700343 setColorMatrix3(matrix);
344}
345
Tim Murray21fa7a02013-08-15 16:25:03 -0700346
347
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700348sp<ScriptIntrinsicConvolve3x3> ScriptIntrinsicConvolve3x3::create(const sp<RS>& rs, const sp<const Element>& e) {
Tim Murray10913a52013-08-20 17:19:47 -0700349 if (!(e->isCompatible(Element::U8(rs))) &&
350 !(e->isCompatible(Element::U8_2(rs))) &&
351 !(e->isCompatible(Element::U8_3(rs))) &&
352 !(e->isCompatible(Element::U8_4(rs))) &&
353 !(e->isCompatible(Element::F32(rs))) &&
354 !(e->isCompatible(Element::F32_2(rs))) &&
355 !(e->isCompatible(Element::F32_3(rs))) &&
356 !(e->isCompatible(Element::F32_4(rs)))) {
357 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve3x3");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700358 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -0700359 }
360
Tim Murray21fa7a02013-08-15 16:25:03 -0700361 return new ScriptIntrinsicConvolve3x3(rs, e);
362}
363
Tim Murray89daad62013-07-29 14:30:02 -0700364ScriptIntrinsicConvolve3x3::ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e)
365 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_3x3, e) {
366
367}
368
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700369void ScriptIntrinsicConvolve3x3::setInput(const sp<Allocation>& in) {
Tim Murray10913a52013-08-20 17:19:47 -0700370 if (!(in->getType()->getElement()->isCompatible(mElement))) {
371 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
372 return;
373 }
Tim Murray89daad62013-07-29 14:30:02 -0700374 Script::setVar(1, in);
375}
376
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700377void ScriptIntrinsicConvolve3x3::forEach(const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700378 if (!(out->getType()->getElement()->isCompatible(mElement))) {
379 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
380 return;
381 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700382 Script::forEach(0, nullptr, out, nullptr, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700383}
384
385void ScriptIntrinsicConvolve3x3::setCoefficients(float* v) {
386 Script::setVar(0, (void*)v, sizeof(float) * 9);
387}
388
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700389sp<ScriptIntrinsicConvolve5x5> ScriptIntrinsicConvolve5x5::create(const sp<RS>& rs, const sp<const Element>& e) {
Tim Murray10913a52013-08-20 17:19:47 -0700390 if (!(e->isCompatible(Element::U8(rs))) &&
391 !(e->isCompatible(Element::U8_2(rs))) &&
392 !(e->isCompatible(Element::U8_3(rs))) &&
393 !(e->isCompatible(Element::U8_4(rs))) &&
394 !(e->isCompatible(Element::F32(rs))) &&
395 !(e->isCompatible(Element::F32_2(rs))) &&
396 !(e->isCompatible(Element::F32_3(rs))) &&
397 !(e->isCompatible(Element::F32_4(rs)))) {
398 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve5x5");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700399 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -0700400 }
401
Tim Murray21fa7a02013-08-15 16:25:03 -0700402 return new ScriptIntrinsicConvolve5x5(rs, e);
403}
404
Tim Murray89daad62013-07-29 14:30:02 -0700405ScriptIntrinsicConvolve5x5::ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e)
406 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_5x5, e) {
407
408}
409
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700410void ScriptIntrinsicConvolve5x5::setInput(const sp<Allocation>& in) {
Tim Murray10913a52013-08-20 17:19:47 -0700411 if (!(in->getType()->getElement()->isCompatible(mElement))) {
412 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 input");
413 return;
414 }
Tim Murray89daad62013-07-29 14:30:02 -0700415 Script::setVar(1, in);
416}
417
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700418void ScriptIntrinsicConvolve5x5::forEach(const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700419 if (!(out->getType()->getElement()->isCompatible(mElement))) {
420 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 output");
421 return;
422 }
423
Chris Wailes44bef6f2014-08-12 13:51:10 -0700424 Script::forEach(0, nullptr, out, nullptr, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700425}
426
427void ScriptIntrinsicConvolve5x5::setCoefficients(float* v) {
428 Script::setVar(0, (void*)v, sizeof(float) * 25);
429}
430
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700431sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(const sp<RS>& rs, const sp<const Element>& e) {
Jon Parrb05c8502015-03-13 14:41:58 +0000432 return new ScriptIntrinsicHistogram(rs, e);
Tim Murray21fa7a02013-08-15 16:25:03 -0700433}
434
Tim Murrayb27b1812013-08-05 14:00:40 -0700435ScriptIntrinsicHistogram::ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e)
436 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_HISTOGRAM, e) {
Tim Murray89daad62013-07-29 14:30:02 -0700437
438}
439
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700440void ScriptIntrinsicHistogram::setOutput(const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700441 if (!(out->getType()->getElement()->isCompatible(Element::U32(mRS))) &&
442 !(out->getType()->getElement()->isCompatible(Element::U32_2(mRS))) &&
443 !(out->getType()->getElement()->isCompatible(Element::U32_3(mRS))) &&
444 !(out->getType()->getElement()->isCompatible(Element::U32_4(mRS))) &&
445 !(out->getType()->getElement()->isCompatible(Element::I32(mRS))) &&
446 !(out->getType()->getElement()->isCompatible(Element::I32_2(mRS))) &&
447 !(out->getType()->getElement()->isCompatible(Element::I32_3(mRS))) &&
448 !(out->getType()->getElement()->isCompatible(Element::I32_4(mRS)))) {
449 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Histogram output");
450 return;
451 }
452
453 if (out->getType()->getX() != 256 ||
454 out->getType()->getY() != 0 ||
455 out->getType()->hasMipmaps()) {
456 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid Allocation type for Histogram output");
457 return;
458 }
459 mOut = out;
460 Script::setVar(1, out);
Tim Murrayb27b1812013-08-05 14:00:40 -0700461}
462
463void ScriptIntrinsicHistogram::setDotCoefficients(float r, float g, float b, float a) {
464 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
465 return;
466 }
467 if ((r + g + b + a) > 1.f) {
468 return;
469 }
470
471 FieldPacker fp(16);
472 fp.add(r);
473 fp.add(g);
474 fp.add(b);
475 fp.add(a);
476 Script::setVar(0, fp.getData(), fp.getLength());
477
478}
479
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700480void ScriptIntrinsicHistogram::forEach(const sp<Allocation>& ain) {
Tim Murray10913a52013-08-20 17:19:47 -0700481 if (ain->getType()->getElement()->getVectorSize() <
482 mOut->getType()->getElement()->getVectorSize()) {
483 mRS->throwError(RS_ERROR_INVALID_PARAMETER,
484 "Input vector size must be >= output vector size");
485 return;
486 }
487
Jon Parrb05c8502015-03-13 14:41:58 +0000488 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
Tim Murray10913a52013-08-20 17:19:47 -0700489 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
490 mRS->throwError(RS_ERROR_INVALID_ELEMENT,
491 "Input allocation to Histogram must be U8 or U8_4");
492 return;
493 }
494
Chris Wailes44bef6f2014-08-12 13:51:10 -0700495 Script::forEach(0, ain, nullptr, nullptr, 0);
Tim Murrayb27b1812013-08-05 14:00:40 -0700496}
497
498
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700499void ScriptIntrinsicHistogram::forEach_dot(const sp<Allocation>& ain) {
Tim Murray10913a52013-08-20 17:19:47 -0700500 if (mOut->getType()->getElement()->getVectorSize() != 1) {
501 mRS->throwError(RS_ERROR_INVALID_PARAMETER,
502 "Output Histogram allocation must have vector size of 1 " \
503 "when used with forEach_dot");
504 return;
505 }
Jon Parrb05c8502015-03-13 14:41:58 +0000506 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
Tim Murray10913a52013-08-20 17:19:47 -0700507 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
508 mRS->throwError(RS_ERROR_INVALID_ELEMENT,
509 "Input allocation to Histogram must be U8 or U8_4");
510 return;
511 }
512
Chris Wailes44bef6f2014-08-12 13:51:10 -0700513 Script::forEach(1, ain, nullptr, nullptr, 0);
Tim Murrayb27b1812013-08-05 14:00:40 -0700514}
515
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700516sp<ScriptIntrinsicLUT> ScriptIntrinsicLUT::create(const sp<RS>& rs, const sp<const Element>& e) {
Tim Murray10913a52013-08-20 17:19:47 -0700517 if (!(e->isCompatible(Element::U8_4(rs)))) {
518 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700519 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -0700520 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700521 return new ScriptIntrinsicLUT(rs, e);
522}
523
Tim Murrayb27b1812013-08-05 14:00:40 -0700524ScriptIntrinsicLUT::ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e)
525 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_LUT, e), mDirty(true) {
Tim Murray2acce992013-08-28 14:23:31 -0700526 LUT = Allocation::createSized(rs, Element::U8(rs), 1024);
Tim Murrayb27b1812013-08-05 14:00:40 -0700527 for (int i = 0; i < 256; i++) {
528 mCache[i] = i;
529 mCache[i+256] = i;
530 mCache[i+512] = i;
531 mCache[i+768] = i;
532 }
Tim Murray2acce992013-08-28 14:23:31 -0700533 setVar(0, LUT);
Tim Murrayb27b1812013-08-05 14:00:40 -0700534}
535
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700536void ScriptIntrinsicLUT::forEach(const sp<Allocation>& ain, const sp<Allocation>& aout) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700537 if (mDirty) {
538 LUT->copy1DFrom((void*)mCache);
539 mDirty = false;
540 }
Tim Murray10913a52013-08-20 17:19:47 -0700541 if (!(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) ||
542 !(aout->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
543 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
544 return;
545 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700546 Script::forEach(0, ain, aout, nullptr, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700547
548}
549
Tim Murray2acce992013-08-28 14:23:31 -0700550void ScriptIntrinsicLUT::setTable(unsigned int offset, unsigned char base, unsigned int length, unsigned char* lutValues) {
551 if ((base + length) > 256 || length == 0) {
552 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
Tim Murrayb27b1812013-08-05 14:00:40 -0700553 return;
554 }
555 mDirty = true;
Tim Murray2acce992013-08-28 14:23:31 -0700556 for (unsigned int i = 0; i < length; i++) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700557 mCache[offset + base + i] = lutValues[i];
558 }
559}
Tim Murray89daad62013-07-29 14:30:02 -0700560
Tim Murray2acce992013-08-28 14:23:31 -0700561void ScriptIntrinsicLUT::setRed(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700562 setTable(0, base, length, lutValues);
563}
Tim Murray89daad62013-07-29 14:30:02 -0700564
Tim Murray2acce992013-08-28 14:23:31 -0700565void ScriptIntrinsicLUT::setGreen(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700566 setTable(256, base, length, lutValues);
567}
568
Tim Murray2acce992013-08-28 14:23:31 -0700569void ScriptIntrinsicLUT::setBlue(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700570 setTable(512, base, length, lutValues);
571}
572
Tim Murray2acce992013-08-28 14:23:31 -0700573void ScriptIntrinsicLUT::setAlpha(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700574 setTable(768, base, length, lutValues);
575}
576
577ScriptIntrinsicLUT::~ScriptIntrinsicLUT() {
578
579}
580
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700581sp<ScriptIntrinsicResize> ScriptIntrinsicResize::create(const sp<RS>& rs) {
Miao Wange5428e62015-03-10 15:29:40 -0700582 return new ScriptIntrinsicResize(rs, nullptr);
583}
584
585ScriptIntrinsicResize::ScriptIntrinsicResize(sp<RS> rs, sp<const Element> e)
586 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_RESIZE, e) {
587
588}
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700589void ScriptIntrinsicResize::forEach_bicubic(const sp<Allocation>& aout) {
Miao Wange5428e62015-03-10 15:29:40 -0700590 if (aout == mInput) {
591 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Resize Input and Ouput cannot be the same");
592 }
593
594 if (!(mInput->getType()->getElement()->isCompatible(aout->getType()->getElement()))) {
595 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Resize forEach element mismatch");
596 return;
597 }
598 Script::forEach(0, nullptr, aout, nullptr, 0);
599}
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700600void ScriptIntrinsicResize::setInput(const sp<Allocation>& ain) {
Miao Wange5428e62015-03-10 15:29:40 -0700601 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
602 !(ain->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
603 !(ain->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
604 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
605 !(ain->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
606 !(ain->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
607 !(ain->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
608 !(ain->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
609 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Resize Input");
610 return;
611 }
612
613 mInput = ain;
614 Script::setVar(0, ain);
615}
616
617
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700618sp<ScriptIntrinsicYuvToRGB> ScriptIntrinsicYuvToRGB::create(const sp<RS>& rs, const sp<const Element>& e) {
Tim Murray10913a52013-08-20 17:19:47 -0700619 if (!(e->isCompatible(Element::U8_4(rs)))) {
620 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for YuvToRGB");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700621 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -0700622 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700623 return new ScriptIntrinsicYuvToRGB(rs, e);
624}
625
Tim Murrayb27b1812013-08-05 14:00:40 -0700626ScriptIntrinsicYuvToRGB::ScriptIntrinsicYuvToRGB(sp<RS> rs, sp<const Element> e)
627 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB, e) {
628
629}
630
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700631void ScriptIntrinsicYuvToRGB::setInput(const sp<Allocation>& in) {
Tim Murrayeb4426d2013-08-27 15:30:16 -0700632 if (!(in->getType()->getElement()->isCompatible(Element::YUV(mRS)))) {
Tim Murray10913a52013-08-20 17:19:47 -0700633 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for input in YuvToRGB");
634 return;
635 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700636 Script::setVar(0, in);
637}
638
Chih-Hung Hsieh45768e12016-08-10 12:32:11 -0700639void ScriptIntrinsicYuvToRGB::forEach(const sp<Allocation>& out) {
Tim Murray10913a52013-08-20 17:19:47 -0700640 if (!(out->getType()->getElement()->isCompatible(mElement))) {
641 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for output in YuvToRGB");
642 return;
643 }
644
Chris Wailes44bef6f2014-08-12 13:51:10 -0700645 Script::forEach(0, nullptr, out, nullptr, 0);
Chih-Hung Hsiehdfcfabf2016-11-04 15:55:18 -0700646}