ScriptIntrinsics.cpp revision e5428e661ce6f9d24f838cab0a8fb0fa8c76dbca
1/* 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 17#include <malloc.h> 18 19#include "RenderScript.h" 20#include "rsCppInternal.h" 21 22using namespace android; 23using namespace RSC; 24 25ScriptIntrinsic::ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e) 26 : Script(nullptr, rs) { 27 mID = createDispatch(rs, RS::dispatch->ScriptIntrinsicCreate(rs->getContext(), id, 28 e != nullptr ? e->getID() : 0)); 29 mElement = e; 30} 31 32ScriptIntrinsic::~ScriptIntrinsic() { 33 34} 35 36sp<ScriptIntrinsic3DLUT> ScriptIntrinsic3DLUT::create(sp<RS> rs, sp<const Element> e) { 37 if (e->isCompatible(Element::U8_4(rs)) == false) { 38 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic"); 39 return nullptr; 40 } 41 return new ScriptIntrinsic3DLUT(rs, e); 42} 43 44ScriptIntrinsic3DLUT::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) { 49 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 } 54 Script::forEach(0, ain, aout, nullptr, 0); 55} 56void ScriptIntrinsic3DLUT::setLUT(sp<Allocation> lut) { 57 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 67 Script::setVar(0, lut); 68} 69 70sp<ScriptIntrinsicBlend> ScriptIntrinsicBlend::create(sp<RS> rs, sp<const Element> e) { 71 if (e->isCompatible(Element::U8_4(rs)) == false) { 72 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic"); 73 return nullptr; 74 } 75 return new ScriptIntrinsicBlend(rs, e); 76} 77 78ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e) 79 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) { 80} 81 82void ScriptIntrinsicBlend::forEachClear(sp<Allocation> in, sp<Allocation> out) { 83 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 } 87 Script::forEach(0, in, out, nullptr, 0); 88} 89 90void ScriptIntrinsicBlend::forEachSrc(sp<Allocation> in, sp<Allocation> out) { 91 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 } 95 Script::forEach(1, in, out, nullptr, 0); 96} 97 98void ScriptIntrinsicBlend::forEachDst(sp<Allocation> in, sp<Allocation> out) { 99 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 } 103 Script::forEach(2, in, out, nullptr, 0); 104} 105 106void ScriptIntrinsicBlend::forEachSrcOver(sp<Allocation> in, sp<Allocation> out) { 107 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 } 111 Script::forEach(3, in, out, nullptr, 0); 112} 113 114void ScriptIntrinsicBlend::forEachDstOver(sp<Allocation> in, sp<Allocation> out) { 115 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 } 119 Script::forEach(4, in, out, nullptr, 0); 120} 121 122void ScriptIntrinsicBlend::forEachSrcIn(sp<Allocation> in, sp<Allocation> out) { 123 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 } 127 Script::forEach(5, in, out, nullptr, 0); 128} 129 130void ScriptIntrinsicBlend::forEachDstIn(sp<Allocation> in, sp<Allocation> out) { 131 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 } 135 Script::forEach(6, in, out, nullptr, 0); 136} 137 138void ScriptIntrinsicBlend::forEachSrcOut(sp<Allocation> in, sp<Allocation> out) { 139 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 } 143 Script::forEach(7, in, out, nullptr, 0); 144} 145 146void ScriptIntrinsicBlend::forEachDstOut(sp<Allocation> in, sp<Allocation> out) { 147 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 } 151 Script::forEach(8, in, out, nullptr, 0); 152} 153 154void ScriptIntrinsicBlend::forEachSrcAtop(sp<Allocation> in, sp<Allocation> out) { 155 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 } 159 Script::forEach(9, in, out, nullptr, 0); 160} 161 162void ScriptIntrinsicBlend::forEachDstAtop(sp<Allocation> in, sp<Allocation> out) { 163 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 } 167 Script::forEach(10, in, out, nullptr, 0); 168} 169 170void ScriptIntrinsicBlend::forEachXor(sp<Allocation> in, sp<Allocation> out) { 171 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 } 175 Script::forEach(11, in, out, nullptr, 0); 176} 177 178// Numbering jumps here 179void ScriptIntrinsicBlend::forEachMultiply(sp<Allocation> in, sp<Allocation> out) { 180 if (in->getType()->getElement()->isCompatible(mElement) == false || 181 out->getType()->getElement()->isCompatible(mElement) == false) { 182 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 183 } 184 Script::forEach(14, in, out, nullptr, 0); 185} 186 187// Numbering jumps here 188void ScriptIntrinsicBlend::forEachAdd(sp<Allocation> in, sp<Allocation> out) { 189 if (in->getType()->getElement()->isCompatible(mElement) == false || 190 out->getType()->getElement()->isCompatible(mElement) == false) { 191 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 192 } 193 Script::forEach(34, in, out, nullptr, 0); 194} 195 196void ScriptIntrinsicBlend::forEachSubtract(sp<Allocation> in, sp<Allocation> out) { 197 if (in->getType()->getElement()->isCompatible(mElement) == false || 198 out->getType()->getElement()->isCompatible(mElement) == false) { 199 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 200 } 201 Script::forEach(35, in, out, nullptr, 0); 202} 203 204 205 206 207sp<ScriptIntrinsicBlur> ScriptIntrinsicBlur::create(sp<RS> rs, sp<const Element> e) { 208 if ((e->isCompatible(Element::U8_4(rs)) == false) && 209 (e->isCompatible(Element::U8(rs)) == false)) { 210 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur"); 211 return nullptr; 212 } 213 return new ScriptIntrinsicBlur(rs, e); 214} 215 216ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e) 217 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) { 218 219} 220 221void ScriptIntrinsicBlur::setInput(sp<Allocation> in) { 222 if (in->getType()->getElement()->isCompatible(mElement) == false) { 223 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur input"); 224 return; 225 } 226 Script::setVar(1, in); 227} 228 229void ScriptIntrinsicBlur::forEach(sp<Allocation> out) { 230 if (out->getType()->getElement()->isCompatible(mElement) == false) { 231 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur output"); 232 return; 233 } 234 Script::forEach(0, nullptr, out, nullptr, 0); 235} 236 237void ScriptIntrinsicBlur::setRadius(float radius) { 238 if (radius > 0.f && radius <= 25.f) { 239 Script::setVar(0, &radius, sizeof(float)); 240 } else { 241 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Blur radius out of 0-25 pixel bound"); 242 } 243} 244 245 246 247sp<ScriptIntrinsicColorMatrix> ScriptIntrinsicColorMatrix::create(sp<RS> rs) { 248 return new ScriptIntrinsicColorMatrix(rs, Element::RGBA_8888(rs)); 249} 250 251ScriptIntrinsicColorMatrix::ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e) 252 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_COLOR_MATRIX, e) { 253 float add[4] = {0.f, 0.f, 0.f, 0.f}; 254 setAdd(add); 255 256} 257 258void ScriptIntrinsicColorMatrix::forEach(sp<Allocation> in, sp<Allocation> out) { 259 if (!(in->getType()->getElement()->isCompatible(Element::U8(mRS))) && 260 !(in->getType()->getElement()->isCompatible(Element::U8_2(mRS))) && 261 !(in->getType()->getElement()->isCompatible(Element::U8_3(mRS))) && 262 !(in->getType()->getElement()->isCompatible(Element::U8_4(mRS))) && 263 !(in->getType()->getElement()->isCompatible(Element::F32(mRS))) && 264 !(in->getType()->getElement()->isCompatible(Element::F32_2(mRS))) && 265 !(in->getType()->getElement()->isCompatible(Element::F32_3(mRS))) && 266 !(in->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) { 267 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix"); 268 return; 269 } 270 271 if (!(out->getType()->getElement()->isCompatible(Element::U8(mRS))) && 272 !(out->getType()->getElement()->isCompatible(Element::U8_2(mRS))) && 273 !(out->getType()->getElement()->isCompatible(Element::U8_3(mRS))) && 274 !(out->getType()->getElement()->isCompatible(Element::U8_4(mRS))) && 275 !(out->getType()->getElement()->isCompatible(Element::F32(mRS))) && 276 !(out->getType()->getElement()->isCompatible(Element::F32_2(mRS))) && 277 !(out->getType()->getElement()->isCompatible(Element::F32_3(mRS))) && 278 !(out->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) { 279 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix"); 280 return; 281 } 282 283 Script::forEach(0, in, out, nullptr, 0); 284} 285 286void ScriptIntrinsicColorMatrix::setAdd(float* add) { 287 Script::setVar(1, (void*)add, sizeof(float) * 4); 288} 289 290void ScriptIntrinsicColorMatrix::setColorMatrix3(float* m) { 291 float temp[16]; 292 temp[0] = m[0]; 293 temp[1] = m[1]; 294 temp[2] = m[2]; 295 temp[3] = 0.f; 296 297 temp[4] = m[3]; 298 temp[5] = m[4]; 299 temp[6] = m[5]; 300 temp[7] = 0.f; 301 302 temp[8] = m[6]; 303 temp[9] = m[7]; 304 temp[10] = m[8]; 305 temp[11] = 0.f; 306 307 temp[12] = 0.f; 308 temp[13] = 0.f; 309 temp[14] = 0.f; 310 temp[15] = 1.f; 311 312 setColorMatrix4(temp); 313} 314 315 316void ScriptIntrinsicColorMatrix::setColorMatrix4(float* m) { 317 Script::setVar(0, (void*)m, sizeof(float) * 16); 318} 319 320 321void ScriptIntrinsicColorMatrix::setGreyscale() { 322 float matrix[] = {0.299f, 0.299f, 0.299f,0.587f,0.587f,0.587f,0.114f,0.114f, 0.114f}; 323 setColorMatrix3(matrix); 324} 325 326 327void ScriptIntrinsicColorMatrix::setRGBtoYUV() { 328 float matrix[] = { 0.299f, -0.14713f, 0.615f, 0.587f, -0.28886f, -0.51499f, 0.114f, 0.436f, -0.10001f}; 329 setColorMatrix3(matrix); 330} 331 332 333void ScriptIntrinsicColorMatrix::setYUVtoRGB() { 334 float matrix[] = {1.f, 1.f, 1.f, 0.f, -0.39465f, 2.03211f, 1.13983f, -0.5806f, 0.f}; 335 setColorMatrix3(matrix); 336} 337 338 339 340sp<ScriptIntrinsicConvolve3x3> ScriptIntrinsicConvolve3x3::create(sp<RS> rs, sp<const Element> e) { 341 if (!(e->isCompatible(Element::U8(rs))) && 342 !(e->isCompatible(Element::U8_2(rs))) && 343 !(e->isCompatible(Element::U8_3(rs))) && 344 !(e->isCompatible(Element::U8_4(rs))) && 345 !(e->isCompatible(Element::F32(rs))) && 346 !(e->isCompatible(Element::F32_2(rs))) && 347 !(e->isCompatible(Element::F32_3(rs))) && 348 !(e->isCompatible(Element::F32_4(rs)))) { 349 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve3x3"); 350 return nullptr; 351 } 352 353 return new ScriptIntrinsicConvolve3x3(rs, e); 354} 355 356ScriptIntrinsicConvolve3x3::ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e) 357 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_3x3, e) { 358 359} 360 361void ScriptIntrinsicConvolve3x3::setInput(sp<Allocation> in) { 362 if (!(in->getType()->getElement()->isCompatible(mElement))) { 363 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3"); 364 return; 365 } 366 Script::setVar(1, in); 367} 368 369void ScriptIntrinsicConvolve3x3::forEach(sp<Allocation> out) { 370 if (!(out->getType()->getElement()->isCompatible(mElement))) { 371 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3"); 372 return; 373 } 374 Script::forEach(0, nullptr, out, nullptr, 0); 375} 376 377void ScriptIntrinsicConvolve3x3::setCoefficients(float* v) { 378 Script::setVar(0, (void*)v, sizeof(float) * 9); 379} 380 381sp<ScriptIntrinsicConvolve5x5> ScriptIntrinsicConvolve5x5::create(sp<RS> rs, sp<const Element> e) { 382 if (!(e->isCompatible(Element::U8(rs))) && 383 !(e->isCompatible(Element::U8_2(rs))) && 384 !(e->isCompatible(Element::U8_3(rs))) && 385 !(e->isCompatible(Element::U8_4(rs))) && 386 !(e->isCompatible(Element::F32(rs))) && 387 !(e->isCompatible(Element::F32_2(rs))) && 388 !(e->isCompatible(Element::F32_3(rs))) && 389 !(e->isCompatible(Element::F32_4(rs)))) { 390 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve5x5"); 391 return nullptr; 392 } 393 394 return new ScriptIntrinsicConvolve5x5(rs, e); 395} 396 397ScriptIntrinsicConvolve5x5::ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e) 398 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_5x5, e) { 399 400} 401 402void ScriptIntrinsicConvolve5x5::setInput(sp<Allocation> in) { 403 if (!(in->getType()->getElement()->isCompatible(mElement))) { 404 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 input"); 405 return; 406 } 407 Script::setVar(1, in); 408} 409 410void ScriptIntrinsicConvolve5x5::forEach(sp<Allocation> out) { 411 if (!(out->getType()->getElement()->isCompatible(mElement))) { 412 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 output"); 413 return; 414 } 415 416 Script::forEach(0, nullptr, out, nullptr, 0); 417} 418 419void ScriptIntrinsicConvolve5x5::setCoefficients(float* v) { 420 Script::setVar(0, (void*)v, sizeof(float) * 25); 421} 422 423sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(sp<RS> rs, sp<const Element> e) { 424 return new ScriptIntrinsicHistogram(rs, e); 425} 426 427ScriptIntrinsicHistogram::ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e) 428 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_HISTOGRAM, e) { 429 430} 431 432void ScriptIntrinsicHistogram::setOutput(sp<Allocation> out) { 433 if (!(out->getType()->getElement()->isCompatible(Element::U32(mRS))) && 434 !(out->getType()->getElement()->isCompatible(Element::U32_2(mRS))) && 435 !(out->getType()->getElement()->isCompatible(Element::U32_3(mRS))) && 436 !(out->getType()->getElement()->isCompatible(Element::U32_4(mRS))) && 437 !(out->getType()->getElement()->isCompatible(Element::I32(mRS))) && 438 !(out->getType()->getElement()->isCompatible(Element::I32_2(mRS))) && 439 !(out->getType()->getElement()->isCompatible(Element::I32_3(mRS))) && 440 !(out->getType()->getElement()->isCompatible(Element::I32_4(mRS)))) { 441 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Histogram output"); 442 return; 443 } 444 445 if (out->getType()->getX() != 256 || 446 out->getType()->getY() != 0 || 447 out->getType()->hasMipmaps()) { 448 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid Allocation type for Histogram output"); 449 return; 450 } 451 mOut = out; 452 Script::setVar(1, out); 453} 454 455void ScriptIntrinsicHistogram::setDotCoefficients(float r, float g, float b, float a) { 456 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) { 457 return; 458 } 459 if ((r + g + b + a) > 1.f) { 460 return; 461 } 462 463 FieldPacker fp(16); 464 fp.add(r); 465 fp.add(g); 466 fp.add(b); 467 fp.add(a); 468 Script::setVar(0, fp.getData(), fp.getLength()); 469 470} 471 472void ScriptIntrinsicHistogram::forEach(sp<Allocation> ain) { 473 if (ain->getType()->getElement()->getVectorSize() < 474 mOut->getType()->getElement()->getVectorSize()) { 475 mRS->throwError(RS_ERROR_INVALID_PARAMETER, 476 "Input vector size must be >= output vector size"); 477 return; 478 } 479 480 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) && 481 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) { 482 mRS->throwError(RS_ERROR_INVALID_ELEMENT, 483 "Input allocation to Histogram must be U8 or U8_4"); 484 return; 485 } 486 487 Script::forEach(0, ain, nullptr, nullptr, 0); 488} 489 490 491void ScriptIntrinsicHistogram::forEach_dot(sp<Allocation> ain) { 492 if (mOut->getType()->getElement()->getVectorSize() != 1) { 493 mRS->throwError(RS_ERROR_INVALID_PARAMETER, 494 "Output Histogram allocation must have vector size of 1 " \ 495 "when used with forEach_dot"); 496 return; 497 } 498 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) && 499 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) { 500 mRS->throwError(RS_ERROR_INVALID_ELEMENT, 501 "Input allocation to Histogram must be U8 or U8_4"); 502 return; 503 } 504 505 Script::forEach(1, ain, nullptr, nullptr, 0); 506} 507 508sp<ScriptIntrinsicLUT> ScriptIntrinsicLUT::create(sp<RS> rs, sp<const Element> e) { 509 if (!(e->isCompatible(Element::U8_4(rs)))) { 510 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT"); 511 return nullptr; 512 } 513 return new ScriptIntrinsicLUT(rs, e); 514} 515 516ScriptIntrinsicLUT::ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e) 517 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_LUT, e), mDirty(true) { 518 LUT = Allocation::createSized(rs, Element::U8(rs), 1024); 519 for (int i = 0; i < 256; i++) { 520 mCache[i] = i; 521 mCache[i+256] = i; 522 mCache[i+512] = i; 523 mCache[i+768] = i; 524 } 525 setVar(0, LUT); 526} 527 528void ScriptIntrinsicLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) { 529 if (mDirty) { 530 LUT->copy1DFrom((void*)mCache); 531 mDirty = false; 532 } 533 if (!(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) || 534 !(aout->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) { 535 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT"); 536 return; 537 } 538 Script::forEach(0, ain, aout, nullptr, 0); 539 540} 541 542void ScriptIntrinsicLUT::setTable(unsigned int offset, unsigned char base, unsigned int length, unsigned char* lutValues) { 543 if ((base + length) > 256 || length == 0) { 544 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range"); 545 return; 546 } 547 mDirty = true; 548 for (unsigned int i = 0; i < length; i++) { 549 mCache[offset + base + i] = lutValues[i]; 550 } 551} 552 553void ScriptIntrinsicLUT::setRed(unsigned char base, unsigned int length, unsigned char* lutValues) { 554 setTable(0, base, length, lutValues); 555} 556 557void ScriptIntrinsicLUT::setGreen(unsigned char base, unsigned int length, unsigned char* lutValues) { 558 setTable(256, base, length, lutValues); 559} 560 561void ScriptIntrinsicLUT::setBlue(unsigned char base, unsigned int length, unsigned char* lutValues) { 562 setTable(512, base, length, lutValues); 563} 564 565void ScriptIntrinsicLUT::setAlpha(unsigned char base, unsigned int length, unsigned char* lutValues) { 566 setTable(768, base, length, lutValues); 567} 568 569ScriptIntrinsicLUT::~ScriptIntrinsicLUT() { 570 571} 572 573sp<ScriptIntrinsicResize> ScriptIntrinsicResize::create(sp<RS> rs) { 574 return new ScriptIntrinsicResize(rs, nullptr); 575} 576 577ScriptIntrinsicResize::ScriptIntrinsicResize(sp<RS> rs, sp<const Element> e) 578 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_RESIZE, e) { 579 580} 581void ScriptIntrinsicResize::forEach_bicubic(sp<Allocation> aout) { 582 if (aout == mInput) { 583 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Resize Input and Ouput cannot be the same"); 584 } 585 586 if (!(mInput->getType()->getElement()->isCompatible(aout->getType()->getElement()))) { 587 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Resize forEach element mismatch"); 588 return; 589 } 590 Script::forEach(0, nullptr, aout, nullptr, 0); 591} 592void ScriptIntrinsicResize::setInput(sp<Allocation> ain) { 593 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) && 594 !(ain->getType()->getElement()->isCompatible(Element::U8_2(mRS))) && 595 !(ain->getType()->getElement()->isCompatible(Element::U8_3(mRS))) && 596 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) && 597 !(ain->getType()->getElement()->isCompatible(Element::F32(mRS))) && 598 !(ain->getType()->getElement()->isCompatible(Element::F32_2(mRS))) && 599 !(ain->getType()->getElement()->isCompatible(Element::F32_3(mRS))) && 600 !(ain->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) { 601 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Resize Input"); 602 return; 603 } 604 605 mInput = ain; 606 Script::setVar(0, ain); 607} 608 609 610sp<ScriptIntrinsicYuvToRGB> ScriptIntrinsicYuvToRGB::create(sp<RS> rs, sp<const Element> e) { 611 if (!(e->isCompatible(Element::U8_4(rs)))) { 612 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for YuvToRGB"); 613 return nullptr; 614 } 615 return new ScriptIntrinsicYuvToRGB(rs, e); 616} 617 618ScriptIntrinsicYuvToRGB::ScriptIntrinsicYuvToRGB(sp<RS> rs, sp<const Element> e) 619 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB, e) { 620 621} 622 623void ScriptIntrinsicYuvToRGB::setInput(sp<Allocation> in) { 624 if (!(in->getType()->getElement()->isCompatible(Element::YUV(mRS)))) { 625 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for input in YuvToRGB"); 626 return; 627 } 628 Script::setVar(0, in); 629} 630 631void ScriptIntrinsicYuvToRGB::forEach(sp<Allocation> out) { 632 if (!(out->getType()->getElement()->isCompatible(mElement))) { 633 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for output in YuvToRGB"); 634 return; 635 } 636 637 Script::forEach(0, nullptr, out, nullptr, 0); 638} 639