blob: 38224e69350a503fc9e262c4fba08b31206aa278 [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
22using namespace android;
Tim Murray9eb7f4b2012-11-16 14:02:18 -080023using namespace RSC;
Tim Murray7f0d5682012-11-08 16:35:24 -080024
Tim Murray3cd44af2012-11-14 11:25:27 -080025ScriptIntrinsic::ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e)
Chris Wailes44bef6f2014-08-12 13:51:10 -070026 : Script(nullptr, rs) {
Miao Wange5428e62015-03-10 15:29:40 -070027 mID = createDispatch(rs, RS::dispatch->ScriptIntrinsicCreate(rs->getContext(), id,
28 e != nullptr ? e->getID() : 0));
Tim Murray10913a52013-08-20 17:19:47 -070029 mElement = e;
Tim Murray7f0d5682012-11-08 16:35:24 -080030}
31
Tim Murrayb27b1812013-08-05 14:00:40 -070032ScriptIntrinsic::~ScriptIntrinsic() {
33
34}
35
Tim Murray21fa7a02013-08-15 16:25:03 -070036sp<ScriptIntrinsic3DLUT> ScriptIntrinsic3DLUT::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -070037 if (e->isCompatible(Element::U8_4(rs)) == false) {
38 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
Chris Wailes44bef6f2014-08-12 13:51:10 -070039 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -070040 }
Tim Murray21fa7a02013-08-15 16:25:03 -070041 return new ScriptIntrinsic3DLUT(rs, e);
42}
43
Tim Murray89daad62013-07-29 14:30:02 -070044ScriptIntrinsic3DLUT::ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e)
45 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_3DLUT, e) {
46
47}
48void ScriptIntrinsic3DLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
Tim Murray10913a52013-08-20 17:19:47 -070049 if (ain->getType()->getElement()->isCompatible(mElement) == false ||
50 aout->getType()->getElement()->isCompatible(mElement) == false) {
51 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "3DLUT forEach element mismatch");
52 return;
53 }
Chris Wailes44bef6f2014-08-12 13:51:10 -070054 Script::forEach(0, ain, aout, nullptr, 0);
Tim Murray89daad62013-07-29 14:30:02 -070055}
56void ScriptIntrinsic3DLUT::setLUT(sp<Allocation> lut) {
Tim Murray10913a52013-08-20 17:19:47 -070057 sp<const Type> t = lut->getType();
58 if (!t->getElement()->isCompatible(mElement)) {
59 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "setLUT element does not match");
60 return;
61 }
62 if (t->getZ() == 0) {
63 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "setLUT Allocation must be 3D");
64 return;
65 }
66
Tim Murray89daad62013-07-29 14:30:02 -070067 Script::setVar(0, lut);
68}
69
Tim Murray21fa7a02013-08-15 16:25:03 -070070sp<ScriptIntrinsicBlend> ScriptIntrinsicBlend::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -070071 if (e->isCompatible(Element::U8_4(rs)) == false) {
72 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
Chris Wailes44bef6f2014-08-12 13:51:10 -070073 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -070074 }
Tim Murray21fa7a02013-08-15 16:25:03 -070075 return new ScriptIntrinsicBlend(rs, e);
76}
77
Tim Murray3cd44af2012-11-14 11:25:27 -080078ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e)
Tim Murray7f0d5682012-11-08 16:35:24 -080079 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) {
Tim Murray7f0d5682012-11-08 16:35:24 -080080}
81
Tim Murray75e877d2013-09-11 14:45:20 -070082void ScriptIntrinsicBlend::forEachClear(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -070083 if (in->getType()->getElement()->isCompatible(mElement) == false ||
84 out->getType()->getElement()->isCompatible(mElement) == false) {
85 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
86 }
Chris Wailes44bef6f2014-08-12 13:51:10 -070087 Script::forEach(0, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -080088}
89
Tim Murray75e877d2013-09-11 14:45:20 -070090void ScriptIntrinsicBlend::forEachSrc(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -070091 if (in->getType()->getElement()->isCompatible(mElement) == false ||
92 out->getType()->getElement()->isCompatible(mElement) == false) {
93 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
94 }
Chris Wailes44bef6f2014-08-12 13:51:10 -070095 Script::forEach(1, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -080096}
97
Tim Murray75e877d2013-09-11 14:45:20 -070098void ScriptIntrinsicBlend::forEachDst(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -070099 if (in->getType()->getElement()->isCompatible(mElement) == false ||
100 out->getType()->getElement()->isCompatible(mElement) == false) {
101 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
102 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700103 Script::forEach(2, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800104}
105
Tim Murray75e877d2013-09-11 14:45:20 -0700106void ScriptIntrinsicBlend::forEachSrcOver(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700107 if (in->getType()->getElement()->isCompatible(mElement) == false ||
108 out->getType()->getElement()->isCompatible(mElement) == false) {
109 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
110 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700111 Script::forEach(3, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800112}
113
Tim Murray75e877d2013-09-11 14:45:20 -0700114void ScriptIntrinsicBlend::forEachDstOver(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700115 if (in->getType()->getElement()->isCompatible(mElement) == false ||
116 out->getType()->getElement()->isCompatible(mElement) == false) {
117 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
118 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700119 Script::forEach(4, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800120}
121
Tim Murray75e877d2013-09-11 14:45:20 -0700122void ScriptIntrinsicBlend::forEachSrcIn(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700123 if (in->getType()->getElement()->isCompatible(mElement) == false ||
124 out->getType()->getElement()->isCompatible(mElement) == false) {
125 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
126 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700127 Script::forEach(5, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800128}
129
Tim Murray75e877d2013-09-11 14:45:20 -0700130void ScriptIntrinsicBlend::forEachDstIn(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700131 if (in->getType()->getElement()->isCompatible(mElement) == false ||
132 out->getType()->getElement()->isCompatible(mElement) == false) {
133 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
134 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700135 Script::forEach(6, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800136}
137
Tim Murray75e877d2013-09-11 14:45:20 -0700138void ScriptIntrinsicBlend::forEachSrcOut(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700139 if (in->getType()->getElement()->isCompatible(mElement) == false ||
140 out->getType()->getElement()->isCompatible(mElement) == false) {
141 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
142 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700143 Script::forEach(7, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800144}
145
Tim Murray75e877d2013-09-11 14:45:20 -0700146void ScriptIntrinsicBlend::forEachDstOut(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700147 if (in->getType()->getElement()->isCompatible(mElement) == false ||
148 out->getType()->getElement()->isCompatible(mElement) == false) {
149 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
150 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700151 Script::forEach(8, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800152}
153
Tim Murray75e877d2013-09-11 14:45:20 -0700154void ScriptIntrinsicBlend::forEachSrcAtop(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700155 if (in->getType()->getElement()->isCompatible(mElement) == false ||
156 out->getType()->getElement()->isCompatible(mElement) == false) {
157 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
158 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700159 Script::forEach(9, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800160}
161
Tim Murray75e877d2013-09-11 14:45:20 -0700162void ScriptIntrinsicBlend::forEachDstAtop(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700163 if (in->getType()->getElement()->isCompatible(mElement) == false ||
164 out->getType()->getElement()->isCompatible(mElement) == false) {
165 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
166 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700167 Script::forEach(10, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800168}
169
Tim Murray75e877d2013-09-11 14:45:20 -0700170void ScriptIntrinsicBlend::forEachXor(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700171 if (in->getType()->getElement()->isCompatible(mElement) == false ||
172 out->getType()->getElement()->isCompatible(mElement) == false) {
173 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
174 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700175 Script::forEach(11, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800176}
177
Tim Murray75e877d2013-09-11 14:45:20 -0700178void ScriptIntrinsicBlend::forEachMultiply(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700179 if (in->getType()->getElement()->isCompatible(mElement) == false ||
180 out->getType()->getElement()->isCompatible(mElement) == false) {
181 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
182 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700183 Script::forEach(14, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800184}
185
Tim Murray75e877d2013-09-11 14:45:20 -0700186void ScriptIntrinsicBlend::forEachAdd(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700187 if (in->getType()->getElement()->isCompatible(mElement) == false ||
188 out->getType()->getElement()->isCompatible(mElement) == false) {
189 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
190 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700191 Script::forEach(34, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800192}
193
Tim Murray75e877d2013-09-11 14:45:20 -0700194void ScriptIntrinsicBlend::forEachSubtract(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700195 if (in->getType()->getElement()->isCompatible(mElement) == false ||
196 out->getType()->getElement()->isCompatible(mElement) == false) {
197 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
198 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700199 Script::forEach(35, in, out, nullptr, 0);
Tim Murray7f0d5682012-11-08 16:35:24 -0800200}
201
Tim Murray89daad62013-07-29 14:30:02 -0700202
203
204
Tim Murray21fa7a02013-08-15 16:25:03 -0700205sp<ScriptIntrinsicBlur> ScriptIntrinsicBlur::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700206 if ((e->isCompatible(Element::U8_4(rs)) == false) &&
207 (e->isCompatible(Element::U8(rs)) == false)) {
208 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700209 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -0700210 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700211 return new ScriptIntrinsicBlur(rs, e);
212}
213
Tim Murray3cd44af2012-11-14 11:25:27 -0800214ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e)
Tim Murray8f1e60c2012-11-13 12:25:11 -0800215 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) {
Tim Murray7f0d5682012-11-08 16:35:24 -0800216
Tim Murray8f1e60c2012-11-13 12:25:11 -0800217}
Tim Murray7f0d5682012-11-08 16:35:24 -0800218
Tim Murray21fa7a02013-08-15 16:25:03 -0700219void ScriptIntrinsicBlur::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700220 if (in->getType()->getElement()->isCompatible(mElement) == false) {
221 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur input");
222 return;
223 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800224 Script::setVar(1, in);
Tim Murray21fa7a02013-08-15 16:25:03 -0700225}
226
227void ScriptIntrinsicBlur::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700228 if (out->getType()->getElement()->isCompatible(mElement) == false) {
229 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur output");
230 return;
231 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700232 Script::forEach(0, nullptr, out, nullptr, 0);
Tim Murray8f1e60c2012-11-13 12:25:11 -0800233}
Tim Murray7f0d5682012-11-08 16:35:24 -0800234
Tim Murray8f1e60c2012-11-13 12:25:11 -0800235void ScriptIntrinsicBlur::setRadius(float radius) {
Tim Murray10913a52013-08-20 17:19:47 -0700236 if (radius > 0.f && radius <= 25.f) {
237 Script::setVar(0, &radius, sizeof(float));
238 } else {
239 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Blur radius out of 0-25 pixel bound");
240 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800241}
Tim Murray89daad62013-07-29 14:30:02 -0700242
243
244
Tim Murrayaae73c92013-09-03 17:05:46 -0700245sp<ScriptIntrinsicColorMatrix> ScriptIntrinsicColorMatrix::create(sp<RS> rs) {
246 return new ScriptIntrinsicColorMatrix(rs, Element::RGBA_8888(rs));
Tim Murray21fa7a02013-08-15 16:25:03 -0700247}
248
Tim Murray89daad62013-07-29 14:30:02 -0700249ScriptIntrinsicColorMatrix::ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e)
250 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_COLOR_MATRIX, e) {
Tim Murrayaae73c92013-09-03 17:05:46 -0700251 float add[4] = {0.f, 0.f, 0.f, 0.f};
252 setAdd(add);
Tim Murray89daad62013-07-29 14:30:02 -0700253
254}
255
256void ScriptIntrinsicColorMatrix::forEach(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700257 if (!(in->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
258 !(in->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
259 !(in->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
260 !(in->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
261 !(in->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
262 !(in->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
263 !(in->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
264 !(in->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
265 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
266 return;
267 }
268
269 if (!(out->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
270 !(out->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
271 !(out->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
272 !(out->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
273 !(out->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
274 !(out->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
275 !(out->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
276 !(out->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
277 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
278 return;
279 }
280
Chris Wailes44bef6f2014-08-12 13:51:10 -0700281 Script::forEach(0, in, out, nullptr, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700282}
283
Tim Murray10913a52013-08-20 17:19:47 -0700284void ScriptIntrinsicColorMatrix::setAdd(float* add) {
285 Script::setVar(1, (void*)add, sizeof(float) * 4);
286}
Tim Murray89daad62013-07-29 14:30:02 -0700287
288void ScriptIntrinsicColorMatrix::setColorMatrix3(float* m) {
Tim Murrayaae73c92013-09-03 17:05:46 -0700289 float temp[16];
290 temp[0] = m[0];
291 temp[1] = m[1];
292 temp[2] = m[2];
293 temp[3] = 0.f;
294
295 temp[4] = m[3];
296 temp[5] = m[4];
297 temp[6] = m[5];
298 temp[7] = 0.f;
299
300 temp[8] = m[6];
301 temp[9] = m[7];
302 temp[10] = m[8];
303 temp[11] = 0.f;
304
305 temp[12] = 0.f;
306 temp[13] = 0.f;
307 temp[14] = 0.f;
308 temp[15] = 1.f;
309
310 setColorMatrix4(temp);
Tim Murray89daad62013-07-29 14:30:02 -0700311}
312
313
314void ScriptIntrinsicColorMatrix::setColorMatrix4(float* m) {
315 Script::setVar(0, (void*)m, sizeof(float) * 16);
316}
317
318
319void ScriptIntrinsicColorMatrix::setGreyscale() {
Tim Murrayaae73c92013-09-03 17:05:46 -0700320 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 -0700321 setColorMatrix3(matrix);
322}
323
324
325void ScriptIntrinsicColorMatrix::setRGBtoYUV() {
Tim Murrayaae73c92013-09-03 17:05:46 -0700326 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 -0700327 setColorMatrix3(matrix);
328}
329
330
331void ScriptIntrinsicColorMatrix::setYUVtoRGB() {
Tim Murrayaae73c92013-09-03 17:05:46 -0700332 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 -0700333 setColorMatrix3(matrix);
334}
335
Tim Murray21fa7a02013-08-15 16:25:03 -0700336
337
338sp<ScriptIntrinsicConvolve3x3> ScriptIntrinsicConvolve3x3::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700339 if (!(e->isCompatible(Element::U8(rs))) &&
340 !(e->isCompatible(Element::U8_2(rs))) &&
341 !(e->isCompatible(Element::U8_3(rs))) &&
342 !(e->isCompatible(Element::U8_4(rs))) &&
343 !(e->isCompatible(Element::F32(rs))) &&
344 !(e->isCompatible(Element::F32_2(rs))) &&
345 !(e->isCompatible(Element::F32_3(rs))) &&
346 !(e->isCompatible(Element::F32_4(rs)))) {
347 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve3x3");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700348 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -0700349 }
350
Tim Murray21fa7a02013-08-15 16:25:03 -0700351 return new ScriptIntrinsicConvolve3x3(rs, e);
352}
353
Tim Murray89daad62013-07-29 14:30:02 -0700354ScriptIntrinsicConvolve3x3::ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e)
355 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_3x3, e) {
356
357}
358
359void ScriptIntrinsicConvolve3x3::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700360 if (!(in->getType()->getElement()->isCompatible(mElement))) {
361 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
362 return;
363 }
Tim Murray89daad62013-07-29 14:30:02 -0700364 Script::setVar(1, in);
365}
366
367void ScriptIntrinsicConvolve3x3::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700368 if (!(out->getType()->getElement()->isCompatible(mElement))) {
369 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
370 return;
371 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700372 Script::forEach(0, nullptr, out, nullptr, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700373}
374
375void ScriptIntrinsicConvolve3x3::setCoefficients(float* v) {
376 Script::setVar(0, (void*)v, sizeof(float) * 9);
377}
378
Tim Murray21fa7a02013-08-15 16:25:03 -0700379sp<ScriptIntrinsicConvolve5x5> ScriptIntrinsicConvolve5x5::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700380 if (!(e->isCompatible(Element::U8(rs))) &&
381 !(e->isCompatible(Element::U8_2(rs))) &&
382 !(e->isCompatible(Element::U8_3(rs))) &&
383 !(e->isCompatible(Element::U8_4(rs))) &&
384 !(e->isCompatible(Element::F32(rs))) &&
385 !(e->isCompatible(Element::F32_2(rs))) &&
386 !(e->isCompatible(Element::F32_3(rs))) &&
387 !(e->isCompatible(Element::F32_4(rs)))) {
388 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve5x5");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700389 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -0700390 }
391
Tim Murray21fa7a02013-08-15 16:25:03 -0700392 return new ScriptIntrinsicConvolve5x5(rs, e);
393}
394
Tim Murray89daad62013-07-29 14:30:02 -0700395ScriptIntrinsicConvolve5x5::ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e)
396 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_5x5, e) {
397
398}
399
400void ScriptIntrinsicConvolve5x5::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700401 if (!(in->getType()->getElement()->isCompatible(mElement))) {
402 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 input");
403 return;
404 }
Tim Murray89daad62013-07-29 14:30:02 -0700405 Script::setVar(1, in);
406}
407
408void ScriptIntrinsicConvolve5x5::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700409 if (!(out->getType()->getElement()->isCompatible(mElement))) {
410 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 output");
411 return;
412 }
413
Chris Wailes44bef6f2014-08-12 13:51:10 -0700414 Script::forEach(0, nullptr, out, nullptr, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700415}
416
417void ScriptIntrinsicConvolve5x5::setCoefficients(float* v) {
418 Script::setVar(0, (void*)v, sizeof(float) * 25);
419}
420
Jon Parrb05c8502015-03-13 14:41:58 +0000421sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(sp<RS> rs, sp<const Element> e) {
422 return new ScriptIntrinsicHistogram(rs, e);
Tim Murray21fa7a02013-08-15 16:25:03 -0700423}
424
Tim Murrayb27b1812013-08-05 14:00:40 -0700425ScriptIntrinsicHistogram::ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e)
426 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_HISTOGRAM, e) {
Tim Murray89daad62013-07-29 14:30:02 -0700427
428}
429
Tim Murray10913a52013-08-20 17:19:47 -0700430void ScriptIntrinsicHistogram::setOutput(sp<Allocation> out) {
431 if (!(out->getType()->getElement()->isCompatible(Element::U32(mRS))) &&
432 !(out->getType()->getElement()->isCompatible(Element::U32_2(mRS))) &&
433 !(out->getType()->getElement()->isCompatible(Element::U32_3(mRS))) &&
434 !(out->getType()->getElement()->isCompatible(Element::U32_4(mRS))) &&
435 !(out->getType()->getElement()->isCompatible(Element::I32(mRS))) &&
436 !(out->getType()->getElement()->isCompatible(Element::I32_2(mRS))) &&
437 !(out->getType()->getElement()->isCompatible(Element::I32_3(mRS))) &&
438 !(out->getType()->getElement()->isCompatible(Element::I32_4(mRS)))) {
439 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Histogram output");
440 return;
441 }
442
443 if (out->getType()->getX() != 256 ||
444 out->getType()->getY() != 0 ||
445 out->getType()->hasMipmaps()) {
446 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid Allocation type for Histogram output");
447 return;
448 }
449 mOut = out;
450 Script::setVar(1, out);
Tim Murrayb27b1812013-08-05 14:00:40 -0700451}
452
453void ScriptIntrinsicHistogram::setDotCoefficients(float r, float g, float b, float a) {
454 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
455 return;
456 }
457 if ((r + g + b + a) > 1.f) {
458 return;
459 }
460
461 FieldPacker fp(16);
462 fp.add(r);
463 fp.add(g);
464 fp.add(b);
465 fp.add(a);
466 Script::setVar(0, fp.getData(), fp.getLength());
467
468}
469
470void ScriptIntrinsicHistogram::forEach(sp<Allocation> ain) {
Tim Murray10913a52013-08-20 17:19:47 -0700471 if (ain->getType()->getElement()->getVectorSize() <
472 mOut->getType()->getElement()->getVectorSize()) {
473 mRS->throwError(RS_ERROR_INVALID_PARAMETER,
474 "Input vector size must be >= output vector size");
475 return;
476 }
477
Jon Parrb05c8502015-03-13 14:41:58 +0000478 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
Tim Murray10913a52013-08-20 17:19:47 -0700479 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
480 mRS->throwError(RS_ERROR_INVALID_ELEMENT,
481 "Input allocation to Histogram must be U8 or U8_4");
482 return;
483 }
484
Chris Wailes44bef6f2014-08-12 13:51:10 -0700485 Script::forEach(0, ain, nullptr, nullptr, 0);
Tim Murrayb27b1812013-08-05 14:00:40 -0700486}
487
488
489void ScriptIntrinsicHistogram::forEach_dot(sp<Allocation> ain) {
Tim Murray10913a52013-08-20 17:19:47 -0700490 if (mOut->getType()->getElement()->getVectorSize() != 1) {
491 mRS->throwError(RS_ERROR_INVALID_PARAMETER,
492 "Output Histogram allocation must have vector size of 1 " \
493 "when used with forEach_dot");
494 return;
495 }
Jon Parrb05c8502015-03-13 14:41:58 +0000496 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
Tim Murray10913a52013-08-20 17:19:47 -0700497 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
498 mRS->throwError(RS_ERROR_INVALID_ELEMENT,
499 "Input allocation to Histogram must be U8 or U8_4");
500 return;
501 }
502
Chris Wailes44bef6f2014-08-12 13:51:10 -0700503 Script::forEach(1, ain, nullptr, nullptr, 0);
Tim Murrayb27b1812013-08-05 14:00:40 -0700504}
505
Tim Murray21fa7a02013-08-15 16:25:03 -0700506sp<ScriptIntrinsicLUT> ScriptIntrinsicLUT::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700507 if (!(e->isCompatible(Element::U8_4(rs)))) {
508 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700509 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -0700510 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700511 return new ScriptIntrinsicLUT(rs, e);
512}
513
Tim Murrayb27b1812013-08-05 14:00:40 -0700514ScriptIntrinsicLUT::ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e)
515 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_LUT, e), mDirty(true) {
Tim Murray2acce992013-08-28 14:23:31 -0700516 LUT = Allocation::createSized(rs, Element::U8(rs), 1024);
Tim Murrayb27b1812013-08-05 14:00:40 -0700517 for (int i = 0; i < 256; i++) {
518 mCache[i] = i;
519 mCache[i+256] = i;
520 mCache[i+512] = i;
521 mCache[i+768] = i;
522 }
Tim Murray2acce992013-08-28 14:23:31 -0700523 setVar(0, LUT);
Tim Murrayb27b1812013-08-05 14:00:40 -0700524}
525
Tim Murray89daad62013-07-29 14:30:02 -0700526void ScriptIntrinsicLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700527 if (mDirty) {
528 LUT->copy1DFrom((void*)mCache);
529 mDirty = false;
530 }
Tim Murray10913a52013-08-20 17:19:47 -0700531 if (!(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) ||
532 !(aout->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
533 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
534 return;
535 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700536 Script::forEach(0, ain, aout, nullptr, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700537
538}
539
Tim Murray2acce992013-08-28 14:23:31 -0700540void ScriptIntrinsicLUT::setTable(unsigned int offset, unsigned char base, unsigned int length, unsigned char* lutValues) {
541 if ((base + length) > 256 || length == 0) {
542 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
Tim Murrayb27b1812013-08-05 14:00:40 -0700543 return;
544 }
545 mDirty = true;
Tim Murray2acce992013-08-28 14:23:31 -0700546 for (unsigned int i = 0; i < length; i++) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700547 mCache[offset + base + i] = lutValues[i];
548 }
549}
Tim Murray89daad62013-07-29 14:30:02 -0700550
Tim Murray2acce992013-08-28 14:23:31 -0700551void ScriptIntrinsicLUT::setRed(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700552 setTable(0, base, length, lutValues);
553}
Tim Murray89daad62013-07-29 14:30:02 -0700554
Tim Murray2acce992013-08-28 14:23:31 -0700555void ScriptIntrinsicLUT::setGreen(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700556 setTable(256, base, length, lutValues);
557}
558
Tim Murray2acce992013-08-28 14:23:31 -0700559void ScriptIntrinsicLUT::setBlue(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700560 setTable(512, base, length, lutValues);
561}
562
Tim Murray2acce992013-08-28 14:23:31 -0700563void ScriptIntrinsicLUT::setAlpha(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700564 setTable(768, base, length, lutValues);
565}
566
567ScriptIntrinsicLUT::~ScriptIntrinsicLUT() {
568
569}
570
Miao Wange5428e62015-03-10 15:29:40 -0700571sp<ScriptIntrinsicResize> ScriptIntrinsicResize::create(sp<RS> rs) {
572 return new ScriptIntrinsicResize(rs, nullptr);
573}
574
575ScriptIntrinsicResize::ScriptIntrinsicResize(sp<RS> rs, sp<const Element> e)
576 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_RESIZE, e) {
577
578}
579void ScriptIntrinsicResize::forEach_bicubic(sp<Allocation> aout) {
580 if (aout == mInput) {
581 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Resize Input and Ouput cannot be the same");
582 }
583
584 if (!(mInput->getType()->getElement()->isCompatible(aout->getType()->getElement()))) {
585 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Resize forEach element mismatch");
586 return;
587 }
588 Script::forEach(0, nullptr, aout, nullptr, 0);
589}
590void ScriptIntrinsicResize::setInput(sp<Allocation> ain) {
591 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
592 !(ain->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
593 !(ain->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
594 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
595 !(ain->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
596 !(ain->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
597 !(ain->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
598 !(ain->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
599 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Resize Input");
600 return;
601 }
602
603 mInput = ain;
604 Script::setVar(0, ain);
605}
606
607
Tim Murray21fa7a02013-08-15 16:25:03 -0700608sp<ScriptIntrinsicYuvToRGB> ScriptIntrinsicYuvToRGB::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700609 if (!(e->isCompatible(Element::U8_4(rs)))) {
610 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for YuvToRGB");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700611 return nullptr;
Tim Murray10913a52013-08-20 17:19:47 -0700612 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700613 return new ScriptIntrinsicYuvToRGB(rs, e);
614}
615
Tim Murrayb27b1812013-08-05 14:00:40 -0700616ScriptIntrinsicYuvToRGB::ScriptIntrinsicYuvToRGB(sp<RS> rs, sp<const Element> e)
617 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB, e) {
618
619}
620
621void ScriptIntrinsicYuvToRGB::setInput(sp<Allocation> in) {
Tim Murrayeb4426d2013-08-27 15:30:16 -0700622 if (!(in->getType()->getElement()->isCompatible(Element::YUV(mRS)))) {
Tim Murray10913a52013-08-20 17:19:47 -0700623 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for input in YuvToRGB");
624 return;
625 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700626 Script::setVar(0, in);
627}
628
629void ScriptIntrinsicYuvToRGB::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700630 if (!(out->getType()->getElement()->isCompatible(mElement))) {
631 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for output in YuvToRGB");
632 return;
633 }
634
Chris Wailes44bef6f2014-08-12 13:51:10 -0700635 Script::forEach(0, nullptr, out, nullptr, 0);
Miao Wang49b12262015-09-04 11:48:16 -0700636}