blob: f9a1d979265dec27311f14c896f102d9bfd308d5 [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
Matthieu Delahaye60498fe2014-02-18 13:21:06 -060069sp<ScriptIntrinsicVP9InterPred> ScriptIntrinsicVP9InterPred::create(sp<RS> rs, sp<const Element> e) {
70 if (e->isCompatible(Element::U8(rs)) == false) {
71 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
72 return NULL;
73 }
74 return new ScriptIntrinsicVP9InterPred(rs, e);
75}
76
77ScriptIntrinsicVP9InterPred::ScriptIntrinsicVP9InterPred(sp<RS> rs, sp<const Element> e)
78 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_INTER_PRED, e) {
79}
80
81void ScriptIntrinsicVP9InterPred::forEach(sp<Allocation> asize) {
82 if (asize->getType()->getElement()->isCompatible(mElement) == false) {
83 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "InterPred forEach element mismatch");
84 return;
85 }
86 Script::forEach(0, asize, NULL, NULL, 0);
87}
88
89void ScriptIntrinsicVP9InterPred::setRef(sp<Allocation> ref) {
90 sp<const Type> t = ref->getType();
91 if (!t->getElement()->isCompatible(mElement)) {
92 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "setRef element does not match");
93 return;
94 }
95 Script::setVar(0, ref);
96}
97
98void ScriptIntrinsicVP9InterPred::setParam(sp<Allocation> param) {
99 sp<const Type> t = param->getType();
100 if (!t->getElement()->isCompatible(mElement)) {
101 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "setFriParam element does not match");
102 return;
103 }
104 Script::setVar(1, param);
105}
106
107void ScriptIntrinsicVP9InterPred::setParamCount(int fri, int sec, int offset) {
108 FieldPacker fp(12);
109 fp.add(fri);
110 fp.add(sec);
111 fp.add(offset);
112 Script::setVar(2, fp.getData(), fp.getLength());
113}
114
Tim Murray21fa7a02013-08-15 16:25:03 -0700115sp<ScriptIntrinsicBlend> ScriptIntrinsicBlend::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700116 if (e->isCompatible(Element::U8_4(rs)) == false) {
117 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
118 return NULL;
119 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700120 return new ScriptIntrinsicBlend(rs, e);
121}
122
Tim Murray3cd44af2012-11-14 11:25:27 -0800123ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e)
Tim Murray7f0d5682012-11-08 16:35:24 -0800124 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) {
Tim Murray7f0d5682012-11-08 16:35:24 -0800125}
126
Tim Murray75e877d2013-09-11 14:45:20 -0700127void ScriptIntrinsicBlend::forEachClear(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700128 if (in->getType()->getElement()->isCompatible(mElement) == false ||
129 out->getType()->getElement()->isCompatible(mElement) == false) {
130 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
131 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800132 Script::forEach(0, in, out, NULL, 0);
133}
134
Tim Murray75e877d2013-09-11 14:45:20 -0700135void ScriptIntrinsicBlend::forEachSrc(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700136 if (in->getType()->getElement()->isCompatible(mElement) == false ||
137 out->getType()->getElement()->isCompatible(mElement) == false) {
138 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
139 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800140 Script::forEach(1, in, out, NULL, 0);
141}
142
Tim Murray75e877d2013-09-11 14:45:20 -0700143void ScriptIntrinsicBlend::forEachDst(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700144 if (in->getType()->getElement()->isCompatible(mElement) == false ||
145 out->getType()->getElement()->isCompatible(mElement) == false) {
146 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
147 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800148 Script::forEach(2, in, out, NULL, 0);
149}
150
Tim Murray75e877d2013-09-11 14:45:20 -0700151void ScriptIntrinsicBlend::forEachSrcOver(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700152 if (in->getType()->getElement()->isCompatible(mElement) == false ||
153 out->getType()->getElement()->isCompatible(mElement) == false) {
154 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
155 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800156 Script::forEach(3, in, out, NULL, 0);
157}
158
Tim Murray75e877d2013-09-11 14:45:20 -0700159void ScriptIntrinsicBlend::forEachDstOver(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700160 if (in->getType()->getElement()->isCompatible(mElement) == false ||
161 out->getType()->getElement()->isCompatible(mElement) == false) {
162 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
163 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800164 Script::forEach(4, in, out, NULL, 0);
165}
166
Tim Murray75e877d2013-09-11 14:45:20 -0700167void ScriptIntrinsicBlend::forEachSrcIn(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700168 if (in->getType()->getElement()->isCompatible(mElement) == false ||
169 out->getType()->getElement()->isCompatible(mElement) == false) {
170 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
171 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800172 Script::forEach(5, in, out, NULL, 0);
173}
174
Tim Murray75e877d2013-09-11 14:45:20 -0700175void ScriptIntrinsicBlend::forEachDstIn(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700176 if (in->getType()->getElement()->isCompatible(mElement) == false ||
177 out->getType()->getElement()->isCompatible(mElement) == false) {
178 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
179 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800180 Script::forEach(6, in, out, NULL, 0);
181}
182
Tim Murray75e877d2013-09-11 14:45:20 -0700183void ScriptIntrinsicBlend::forEachSrcOut(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700184 if (in->getType()->getElement()->isCompatible(mElement) == false ||
185 out->getType()->getElement()->isCompatible(mElement) == false) {
186 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
187 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800188 Script::forEach(7, in, out, NULL, 0);
189}
190
Tim Murray75e877d2013-09-11 14:45:20 -0700191void ScriptIntrinsicBlend::forEachDstOut(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700192 if (in->getType()->getElement()->isCompatible(mElement) == false ||
193 out->getType()->getElement()->isCompatible(mElement) == false) {
194 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
195 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800196 Script::forEach(8, in, out, NULL, 0);
197}
198
Tim Murray75e877d2013-09-11 14:45:20 -0700199void ScriptIntrinsicBlend::forEachSrcAtop(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700200 if (in->getType()->getElement()->isCompatible(mElement) == false ||
201 out->getType()->getElement()->isCompatible(mElement) == false) {
202 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
203 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800204 Script::forEach(9, in, out, NULL, 0);
205}
206
Tim Murray75e877d2013-09-11 14:45:20 -0700207void ScriptIntrinsicBlend::forEachDstAtop(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700208 if (in->getType()->getElement()->isCompatible(mElement) == false ||
209 out->getType()->getElement()->isCompatible(mElement) == false) {
210 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
211 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800212 Script::forEach(10, in, out, NULL, 0);
213}
214
Tim Murray75e877d2013-09-11 14:45:20 -0700215void ScriptIntrinsicBlend::forEachXor(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700216 if (in->getType()->getElement()->isCompatible(mElement) == false ||
217 out->getType()->getElement()->isCompatible(mElement) == false) {
218 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
219 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800220 Script::forEach(11, in, out, NULL, 0);
221}
222
223// Numbering jumps here
Tim Murray75e877d2013-09-11 14:45:20 -0700224void ScriptIntrinsicBlend::forEachMultiply(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700225 if (in->getType()->getElement()->isCompatible(mElement) == false ||
226 out->getType()->getElement()->isCompatible(mElement) == false) {
227 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
228 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800229 Script::forEach(14, in, out, NULL, 0);
230}
231
232// Numbering jumps here
Tim Murray75e877d2013-09-11 14:45:20 -0700233void ScriptIntrinsicBlend::forEachAdd(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700234 if (in->getType()->getElement()->isCompatible(mElement) == false ||
235 out->getType()->getElement()->isCompatible(mElement) == false) {
236 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
237 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800238 Script::forEach(34, in, out, NULL, 0);
239}
240
Tim Murray75e877d2013-09-11 14:45:20 -0700241void ScriptIntrinsicBlend::forEachSubtract(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700242 if (in->getType()->getElement()->isCompatible(mElement) == false ||
243 out->getType()->getElement()->isCompatible(mElement) == false) {
244 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
245 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800246 Script::forEach(35, in, out, NULL, 0);
247}
248
Tim Murray89daad62013-07-29 14:30:02 -0700249
250
251
Tim Murray21fa7a02013-08-15 16:25:03 -0700252sp<ScriptIntrinsicBlur> ScriptIntrinsicBlur::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700253 if ((e->isCompatible(Element::U8_4(rs)) == false) &&
254 (e->isCompatible(Element::U8(rs)) == false)) {
255 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur");
256 return NULL;
257 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700258 return new ScriptIntrinsicBlur(rs, e);
259}
260
Tim Murray3cd44af2012-11-14 11:25:27 -0800261ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e)
Tim Murray8f1e60c2012-11-13 12:25:11 -0800262 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) {
Tim Murray7f0d5682012-11-08 16:35:24 -0800263
Tim Murray8f1e60c2012-11-13 12:25:11 -0800264}
Tim Murray7f0d5682012-11-08 16:35:24 -0800265
Tim Murray21fa7a02013-08-15 16:25:03 -0700266void ScriptIntrinsicBlur::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700267 if (in->getType()->getElement()->isCompatible(mElement) == false) {
268 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur input");
269 return;
270 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800271 Script::setVar(1, in);
Tim Murray21fa7a02013-08-15 16:25:03 -0700272}
273
274void ScriptIntrinsicBlur::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700275 if (out->getType()->getElement()->isCompatible(mElement) == false) {
276 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur output");
277 return;
278 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800279 Script::forEach(0, NULL, out, NULL, 0);
280}
Tim Murray7f0d5682012-11-08 16:35:24 -0800281
Tim Murray8f1e60c2012-11-13 12:25:11 -0800282void ScriptIntrinsicBlur::setRadius(float radius) {
Tim Murray10913a52013-08-20 17:19:47 -0700283 if (radius > 0.f && radius <= 25.f) {
284 Script::setVar(0, &radius, sizeof(float));
285 } else {
286 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Blur radius out of 0-25 pixel bound");
287 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800288}
Tim Murray89daad62013-07-29 14:30:02 -0700289
290
291
Tim Murrayaae73c92013-09-03 17:05:46 -0700292sp<ScriptIntrinsicColorMatrix> ScriptIntrinsicColorMatrix::create(sp<RS> rs) {
293 return new ScriptIntrinsicColorMatrix(rs, Element::RGBA_8888(rs));
Tim Murray21fa7a02013-08-15 16:25:03 -0700294}
295
Tim Murray89daad62013-07-29 14:30:02 -0700296ScriptIntrinsicColorMatrix::ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e)
297 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_COLOR_MATRIX, e) {
Tim Murrayaae73c92013-09-03 17:05:46 -0700298 float add[4] = {0.f, 0.f, 0.f, 0.f};
299 setAdd(add);
Tim Murray89daad62013-07-29 14:30:02 -0700300
301}
302
303void ScriptIntrinsicColorMatrix::forEach(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700304 if (!(in->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
305 !(in->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
306 !(in->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
307 !(in->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
308 !(in->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
309 !(in->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
310 !(in->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
311 !(in->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
312 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
313 return;
314 }
315
316 if (!(out->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
317 !(out->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
318 !(out->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
319 !(out->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
320 !(out->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
321 !(out->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
322 !(out->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
323 !(out->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
324 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
325 return;
326 }
327
Tim Murray89daad62013-07-29 14:30:02 -0700328 Script::forEach(0, in, out, NULL, 0);
329}
330
Tim Murray10913a52013-08-20 17:19:47 -0700331void ScriptIntrinsicColorMatrix::setAdd(float* add) {
332 Script::setVar(1, (void*)add, sizeof(float) * 4);
333}
Tim Murray89daad62013-07-29 14:30:02 -0700334
335void ScriptIntrinsicColorMatrix::setColorMatrix3(float* m) {
Tim Murrayaae73c92013-09-03 17:05:46 -0700336 float temp[16];
337 temp[0] = m[0];
338 temp[1] = m[1];
339 temp[2] = m[2];
340 temp[3] = 0.f;
341
342 temp[4] = m[3];
343 temp[5] = m[4];
344 temp[6] = m[5];
345 temp[7] = 0.f;
346
347 temp[8] = m[6];
348 temp[9] = m[7];
349 temp[10] = m[8];
350 temp[11] = 0.f;
351
352 temp[12] = 0.f;
353 temp[13] = 0.f;
354 temp[14] = 0.f;
355 temp[15] = 1.f;
356
357 setColorMatrix4(temp);
Tim Murray89daad62013-07-29 14:30:02 -0700358}
359
360
361void ScriptIntrinsicColorMatrix::setColorMatrix4(float* m) {
362 Script::setVar(0, (void*)m, sizeof(float) * 16);
363}
364
365
366void ScriptIntrinsicColorMatrix::setGreyscale() {
Tim Murrayaae73c92013-09-03 17:05:46 -0700367 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 -0700368 setColorMatrix3(matrix);
369}
370
371
372void ScriptIntrinsicColorMatrix::setRGBtoYUV() {
Tim Murrayaae73c92013-09-03 17:05:46 -0700373 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 -0700374 setColorMatrix3(matrix);
375}
376
377
378void ScriptIntrinsicColorMatrix::setYUVtoRGB() {
Tim Murrayaae73c92013-09-03 17:05:46 -0700379 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 -0700380 setColorMatrix3(matrix);
381}
382
Tim Murray21fa7a02013-08-15 16:25:03 -0700383
384
385sp<ScriptIntrinsicConvolve3x3> ScriptIntrinsicConvolve3x3::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700386 if (!(e->isCompatible(Element::U8(rs))) &&
387 !(e->isCompatible(Element::U8_2(rs))) &&
388 !(e->isCompatible(Element::U8_3(rs))) &&
389 !(e->isCompatible(Element::U8_4(rs))) &&
390 !(e->isCompatible(Element::F32(rs))) &&
391 !(e->isCompatible(Element::F32_2(rs))) &&
392 !(e->isCompatible(Element::F32_3(rs))) &&
393 !(e->isCompatible(Element::F32_4(rs)))) {
394 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve3x3");
395 return NULL;
396 }
397
Tim Murray21fa7a02013-08-15 16:25:03 -0700398 return new ScriptIntrinsicConvolve3x3(rs, e);
399}
400
Tim Murray89daad62013-07-29 14:30:02 -0700401ScriptIntrinsicConvolve3x3::ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e)
402 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_3x3, e) {
403
404}
405
406void ScriptIntrinsicConvolve3x3::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700407 if (!(in->getType()->getElement()->isCompatible(mElement))) {
408 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
409 return;
410 }
Tim Murray89daad62013-07-29 14:30:02 -0700411 Script::setVar(1, in);
412}
413
414void ScriptIntrinsicConvolve3x3::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700415 if (!(out->getType()->getElement()->isCompatible(mElement))) {
416 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
417 return;
418 }
Tim Murray89daad62013-07-29 14:30:02 -0700419 Script::forEach(0, NULL, out, NULL, 0);
420}
421
422void ScriptIntrinsicConvolve3x3::setCoefficients(float* v) {
423 Script::setVar(0, (void*)v, sizeof(float) * 9);
424}
425
Tim Murray21fa7a02013-08-15 16:25:03 -0700426sp<ScriptIntrinsicConvolve5x5> ScriptIntrinsicConvolve5x5::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700427 if (!(e->isCompatible(Element::U8(rs))) &&
428 !(e->isCompatible(Element::U8_2(rs))) &&
429 !(e->isCompatible(Element::U8_3(rs))) &&
430 !(e->isCompatible(Element::U8_4(rs))) &&
431 !(e->isCompatible(Element::F32(rs))) &&
432 !(e->isCompatible(Element::F32_2(rs))) &&
433 !(e->isCompatible(Element::F32_3(rs))) &&
434 !(e->isCompatible(Element::F32_4(rs)))) {
435 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve5x5");
436 return NULL;
437 }
438
Tim Murray21fa7a02013-08-15 16:25:03 -0700439 return new ScriptIntrinsicConvolve5x5(rs, e);
440}
441
Tim Murray89daad62013-07-29 14:30:02 -0700442ScriptIntrinsicConvolve5x5::ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e)
443 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_5x5, e) {
444
445}
446
447void ScriptIntrinsicConvolve5x5::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700448 if (!(in->getType()->getElement()->isCompatible(mElement))) {
449 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 input");
450 return;
451 }
Tim Murray89daad62013-07-29 14:30:02 -0700452 Script::setVar(1, in);
453}
454
455void ScriptIntrinsicConvolve5x5::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700456 if (!(out->getType()->getElement()->isCompatible(mElement))) {
457 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 output");
458 return;
459 }
460
Tim Murray89daad62013-07-29 14:30:02 -0700461 Script::forEach(0, NULL, out, NULL, 0);
462}
463
464void ScriptIntrinsicConvolve5x5::setCoefficients(float* v) {
465 Script::setVar(0, (void*)v, sizeof(float) * 25);
466}
467
Tim Murray10913a52013-08-20 17:19:47 -0700468sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(sp<RS> rs) {
469 return new ScriptIntrinsicHistogram(rs, NULL);
Tim Murray21fa7a02013-08-15 16:25:03 -0700470}
471
Tim Murrayb27b1812013-08-05 14:00:40 -0700472ScriptIntrinsicHistogram::ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e)
473 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_HISTOGRAM, e) {
Tim Murray89daad62013-07-29 14:30:02 -0700474
475}
476
Tim Murray10913a52013-08-20 17:19:47 -0700477void ScriptIntrinsicHistogram::setOutput(sp<Allocation> out) {
478 if (!(out->getType()->getElement()->isCompatible(Element::U32(mRS))) &&
479 !(out->getType()->getElement()->isCompatible(Element::U32_2(mRS))) &&
480 !(out->getType()->getElement()->isCompatible(Element::U32_3(mRS))) &&
481 !(out->getType()->getElement()->isCompatible(Element::U32_4(mRS))) &&
482 !(out->getType()->getElement()->isCompatible(Element::I32(mRS))) &&
483 !(out->getType()->getElement()->isCompatible(Element::I32_2(mRS))) &&
484 !(out->getType()->getElement()->isCompatible(Element::I32_3(mRS))) &&
485 !(out->getType()->getElement()->isCompatible(Element::I32_4(mRS)))) {
486 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Histogram output");
487 return;
488 }
489
490 if (out->getType()->getX() != 256 ||
491 out->getType()->getY() != 0 ||
492 out->getType()->hasMipmaps()) {
493 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid Allocation type for Histogram output");
494 return;
495 }
496 mOut = out;
497 Script::setVar(1, out);
Tim Murrayb27b1812013-08-05 14:00:40 -0700498}
499
500void ScriptIntrinsicHistogram::setDotCoefficients(float r, float g, float b, float a) {
501 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
502 return;
503 }
504 if ((r + g + b + a) > 1.f) {
505 return;
506 }
507
508 FieldPacker fp(16);
509 fp.add(r);
510 fp.add(g);
511 fp.add(b);
512 fp.add(a);
513 Script::setVar(0, fp.getData(), fp.getLength());
514
515}
516
517void ScriptIntrinsicHistogram::forEach(sp<Allocation> ain) {
Tim Murray10913a52013-08-20 17:19:47 -0700518 if (ain->getType()->getElement()->getVectorSize() <
519 mOut->getType()->getElement()->getVectorSize()) {
520 mRS->throwError(RS_ERROR_INVALID_PARAMETER,
521 "Input vector size must be >= output vector size");
522 return;
523 }
524
525 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) ||
526 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
527 mRS->throwError(RS_ERROR_INVALID_ELEMENT,
528 "Input allocation to Histogram must be U8 or U8_4");
529 return;
530 }
531
Tim Murrayb27b1812013-08-05 14:00:40 -0700532 Script::forEach(0, ain, NULL, NULL, 0);
533}
534
535
536void ScriptIntrinsicHistogram::forEach_dot(sp<Allocation> ain) {
Tim Murray10913a52013-08-20 17:19:47 -0700537 if (mOut->getType()->getElement()->getVectorSize() != 1) {
538 mRS->throwError(RS_ERROR_INVALID_PARAMETER,
539 "Output Histogram allocation must have vector size of 1 " \
540 "when used with forEach_dot");
541 return;
542 }
543 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) ||
544 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
545 mRS->throwError(RS_ERROR_INVALID_ELEMENT,
546 "Input allocation to Histogram must be U8 or U8_4");
547 return;
548 }
549
Tim Murrayb27b1812013-08-05 14:00:40 -0700550 Script::forEach(1, ain, NULL, NULL, 0);
551}
552
Tim Murray21fa7a02013-08-15 16:25:03 -0700553sp<ScriptIntrinsicLUT> ScriptIntrinsicLUT::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700554 if (!(e->isCompatible(Element::U8_4(rs)))) {
555 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
556 return NULL;
557 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700558 return new ScriptIntrinsicLUT(rs, e);
559}
560
Tim Murrayb27b1812013-08-05 14:00:40 -0700561ScriptIntrinsicLUT::ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e)
562 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_LUT, e), mDirty(true) {
Tim Murray2acce992013-08-28 14:23:31 -0700563 LUT = Allocation::createSized(rs, Element::U8(rs), 1024);
Tim Murrayb27b1812013-08-05 14:00:40 -0700564 for (int i = 0; i < 256; i++) {
565 mCache[i] = i;
566 mCache[i+256] = i;
567 mCache[i+512] = i;
568 mCache[i+768] = i;
569 }
Tim Murray2acce992013-08-28 14:23:31 -0700570 setVar(0, LUT);
Tim Murrayb27b1812013-08-05 14:00:40 -0700571}
572
Tim Murray89daad62013-07-29 14:30:02 -0700573void ScriptIntrinsicLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700574 if (mDirty) {
575 LUT->copy1DFrom((void*)mCache);
576 mDirty = false;
577 }
Tim Murray10913a52013-08-20 17:19:47 -0700578 if (!(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) ||
579 !(aout->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
580 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
581 return;
582 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700583 Script::forEach(0, ain, aout, NULL, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700584
585}
586
Tim Murray2acce992013-08-28 14:23:31 -0700587void ScriptIntrinsicLUT::setTable(unsigned int offset, unsigned char base, unsigned int length, unsigned char* lutValues) {
588 if ((base + length) > 256 || length == 0) {
589 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
Tim Murrayb27b1812013-08-05 14:00:40 -0700590 return;
591 }
592 mDirty = true;
Tim Murray2acce992013-08-28 14:23:31 -0700593 for (unsigned int i = 0; i < length; i++) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700594 mCache[offset + base + i] = lutValues[i];
595 }
596}
Tim Murray89daad62013-07-29 14:30:02 -0700597
Tim Murray2acce992013-08-28 14:23:31 -0700598void ScriptIntrinsicLUT::setRed(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700599 setTable(0, base, length, lutValues);
600}
Tim Murray89daad62013-07-29 14:30:02 -0700601
Tim Murray2acce992013-08-28 14:23:31 -0700602void ScriptIntrinsicLUT::setGreen(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700603 setTable(256, base, length, lutValues);
604}
605
Tim Murray2acce992013-08-28 14:23:31 -0700606void ScriptIntrinsicLUT::setBlue(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700607 setTable(512, base, length, lutValues);
608}
609
Tim Murray2acce992013-08-28 14:23:31 -0700610void ScriptIntrinsicLUT::setAlpha(unsigned char base, unsigned int length, unsigned char* lutValues) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700611 setTable(768, base, length, lutValues);
612}
613
614ScriptIntrinsicLUT::~ScriptIntrinsicLUT() {
615
616}
617
Tim Murray21fa7a02013-08-15 16:25:03 -0700618sp<ScriptIntrinsicYuvToRGB> ScriptIntrinsicYuvToRGB::create(sp<RS> rs, 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");
621 return NULL;
622 }
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
631void ScriptIntrinsicYuvToRGB::setInput(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
639void ScriptIntrinsicYuvToRGB::forEach(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
Tim Murrayb27b1812013-08-05 14:00:40 -0700645 Script::forEach(0, NULL, out, NULL, 0);
646}