ScriptIntrinsics.cpp revision fa77db83d3e36d6aa23622cec5bdcb5e373f0a3b
124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown/* 224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Copyright (C) 2008-2012 The Android Open Source Project 324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * you may not use this file except in compliance with the License. 624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * You may obtain a copy of the License at 724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 1024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Unless required by applicable law or agreed to in writing, software 1124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * See the License for the specific language governing permissions and 1424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * limitations under the License. 1524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 1624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 1724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown#include <malloc.h> 1824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 198e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas#include "RenderScript.h" 208e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas#include "rsCppInternal.h" 2124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 22f0e4dea75691d2fd1256508136ecce88bef6067bIan Lakeusing namespace android; 23c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteusing namespace RSC; 2424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 2524fa6c0dd42df057729e1a258388183f94da7f82Jeff BrownScriptIntrinsic::ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e) 26f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake : Script(NULL, rs) { 27f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake mID = createDispatch(rs, RS::dispatch->ScriptIntrinsicCreate(rs->getContext(), id, e->getID())); 28f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake mElement = e; 2924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 3024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 3124fa6c0dd42df057729e1a258388183f94da7f82Jeff BrownScriptIntrinsic::~ScriptIntrinsic() { 3224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 3324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 3424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 3524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownsp<ScriptIntrinsic3DLUT> ScriptIntrinsic3DLUT::create(sp<RS> rs, sp<const Element> e) { 36f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake if (e->isCompatible(Element::U8_4(rs)) == false) { 37f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic"); 38f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake return NULL; 39f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake } 408e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas return new ScriptIntrinsic3DLUT(rs, e); 41f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake} 42f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake 43f0e4dea75691d2fd1256508136ecce88bef6067bIan LakeScriptIntrinsic3DLUT::ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e) 44f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_3DLUT, e) { 4524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 4624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 4724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsic3DLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) { 4824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (ain->getType()->getElement()->isCompatible(mElement) == false || 4924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown aout->getType()->getElement()->isCompatible(mElement) == false) { 5024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_ELEMENT, "3DLUT forEach element mismatch"); 5124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return; 5224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 53ead061ff8567599fa905a1ee1de2532b7050d7faRoboErik Script::forEach(0, ain, aout, NULL, 0); 5424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 5524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsic3DLUT::setLUT(sp<Allocation> lut) { 5624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown sp<const Type> t = lut->getType(); 5724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (!t->getElement()->isCompatible(mElement)) { 5824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_ELEMENT, "setLUT element does not match"); 5924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return; 60ead061ff8567599fa905a1ee1de2532b7050d7faRoboErik } 6124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (t->getZ() == 0) { 6224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_PARAMETER, "setLUT Allocation must be 3D"); 6324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return; 6424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 6524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 6624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Script::setVar(0, lut); 67e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik} 6824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 6924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownsp<ScriptIntrinsicBlend> ScriptIntrinsicBlend::create(sp<RS> rs, sp<const Element> e) { 7024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (e->isCompatible(Element::U8_4(rs)) == false) { 7124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic"); 7224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return NULL; 7324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 7424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return new ScriptIntrinsicBlend(rs, e); 7524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 7624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 7724fa6c0dd42df057729e1a258388183f94da7f82Jeff BrownScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e) 7824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) { 79e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik} 8024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 81f0e4dea75691d2fd1256508136ecce88bef6067bIan Lakevoid ScriptIntrinsicBlend::blendClear(sp<Allocation> in, sp<Allocation> out) { 8224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 8324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 84e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 8524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 8624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Script::forEach(0, in, out, NULL, 0); 8724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 88e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik 8924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsicBlend::blendSrc(sp<Allocation> in, sp<Allocation> out) { 9024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 9124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 92e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 93e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik } 94e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik Script::forEach(1, in, out, NULL, 0); 9524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 9624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 9724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsicBlend::blendDst(sp<Allocation> in, sp<Allocation> out) { 9824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 9924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 10024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 101f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake } 10224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Script::forEach(2, in, out, NULL, 0); 10324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 10424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 10524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsicBlend::blendSrcOver(sp<Allocation> in, sp<Allocation> out) { 10624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 10724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 10824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 10924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 11024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Script::forEach(3, in, out, NULL, 0); 11124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 11224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 11324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsicBlend::blendDstOver(sp<Allocation> in, sp<Allocation> out) { 11424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 11524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 116e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 117e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik } 118e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik Script::forEach(4, in, out, NULL, 0); 119e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErik} 12024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 121e0c3fd8d5c24c7e8bcc54234f30c01e78137b67eRoboErikvoid ScriptIntrinsicBlend::blendSrcIn(sp<Allocation> in, sp<Allocation> out) { 1229b032988d409ee6bff579d8f21ef79f4c5fd5fb5Ian Lake if (in->getType()->getElement()->isCompatible(mElement) == false || 1239b032988d409ee6bff579d8f21ef79f4c5fd5fb5Ian Lake out->getType()->getElement()->isCompatible(mElement) == false) { 124c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 1259b032988d409ee6bff579d8f21ef79f4c5fd5fb5Ian Lake } 1269b032988d409ee6bff579d8f21ef79f4c5fd5fb5Ian Lake Script::forEach(5, in, out, NULL, 0); 12724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 12824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 12924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsicBlend::blendDstIn(sp<Allocation> in, sp<Allocation> out) { 13024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 13124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 13224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 13324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 13424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Script::forEach(6, in, out, NULL, 0); 13524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 13624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 13724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsicBlend::blendSrcOut(sp<Allocation> in, sp<Allocation> out) { 13824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 13924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 14024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 141ead061ff8567599fa905a1ee1de2532b7050d7faRoboErik } 14224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Script::forEach(7, in, out, NULL, 0); 143ead061ff8567599fa905a1ee1de2532b7050d7faRoboErik} 14424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 145ead061ff8567599fa905a1ee1de2532b7050d7faRoboErikvoid ScriptIntrinsicBlend::blendDstOut(sp<Allocation> in, sp<Allocation> out) { 14624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 14724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 14824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 14924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 15024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Script::forEach(8, in, out, NULL, 0); 15124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 15224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 15324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsicBlend::blendSrcAtop(sp<Allocation> in, sp<Allocation> out) { 15424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 15524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 15624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 15724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 15824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Script::forEach(9, in, out, NULL, 0); 15924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 16024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 16124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsicBlend::blendDstAtop(sp<Allocation> in, sp<Allocation> out) { 16224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 16324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 16424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 16524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 16624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Script::forEach(10, in, out, NULL, 0); 167c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette} 168c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette 169c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverettevoid ScriptIntrinsicBlend::blendXor(sp<Allocation> in, sp<Allocation> out) { 170c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette if (in->getType()->getElement()->isCompatible(mElement) == false || 171c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette out->getType()->getElement()->isCompatible(mElement) == false) { 172c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 173c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette } 174c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette Script::forEach(11, in, out, NULL, 0); 175c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette} 176c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette 177c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette// Numbering jumps here 178c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverettevoid ScriptIntrinsicBlend::blendMultiply(sp<Allocation> in, sp<Allocation> out) { 179c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette if (in->getType()->getElement()->isCompatible(mElement) == false || 180c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette out->getType()->getElement()->isCompatible(mElement) == false) { 181c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 18224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 18324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Script::forEach(14, in, out, NULL, 0); 18424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 18524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 18624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown// Numbering jumps here 18724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid ScriptIntrinsicBlend::blendAdd(sp<Allocation> in, sp<Allocation> out) { 18824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (in->getType()->getElement()->isCompatible(mElement) == false || 18924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out->getType()->getElement()->isCompatible(mElement) == false) { 19024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 19124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 192f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake Script::forEach(34, in, out, NULL, 0); 193} 194 195void ScriptIntrinsicBlend::blendSubtract(sp<Allocation> in, sp<Allocation> out) { 196 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 } 200 Script::forEach(35, in, out, NULL, 0); 201} 202 203 204 205 206sp<ScriptIntrinsicBlur> ScriptIntrinsicBlur::create(sp<RS> rs, sp<const Element> e) { 207 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 } 212 return new ScriptIntrinsicBlur(rs, e); 213} 214 215ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e) 216 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) { 217 218} 219 220void ScriptIntrinsicBlur::setInput(sp<Allocation> in) { 221 if (in->getType()->getElement()->isCompatible(mElement) == false) { 222 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur input"); 223 return; 224 } 225 Script::setVar(1, in); 226} 227 228void ScriptIntrinsicBlur::forEach(sp<Allocation> out) { 229 if (out->getType()->getElement()->isCompatible(mElement) == false) { 230 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur output"); 231 return; 232 } 233 Script::forEach(0, NULL, out, NULL, 0); 234} 235 236void ScriptIntrinsicBlur::setRadius(float radius) { 237 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 } 242} 243 244 245 246sp<ScriptIntrinsicColorMatrix> ScriptIntrinsicColorMatrix::create(sp<RS> rs, sp<const Element> e) { 247 return new ScriptIntrinsicColorMatrix(rs, e); 248} 249 250ScriptIntrinsicColorMatrix::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) { 256 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 280 Script::forEach(0, in, out, NULL, 0); 281} 282 283void ScriptIntrinsicColorMatrix::setAdd(float* add) { 284 Script::setVar(1, (void*)add, sizeof(float) * 4); 285} 286 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 314 315 316sp<ScriptIntrinsicConvolve3x3> ScriptIntrinsicConvolve3x3::create(sp<RS> rs, sp<const Element> e) { 317 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 329 return new ScriptIntrinsicConvolve3x3(rs, e); 330} 331 332ScriptIntrinsicConvolve3x3::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) { 338 if (!(in->getType()->getElement()->isCompatible(mElement))) { 339 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3"); 340 return; 341 } 342 Script::setVar(1, in); 343} 344 345void ScriptIntrinsicConvolve3x3::forEach(sp<Allocation> out) { 346 if (!(out->getType()->getElement()->isCompatible(mElement))) { 347 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3"); 348 return; 349 } 350 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 357sp<ScriptIntrinsicConvolve5x5> ScriptIntrinsicConvolve5x5::create(sp<RS> rs, sp<const Element> e) { 358 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 370 return new ScriptIntrinsicConvolve5x5(rs, e); 371} 372 373ScriptIntrinsicConvolve5x5::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) { 379 if (!(in->getType()->getElement()->isCompatible(mElement))) { 380 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 input"); 381 return; 382 } 383 Script::setVar(1, in); 384} 385 386void ScriptIntrinsicConvolve5x5::forEach(sp<Allocation> out) { 387 if (!(out->getType()->getElement()->isCompatible(mElement))) { 388 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 output"); 389 return; 390 } 391 392 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 399sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(sp<RS> rs) { 400 return new ScriptIntrinsicHistogram(rs, NULL); 401} 402 403ScriptIntrinsicHistogram::ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e) 404 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_HISTOGRAM, e) { 405 406} 407 408void 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); 429} 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) { 449 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 463 Script::forEach(0, ain, NULL, NULL, 0); 464} 465 466 467void ScriptIntrinsicHistogram::forEach_dot(sp<Allocation> ain) { 468 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 481 Script::forEach(1, ain, NULL, NULL, 0); 482} 483 484sp<ScriptIntrinsicLUT> ScriptIntrinsicLUT::create(sp<RS> rs, sp<const Element> e) { 485 if (!(e->isCompatible(Element::U8_4(rs)))) { 486 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT"); 487 return NULL; 488 } 489 return new ScriptIntrinsicLUT(rs, e); 490} 491 492ScriptIntrinsicLUT::ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e) 493 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_LUT, e), mDirty(true) { 494 LUT = Allocation::createSized(rs, Element::U8(rs), 1024); 495 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 } 501 setVar(0, LUT); 502} 503 504void ScriptIntrinsicLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) { 505 if (mDirty) { 506 LUT->copy1DFrom((void*)mCache); 507 mDirty = false; 508 } 509 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 } 514 Script::forEach(0, ain, aout, NULL, 0); 515 516} 517 518void 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"); 521 return; 522 } 523 mDirty = true; 524 for (unsigned int i = 0; i < length; i++) { 525 mCache[offset + base + i] = lutValues[i]; 526 } 527} 528 529void ScriptIntrinsicLUT::setRed(unsigned char base, unsigned int length, unsigned char* lutValues) { 530 setTable(0, base, length, lutValues); 531} 532 533void ScriptIntrinsicLUT::setGreen(unsigned char base, unsigned int length, unsigned char* lutValues) { 534 setTable(256, base, length, lutValues); 535} 536 537void ScriptIntrinsicLUT::setBlue(unsigned char base, unsigned int length, unsigned char* lutValues) { 538 setTable(512, base, length, lutValues); 539} 540 541void ScriptIntrinsicLUT::setAlpha(unsigned char base, unsigned int length, unsigned char* lutValues) { 542 setTable(768, base, length, lutValues); 543} 544 545ScriptIntrinsicLUT::~ScriptIntrinsicLUT() { 546 547} 548 549sp<ScriptIntrinsicYuvToRGB> ScriptIntrinsicYuvToRGB::create(sp<RS> rs, sp<const Element> e) { 550 if (!(e->isCompatible(Element::U8_4(rs)))) { 551 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for YuvToRGB"); 552 return NULL; 553 } 554 return new ScriptIntrinsicYuvToRGB(rs, e); 555} 556 557ScriptIntrinsicYuvToRGB::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) { 563 if (!(in->getType()->getElement()->isCompatible(Element::YUV(mRS)))) { 564 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for input in YuvToRGB"); 565 return; 566 } 567 Script::setVar(0, in); 568} 569 570void ScriptIntrinsicYuvToRGB::forEach(sp<Allocation> out) { 571 if (!(out->getType()->getElement()->isCompatible(mElement))) { 572 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for output in YuvToRGB"); 573 return; 574 } 575 576 Script::forEach(0, NULL, out, NULL, 0); 577} 578