blob: 98490c5430097f3453c9b4157fb8f0bee9cda85e [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)
Tim Murray7f0d5682012-11-08 16:35:24 -080026 : Script(NULL, rs) {
Tim Murrayfa77db82013-08-29 11:07:17 -070027 mID = createDispatch(rs, RS::dispatch->ScriptIntrinsicCreate(rs->getContext(), id, e->getID()));
Tim Murray10913a52013-08-20 17:19:47 -070028 mElement = e;
Tim Murray7f0d5682012-11-08 16:35:24 -080029}
30
Tim Murrayb27b1812013-08-05 14:00:40 -070031ScriptIntrinsic::~ScriptIntrinsic() {
32
33}
34
Tim Murray21fa7a02013-08-15 16:25:03 -070035sp<ScriptIntrinsic3DLUT> ScriptIntrinsic3DLUT::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -070036 if (e->isCompatible(Element::U8_4(rs)) == false) {
37 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
38 return NULL;
39 }
Tim Murray21fa7a02013-08-15 16:25:03 -070040 return new ScriptIntrinsic3DLUT(rs, e);
41}
42
Tim Murray89daad62013-07-29 14:30:02 -070043ScriptIntrinsic3DLUT::ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e)
44 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_3DLUT, e) {
45
46}
47void ScriptIntrinsic3DLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
Tim Murray10913a52013-08-20 17:19:47 -070048 if (ain->getType()->getElement()->isCompatible(mElement) == false ||
49 aout->getType()->getElement()->isCompatible(mElement) == false) {
50 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "3DLUT forEach element mismatch");
51 return;
52 }
Tim Murray89daad62013-07-29 14:30:02 -070053 Script::forEach(0, ain, aout, NULL, 0);
54}
55void ScriptIntrinsic3DLUT::setLUT(sp<Allocation> lut) {
Tim Murray10913a52013-08-20 17:19:47 -070056 sp<const Type> t = lut->getType();
57 if (!t->getElement()->isCompatible(mElement)) {
58 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "setLUT element does not match");
59 return;
60 }
61 if (t->getZ() == 0) {
62 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "setLUT Allocation must be 3D");
63 return;
64 }
65
Tim Murray89daad62013-07-29 14:30:02 -070066 Script::setVar(0, lut);
67}
68
Tim Murray21fa7a02013-08-15 16:25:03 -070069sp<ScriptIntrinsicBlend> ScriptIntrinsicBlend::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -070070 if (e->isCompatible(Element::U8_4(rs)) == false) {
71 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
72 return NULL;
73 }
Tim Murray21fa7a02013-08-15 16:25:03 -070074 return new ScriptIntrinsicBlend(rs, e);
75}
76
Tim Murray3cd44af2012-11-14 11:25:27 -080077ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e)
Tim Murray7f0d5682012-11-08 16:35:24 -080078 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) {
Tim Murray7f0d5682012-11-08 16:35:24 -080079}
80
81void ScriptIntrinsicBlend::blendClear(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -070082 if (in->getType()->getElement()->isCompatible(mElement) == false ||
83 out->getType()->getElement()->isCompatible(mElement) == false) {
84 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
85 }
Tim Murray7f0d5682012-11-08 16:35:24 -080086 Script::forEach(0, in, out, NULL, 0);
87}
88
89void ScriptIntrinsicBlend::blendSrc(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -070090 if (in->getType()->getElement()->isCompatible(mElement) == false ||
91 out->getType()->getElement()->isCompatible(mElement) == false) {
92 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
93 }
Tim Murray7f0d5682012-11-08 16:35:24 -080094 Script::forEach(1, in, out, NULL, 0);
95}
96
97void ScriptIntrinsicBlend::blendDst(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -070098 if (in->getType()->getElement()->isCompatible(mElement) == false ||
99 out->getType()->getElement()->isCompatible(mElement) == false) {
100 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
101 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800102 Script::forEach(2, in, out, NULL, 0);
103}
104
105void ScriptIntrinsicBlend::blendSrcOver(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700106 if (in->getType()->getElement()->isCompatible(mElement) == false ||
107 out->getType()->getElement()->isCompatible(mElement) == false) {
108 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
109 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800110 Script::forEach(3, in, out, NULL, 0);
111}
112
113void ScriptIntrinsicBlend::blendDstOver(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700114 if (in->getType()->getElement()->isCompatible(mElement) == false ||
115 out->getType()->getElement()->isCompatible(mElement) == false) {
116 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
117 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800118 Script::forEach(4, in, out, NULL, 0);
119}
120
121void ScriptIntrinsicBlend::blendSrcIn(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700122 if (in->getType()->getElement()->isCompatible(mElement) == false ||
123 out->getType()->getElement()->isCompatible(mElement) == false) {
124 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
125 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800126 Script::forEach(5, in, out, NULL, 0);
127}
128
129void ScriptIntrinsicBlend::blendDstIn(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700130 if (in->getType()->getElement()->isCompatible(mElement) == false ||
131 out->getType()->getElement()->isCompatible(mElement) == false) {
132 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
133 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800134 Script::forEach(6, in, out, NULL, 0);
135}
136
137void ScriptIntrinsicBlend::blendSrcOut(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700138 if (in->getType()->getElement()->isCompatible(mElement) == false ||
139 out->getType()->getElement()->isCompatible(mElement) == false) {
140 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
141 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800142 Script::forEach(7, in, out, NULL, 0);
143}
144
145void ScriptIntrinsicBlend::blendDstOut(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700146 if (in->getType()->getElement()->isCompatible(mElement) == false ||
147 out->getType()->getElement()->isCompatible(mElement) == false) {
148 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
149 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800150 Script::forEach(8, in, out, NULL, 0);
151}
152
153void ScriptIntrinsicBlend::blendSrcAtop(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700154 if (in->getType()->getElement()->isCompatible(mElement) == false ||
155 out->getType()->getElement()->isCompatible(mElement) == false) {
156 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
157 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800158 Script::forEach(9, in, out, NULL, 0);
159}
160
161void ScriptIntrinsicBlend::blendDstAtop(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700162 if (in->getType()->getElement()->isCompatible(mElement) == false ||
163 out->getType()->getElement()->isCompatible(mElement) == false) {
164 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
165 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800166 Script::forEach(10, in, out, NULL, 0);
167}
168
169void ScriptIntrinsicBlend::blendXor(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700170 if (in->getType()->getElement()->isCompatible(mElement) == false ||
171 out->getType()->getElement()->isCompatible(mElement) == false) {
172 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
173 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800174 Script::forEach(11, in, out, NULL, 0);
175}
176
177// Numbering jumps here
178void ScriptIntrinsicBlend::blendMultiply(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 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800183 Script::forEach(14, in, out, NULL, 0);
184}
185
186// Numbering jumps here
187void ScriptIntrinsicBlend::blendAdd(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700188 if (in->getType()->getElement()->isCompatible(mElement) == false ||
189 out->getType()->getElement()->isCompatible(mElement) == false) {
190 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
191 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800192 Script::forEach(34, in, out, NULL, 0);
193}
194
195void ScriptIntrinsicBlend::blendSubtract(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700196 if (in->getType()->getElement()->isCompatible(mElement) == false ||
197 out->getType()->getElement()->isCompatible(mElement) == false) {
198 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
199 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800200 Script::forEach(35, in, out, NULL, 0);
201}
202
Tim Murray89daad62013-07-29 14:30:02 -0700203
204
205
Tim Murray21fa7a02013-08-15 16:25:03 -0700206sp<ScriptIntrinsicBlur> ScriptIntrinsicBlur::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700207 if ((e->isCompatible(Element::U8_4(rs)) == false) &&
208 (e->isCompatible(Element::U8(rs)) == false)) {
209 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur");
210 return NULL;
211 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700212 return new ScriptIntrinsicBlur(rs, e);
213}
214
Tim Murray3cd44af2012-11-14 11:25:27 -0800215ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e)
Tim Murray8f1e60c2012-11-13 12:25:11 -0800216 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) {
Tim Murray7f0d5682012-11-08 16:35:24 -0800217
Tim Murray8f1e60c2012-11-13 12:25:11 -0800218}
Tim Murray7f0d5682012-11-08 16:35:24 -0800219
Tim Murray21fa7a02013-08-15 16:25:03 -0700220void ScriptIntrinsicBlur::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700221 if (in->getType()->getElement()->isCompatible(mElement) == false) {
222 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur input");
223 return;
224 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800225 Script::setVar(1, in);
Tim Murray21fa7a02013-08-15 16:25:03 -0700226}
227
228void ScriptIntrinsicBlur::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700229 if (out->getType()->getElement()->isCompatible(mElement) == false) {
230 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur output");
231 return;
232 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800233 Script::forEach(0, NULL, out, NULL, 0);
234}
Tim Murray7f0d5682012-11-08 16:35:24 -0800235
Tim Murray8f1e60c2012-11-13 12:25:11 -0800236void ScriptIntrinsicBlur::setRadius(float radius) {
Tim Murray10913a52013-08-20 17:19:47 -0700237 if (radius > 0.f && radius <= 25.f) {
238 Script::setVar(0, &radius, sizeof(float));
239 } else {
240 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Blur radius out of 0-25 pixel bound");
241 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800242}
Tim Murray89daad62013-07-29 14:30:02 -0700243
244
245
Tim Murray21fa7a02013-08-15 16:25:03 -0700246sp<ScriptIntrinsicColorMatrix> ScriptIntrinsicColorMatrix::create(sp<RS> rs, sp<const Element> e) {
247 return new ScriptIntrinsicColorMatrix(rs, e);
248}
249
Tim Murray89daad62013-07-29 14:30:02 -0700250ScriptIntrinsicColorMatrix::ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e)
251 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_COLOR_MATRIX, e) {
252
253}
254
255void ScriptIntrinsicColorMatrix::forEach(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700256 if (!(in->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
257 !(in->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
258 !(in->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
259 !(in->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
260 !(in->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
261 !(in->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
262 !(in->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
263 !(in->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
264 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
265 return;
266 }
267
268 if (!(out->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
269 !(out->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
270 !(out->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
271 !(out->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
272 !(out->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
273 !(out->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
274 !(out->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
275 !(out->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
276 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
277 return;
278 }
279
Tim Murray89daad62013-07-29 14:30:02 -0700280 Script::forEach(0, in, out, NULL, 0);
281}
282
Tim Murray10913a52013-08-20 17:19:47 -0700283void ScriptIntrinsicColorMatrix::setAdd(float* add) {
284 Script::setVar(1, (void*)add, sizeof(float) * 4);
285}
Tim Murray89daad62013-07-29 14:30:02 -0700286
287void ScriptIntrinsicColorMatrix::setColorMatrix3(float* m) {
288 Script::setVar(0, (void*)m, sizeof(float) * 9);
289}
290
291
292void ScriptIntrinsicColorMatrix::setColorMatrix4(float* m) {
293 Script::setVar(0, (void*)m, sizeof(float) * 16);
294}
295
296
297void ScriptIntrinsicColorMatrix::setGreyscale() {
298 float matrix[] = {0.299f, 0.587f, 0.114f, 0.299f, 0.587f, 0.114f, 0.299f, 0.587f, 0.114f};
299 setColorMatrix3(matrix);
300}
301
302
303void ScriptIntrinsicColorMatrix::setRGBtoYUV() {
304 float matrix[] = {0.299f,0.587f,0.114f,-0.14713f,-0.28886f,0.436f,0.615f,-0.51499f,-0.10001f};
305 setColorMatrix3(matrix);
306}
307
308
309void ScriptIntrinsicColorMatrix::setYUVtoRGB() {
310 float matrix[] = {1.f,0.f,1.13983f,1.f,-0.39465f,-0.5806f,1.f,2.03211f,0.f};
311 setColorMatrix3(matrix);
312}
313
Tim Murray21fa7a02013-08-15 16:25:03 -0700314
315
316sp<ScriptIntrinsicConvolve3x3> ScriptIntrinsicConvolve3x3::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700317 if (!(e->isCompatible(Element::U8(rs))) &&
318 !(e->isCompatible(Element::U8_2(rs))) &&
319 !(e->isCompatible(Element::U8_3(rs))) &&
320 !(e->isCompatible(Element::U8_4(rs))) &&
321 !(e->isCompatible(Element::F32(rs))) &&
322 !(e->isCompatible(Element::F32_2(rs))) &&
323 !(e->isCompatible(Element::F32_3(rs))) &&
324 !(e->isCompatible(Element::F32_4(rs)))) {
325 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve3x3");
326 return NULL;
327 }
328
Tim Murray21fa7a02013-08-15 16:25:03 -0700329 return new ScriptIntrinsicConvolve3x3(rs, e);
330}
331
Tim Murray89daad62013-07-29 14:30:02 -0700332ScriptIntrinsicConvolve3x3::ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e)
333 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_3x3, e) {
334
335}
336
337void ScriptIntrinsicConvolve3x3::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700338 if (!(in->getType()->getElement()->isCompatible(mElement))) {
339 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
340 return;
341 }
Tim Murray89daad62013-07-29 14:30:02 -0700342 Script::setVar(1, in);
343}
344
345void ScriptIntrinsicConvolve3x3::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700346 if (!(out->getType()->getElement()->isCompatible(mElement))) {
347 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
348 return;
349 }
Tim Murray89daad62013-07-29 14:30:02 -0700350 Script::forEach(0, NULL, out, NULL, 0);
351}
352
353void ScriptIntrinsicConvolve3x3::setCoefficients(float* v) {
354 Script::setVar(0, (void*)v, sizeof(float) * 9);
355}
356
Tim Murray21fa7a02013-08-15 16:25:03 -0700357sp<ScriptIntrinsicConvolve5x5> ScriptIntrinsicConvolve5x5::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700358 if (!(e->isCompatible(Element::U8(rs))) &&
359 !(e->isCompatible(Element::U8_2(rs))) &&
360 !(e->isCompatible(Element::U8_3(rs))) &&
361 !(e->isCompatible(Element::U8_4(rs))) &&
362 !(e->isCompatible(Element::F32(rs))) &&
363 !(e->isCompatible(Element::F32_2(rs))) &&
364 !(e->isCompatible(Element::F32_3(rs))) &&
365 !(e->isCompatible(Element::F32_4(rs)))) {
366 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve5x5");
367 return NULL;
368 }
369
Tim Murray21fa7a02013-08-15 16:25:03 -0700370 return new ScriptIntrinsicConvolve5x5(rs, e);
371}
372
Tim Murray89daad62013-07-29 14:30:02 -0700373ScriptIntrinsicConvolve5x5::ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e)
374 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_5x5, e) {
375
376}
377
378void ScriptIntrinsicConvolve5x5::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700379 if (!(in->getType()->getElement()->isCompatible(mElement))) {
380 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 input");
381 return;
382 }
Tim Murray89daad62013-07-29 14:30:02 -0700383 Script::setVar(1, in);
384}
385
386void ScriptIntrinsicConvolve5x5::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700387 if (!(out->getType()->getElement()->isCompatible(mElement))) {
388 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 output");
389 return;
390 }
391
Tim Murray89daad62013-07-29 14:30:02 -0700392 Script::forEach(0, NULL, out, NULL, 0);
393}
394
395void ScriptIntrinsicConvolve5x5::setCoefficients(float* v) {
396 Script::setVar(0, (void*)v, sizeof(float) * 25);
397}
398
Tim Murray10913a52013-08-20 17:19:47 -0700399sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(sp<RS> rs) {
400 return new ScriptIntrinsicHistogram(rs, NULL);
Tim Murray21fa7a02013-08-15 16:25:03 -0700401}
402
Tim Murrayb27b1812013-08-05 14:00:40 -0700403ScriptIntrinsicHistogram::ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e)
404 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_HISTOGRAM, e) {
Tim Murray89daad62013-07-29 14:30:02 -0700405
406}
407
Tim Murray10913a52013-08-20 17:19:47 -0700408void ScriptIntrinsicHistogram::setOutput(sp<Allocation> out) {
409 if (!(out->getType()->getElement()->isCompatible(Element::U32(mRS))) &&
410 !(out->getType()->getElement()->isCompatible(Element::U32_2(mRS))) &&
411 !(out->getType()->getElement()->isCompatible(Element::U32_3(mRS))) &&
412 !(out->getType()->getElement()->isCompatible(Element::U32_4(mRS))) &&
413 !(out->getType()->getElement()->isCompatible(Element::I32(mRS))) &&
414 !(out->getType()->getElement()->isCompatible(Element::I32_2(mRS))) &&
415 !(out->getType()->getElement()->isCompatible(Element::I32_3(mRS))) &&
416 !(out->getType()->getElement()->isCompatible(Element::I32_4(mRS)))) {
417 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Histogram output");
418 return;
419 }
420
421 if (out->getType()->getX() != 256 ||
422 out->getType()->getY() != 0 ||
423 out->getType()->hasMipmaps()) {
424 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid Allocation type for Histogram output");
425 return;
426 }
427 mOut = out;
428 Script::setVar(1, out);
Tim Murrayb27b1812013-08-05 14:00:40 -0700429}
430
431void ScriptIntrinsicHistogram::setDotCoefficients(float r, float g, float b, float a) {
432 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
433 return;
434 }
435 if ((r + g + b + a) > 1.f) {
436 return;
437 }
438
439 FieldPacker fp(16);
440 fp.add(r);
441 fp.add(g);
442 fp.add(b);
443 fp.add(a);
444 Script::setVar(0, fp.getData(), fp.getLength());
445
446}
447
448void ScriptIntrinsicHistogram::forEach(sp<Allocation> ain) {
Tim Murray10913a52013-08-20 17:19:47 -0700449 if (ain->getType()->getElement()->getVectorSize() <
450 mOut->getType()->getElement()->getVectorSize()) {
451 mRS->throwError(RS_ERROR_INVALID_PARAMETER,
452 "Input vector size must be >= output vector size");
453 return;
454 }
455
456 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) ||
457 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
458 mRS->throwError(RS_ERROR_INVALID_ELEMENT,
459 "Input allocation to Histogram must be U8 or U8_4");
460 return;
461 }
462
Tim Murrayb27b1812013-08-05 14:00:40 -0700463 Script::forEach(0, ain, NULL, NULL, 0);
464}
465
466
467void ScriptIntrinsicHistogram::forEach_dot(sp<Allocation> ain) {
Tim Murray10913a52013-08-20 17:19:47 -0700468 if (mOut->getType()->getElement()->getVectorSize() != 1) {
469 mRS->throwError(RS_ERROR_INVALID_PARAMETER,
470 "Output Histogram allocation must have vector size of 1 " \
471 "when used with forEach_dot");
472 return;
473 }
474 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) ||
475 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
476 mRS->throwError(RS_ERROR_INVALID_ELEMENT,
477 "Input allocation to Histogram must be U8 or U8_4");
478 return;
479 }
480
Tim Murrayb27b1812013-08-05 14:00:40 -0700481 Script::forEach(1, ain, NULL, NULL, 0);
482}
483
Tim Murray21fa7a02013-08-15 16:25:03 -0700484sp<ScriptIntrinsicLUT> ScriptIntrinsicLUT::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700485 if (!(e->isCompatible(Element::U8_4(rs)))) {
486 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
487 return NULL;
488 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700489 return new ScriptIntrinsicLUT(rs, e);
490}
491
Tim Murrayb27b1812013-08-05 14:00:40 -0700492ScriptIntrinsicLUT::ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e)
493 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_LUT, e), mDirty(true) {
Tim Murray2acce992013-08-28 14:23:31 -0700494 LUT = Allocation::createSized(rs, Element::U8(rs), 1024);
Tim Murrayb27b1812013-08-05 14:00:40 -0700495 for (int i = 0; i < 256; i++) {
496 mCache[i] = i;
497 mCache[i+256] = i;
498 mCache[i+512] = i;
499 mCache[i+768] = i;
500 }
Tim Murray2acce992013-08-28 14:23:31 -0700501 setVar(0, LUT);
Tim Murrayb27b1812013-08-05 14:00:40 -0700502}
503
Tim Murray89daad62013-07-29 14:30:02 -0700504void ScriptIntrinsicLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700505 if (mDirty) {
506 LUT->copy1DFrom((void*)mCache);
507 mDirty = false;
508 }
Tim Murray10913a52013-08-20 17:19:47 -0700509 if (!(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) ||
510 !(aout->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
511 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
512 return;
513 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700514 Script::forEach(0, ain, aout, NULL, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700515
516}
517
Tim Murray2acce992013-08-28 14:23:31 -0700518void ScriptIntrinsicLUT::setTable(unsigned int offset, unsigned char base, unsigned int length, unsigned char* lutValues) {
519 if ((base + length) > 256 || length == 0) {
520 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
Tim Murrayb27b1812013-08-05 14:00:40 -0700521 return;
522 }
523 mDirty = true;
Tim Murray2acce992013-08-28 14:23:31 -0700524 for (unsigned int i = 0; i < length; i++) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700525 mCache[offset + base + i] = lutValues[i];
526 }
527}
Tim Murray89daad62013-07-29 14:30:02 -0700528
Tim Murray2acce992013-08-28 14:23:31 -0700529void ScriptIntrinsicLUT::setRed(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700530 setTable(0, base, length, lutValues);
531}
Tim Murray89daad62013-07-29 14:30:02 -0700532
Tim Murray2acce992013-08-28 14:23:31 -0700533void ScriptIntrinsicLUT::setGreen(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700534 setTable(256, base, length, lutValues);
535}
536
Tim Murray2acce992013-08-28 14:23:31 -0700537void ScriptIntrinsicLUT::setBlue(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700538 setTable(512, base, length, lutValues);
539}
540
Tim Murray2acce992013-08-28 14:23:31 -0700541void ScriptIntrinsicLUT::setAlpha(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700542 setTable(768, base, length, lutValues);
543}
544
545ScriptIntrinsicLUT::~ScriptIntrinsicLUT() {
546
547}
548
Tim Murray21fa7a02013-08-15 16:25:03 -0700549sp<ScriptIntrinsicYuvToRGB> ScriptIntrinsicYuvToRGB::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700550 if (!(e->isCompatible(Element::U8_4(rs)))) {
551 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for YuvToRGB");
552 return NULL;
553 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700554 return new ScriptIntrinsicYuvToRGB(rs, e);
555}
556
Tim Murrayb27b1812013-08-05 14:00:40 -0700557ScriptIntrinsicYuvToRGB::ScriptIntrinsicYuvToRGB(sp<RS> rs, sp<const Element> e)
558 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB, e) {
559
560}
561
562void ScriptIntrinsicYuvToRGB::setInput(sp<Allocation> in) {
Tim Murrayeb4426d2013-08-27 15:30:16 -0700563 if (!(in->getType()->getElement()->isCompatible(Element::YUV(mRS)))) {
Tim Murray10913a52013-08-20 17:19:47 -0700564 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for input in YuvToRGB");
565 return;
566 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700567 Script::setVar(0, in);
568}
569
570void ScriptIntrinsicYuvToRGB::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700571 if (!(out->getType()->getElement()->isCompatible(mElement))) {
572 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for output in YuvToRGB");
573 return;
574 }
575
Tim Murrayb27b1812013-08-05 14:00:40 -0700576 Script::forEach(0, NULL, out, NULL, 0);
577}