rsdIntrinsicBlend.cpp revision fa17cda2d7e0948677035890e40498ad0b639c92
1/* 2 * Copyright (C) 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 18#include "rsdCore.h" 19#include "rsdIntrinsics.h" 20#include "rsdAllocation.h" 21 22#include "rsdIntrinsicInlines.h" 23 24using namespace android; 25using namespace android::renderscript; 26 27struct ConvolveParams { 28 float f[4]; 29}; 30 31 32enum { 33 BLEND_CLEAR = 0, 34 BLEND_SRC = 1, 35 BLEND_DST = 2, 36 BLEND_SRC_OVER = 3, 37 BLEND_DST_OVER = 4, 38 BLEND_SRC_IN = 5, 39 BLEND_DST_IN = 6, 40 BLEND_SRC_OUT = 7, 41 BLEND_DST_OUT = 8, 42 BLEND_SRC_ATOP = 9, 43 BLEND_DST_ATOP = 10, 44 BLEND_XOR = 11, 45 46 BLEND_NORMAL = 12, 47 BLEND_AVERAGE = 13, 48 BLEND_MULTIPLY = 14, 49 BLEND_SCREEN = 15, 50 BLEND_DARKEN = 16, 51 BLEND_LIGHTEN = 17, 52 BLEND_OVERLAY = 18, 53 BLEND_HARDLIGHT = 19, 54 BLEND_SOFTLIGHT = 20, 55 BLEND_DIFFERENCE = 21, 56 BLEND_NEGATION = 22, 57 BLEND_EXCLUSION = 23, 58 BLEND_COLOR_DODGE = 24, 59 BLEND_INVERSE_COLOR_DODGE = 25, 60 BLEND_SOFT_DODGE = 26, 61 BLEND_COLOR_BURN = 27, 62 BLEND_INVERSE_COLOR_BURN = 28, 63 BLEND_SOFT_BURN = 29, 64 BLEND_REFLECT = 30, 65 BLEND_GLOW = 31, 66 BLEND_FREEZE = 32, 67 BLEND_HEAT = 33, 68 BLEND_ADD = 34, 69 BLEND_SUBTRACT = 35, 70 BLEND_STAMP = 36, 71 BLEND_RED = 37, 72 BLEND_GREEN = 38, 73 BLEND_BLUE = 39, 74 BLEND_HUE = 40, 75 BLEND_SATURATION = 41, 76 BLEND_COLOR = 42, 77 BLEND_LUMINOSITY = 43 78}; 79 80extern "C" void rsdIntrinsicBlendSrcOver_K(void *dst, const void *src, uint32_t count8); 81extern "C" void rsdIntrinsicBlendDstOver_K(void *dst, const void *src, uint32_t count8); 82extern "C" void rsdIntrinsicBlendSrcIn_K(void *dst, const void *src, uint32_t count8); 83extern "C" void rsdIntrinsicBlendDstIn_K(void *dst, const void *src, uint32_t count8); 84extern "C" void rsdIntrinsicBlendSrcOut_K(void *dst, const void *src, uint32_t count8); 85extern "C" void rsdIntrinsicBlendDstOut_K(void *dst, const void *src, uint32_t count8); 86extern "C" void rsdIntrinsicBlendSrcAtop_K(void *dst, const void *src, uint32_t count8); 87extern "C" void rsdIntrinsicBlendDstAtop_K(void *dst, const void *src, uint32_t count8); 88extern "C" void rsdIntrinsicBlendXor_K(void *dst, const void *src, uint32_t count8); 89extern "C" void rsdIntrinsicBlendMultiply_K(void *dst, const void *src, uint32_t count8); 90extern "C" void rsdIntrinsicBlendAdd_K(void *dst, const void *src, uint32_t count8); 91extern "C" void rsdIntrinsicBlendSub_K(void *dst, const void *src, uint32_t count8); 92 93//#undef ARCH_ARM_HAVE_NEON 94 95static void ColorMatrix_uchar4(const RsForEachStubParamStruct *p, 96 uint32_t xstart, uint32_t xend, 97 uint32_t instep, uint32_t outstep) { 98 ConvolveParams *cp = (ConvolveParams *)p->usr; 99 100 // instep/outstep can be ignored--sizeof(uchar4) known at compile time 101 uchar4 *out = (uchar4 *)p->out; 102 uchar4 *in = (uchar4 *)p->in; 103 uint32_t x1 = xstart; 104 uint32_t x2 = xend; 105 106 in += xstart; 107 out += xstart; 108 109 switch (p->slot) { 110 case BLEND_CLEAR: 111 for (;x1 < x2; x1++, out++) { 112 *out = 0; 113 } 114 break; 115 case BLEND_SRC: 116 for (;x1 < x2; x1++, out++, in++) { 117 *out = *in; 118 } 119 break; 120 //BLEND_DST is a NOP 121 case BLEND_DST: 122 break; 123 case BLEND_SRC_OVER: 124#if defined(ARCH_ARM_HAVE_NEON) 125 if((x1 + 8) < x2) { 126 uint32_t len = (x2 - x1) >> 3; 127 rsdIntrinsicBlendSrcOver_K(out, in, len); 128 x1 += len << 3; 129 out += len << 3; 130 in += len << 3; 131 } 132#endif 133 for (;x1 < x2; x1++, out++, in++) { 134 short4 in_s = convert_short4(*in); 135 short4 out_s = convert_short4(*out); 136 in_s = in_s + ((out_s * (short4)(255 - in_s.a)) >> (short4)8); 137 *out = convert_uchar4(in_s); 138 } 139 break; 140 case BLEND_DST_OVER: 141#if defined(ARCH_ARM_HAVE_NEON) 142 if((x1 + 8) < x2) { 143 uint32_t len = (x2 - x1) >> 3; 144 rsdIntrinsicBlendDstOver_K(out, in, len); 145 x1 += len << 3; 146 out += len << 3; 147 in += len << 3; 148 } 149#endif 150 for (;x1 < x2; x1++, out++, in++) { 151 short4 in_s = convert_short4(*in); 152 short4 out_s = convert_short4(*out); 153 in_s = out_s + ((in_s * (short4)(255 - out_s.a)) >> (short4)8); 154 *out = convert_uchar4(in_s); 155 } 156 break; 157 case BLEND_SRC_IN: 158#if defined(ARCH_ARM_HAVE_NEON) 159 if((x1 + 8) < x2) { 160 uint32_t len = (x2 - x1) >> 3; 161 rsdIntrinsicBlendSrcIn_K(out, in, len); 162 x1 += len << 3; 163 out += len << 3; 164 in += len << 3; 165 } 166#endif 167 for (;x1 < x2; x1++, out++, in++) { 168 short4 in_s = convert_short4(*in); 169 in_s = (in_s * out->a) >> (short4)8; 170 *out = convert_uchar4(in_s); 171 } 172 break; 173 case BLEND_DST_IN: 174#if defined(ARCH_ARM_HAVE_NEON) 175 if((x1 + 8) < x2) { 176 uint32_t len = (x2 - x1) >> 3; 177 rsdIntrinsicBlendDstIn_K(out, in, len); 178 x1 += len << 3; 179 out += len << 3; 180 in += len << 3; 181 } 182#endif 183 for (;x1 < x2; x1++, out++, in++) { 184 short4 out_s = convert_short4(*out); 185 out_s = (out_s * in->a) >> (short4)8; 186 *out = convert_uchar4(out_s); 187 } 188 break; 189 case BLEND_SRC_OUT: 190#if defined(ARCH_ARM_HAVE_NEON) 191 if((x1 + 8) < x2) { 192 uint32_t len = (x2 - x1) >> 3; 193 rsdIntrinsicBlendSrcOut_K(out, in, len); 194 x1 += len << 3; 195 out += len << 3; 196 in += len << 3; 197 } 198#endif 199 for (;x1 < x2; x1++, out++, in++) { 200 short4 in_s = convert_short4(*in); 201 in_s = (in_s * (short4)(255 - out->a)) >> (short4)8; 202 *out = convert_uchar4(in_s); 203 } 204 break; 205 case BLEND_DST_OUT: 206#if defined(ARCH_ARM_HAVE_NEON) 207 if((x1 + 8) < x2) { 208 uint32_t len = (x2 - x1) >> 3; 209 rsdIntrinsicBlendDstOut_K(out, in, len); 210 x1 += len << 3; 211 out += len << 3; 212 in += len << 3; 213 } 214#endif 215 for (;x1 < x2; x1++, out++, in++) { 216 short4 out_s = convert_short4(*out); 217 out_s = (out_s * (short4)(255 - in->a)) >> (short4)8; 218 *out = convert_uchar4(out_s); 219 } 220 break; 221 case BLEND_SRC_ATOP: 222#if defined(ARCH_ARM_HAVE_NEON) 223 if((x1 + 8) < x2) { 224 uint32_t len = (x2 - x1) >> 3; 225 rsdIntrinsicBlendSrcAtop_K(out, in, len); 226 x1 += len << 3; 227 out += len << 3; 228 in += len << 3; 229 } 230#endif 231 for (;x1 < x2; x1++, out++, in++) { 232 short4 in_s = convert_short4(*in); 233 short4 out_s = convert_short4(*out); 234 out_s.rgb = ((in_s.rgb * out_s.a) + 235 (out_s.rgb * ((short3)255 - (short3)in_s.a))) >> (short3)8; 236 *out = convert_uchar4(out_s); 237 } 238 break; 239 case BLEND_DST_ATOP: 240#if defined(ARCH_ARM_HAVE_NEON) 241 if((x1 + 8) < x2) { 242 uint32_t len = (x2 - x1) >> 3; 243 rsdIntrinsicBlendDstAtop_K(out, in, len); 244 x1 += len << 3; 245 out += len << 3; 246 in += len << 3; 247 } 248#endif 249 for (;x1 < x2; x1++, out++, in++) { 250 short4 in_s = convert_short4(*in); 251 short4 out_s = convert_short4(*out); 252 out_s.rgb = ((out_s.rgb * in_s.a) + 253 (in_s.rgb * ((short3)255 - (short3)out_s.a))) >> (short3)8; 254 *out = convert_uchar4(out_s); 255 } 256 break; 257 case BLEND_XOR: 258#if defined(ARCH_ARM_HAVE_NEON) 259 if((x1 + 8) < x2) { 260 uint32_t len = (x2 - x1) >> 3; 261 rsdIntrinsicBlendXor_K(out, in, len); 262 x1 += len << 3; 263 out += len << 3; 264 in += len << 3; 265 } 266#endif 267 for (;x1 < x2; x1++, out++, in++) { 268 *out = *in ^ *out; 269 } 270 break; 271 case BLEND_NORMAL: 272 ALOGE("Called unimplemented blend intrinsic BLEND_NORMAL"); 273 rsAssert(false); 274 break; 275 case BLEND_AVERAGE: 276 ALOGE("Called unimplemented blend intrinsic BLEND_AVERAGE"); 277 rsAssert(false); 278 break; 279 case BLEND_MULTIPLY: 280#if defined(ARCH_ARM_HAVE_NEON) 281 if((x1 + 8) < x2) { 282 uint32_t len = (x2 - x1) >> 3; 283 rsdIntrinsicBlendMultiply_K(out, in, len); 284 x1 += len << 3; 285 out += len << 3; 286 in += len << 3; 287 } 288#endif 289 for (;x1 < x2; x1++, out++, in++) { 290 *out = convert_uchar4((convert_short4(*in) * convert_short4(*out)) 291 >> (short4)8); 292 } 293 break; 294 case BLEND_SCREEN: 295 ALOGE("Called unimplemented blend intrinsic BLEND_SCREEN"); 296 rsAssert(false); 297 break; 298 case BLEND_DARKEN: 299 ALOGE("Called unimplemented blend intrinsic BLEND_DARKEN"); 300 rsAssert(false); 301 break; 302 case BLEND_LIGHTEN: 303 ALOGE("Called unimplemented blend intrinsic BLEND_LIGHTEN"); 304 rsAssert(false); 305 break; 306 case BLEND_OVERLAY: 307 ALOGE("Called unimplemented blend intrinsic BLEND_OVERLAY"); 308 rsAssert(false); 309 break; 310 case BLEND_HARDLIGHT: 311 ALOGE("Called unimplemented blend intrinsic BLEND_HARDLIGHT"); 312 rsAssert(false); 313 break; 314 case BLEND_SOFTLIGHT: 315 ALOGE("Called unimplemented blend intrinsic BLEND_SOFTLIGHT"); 316 rsAssert(false); 317 break; 318 case BLEND_DIFFERENCE: 319 ALOGE("Called unimplemented blend intrinsic BLEND_DIFFERENCE"); 320 rsAssert(false); 321 break; 322 case BLEND_NEGATION: 323 ALOGE("Called unimplemented blend intrinsic BLEND_NEGATION"); 324 rsAssert(false); 325 break; 326 case BLEND_EXCLUSION: 327 ALOGE("Called unimplemented blend intrinsic BLEND_EXCLUSION"); 328 rsAssert(false); 329 break; 330 case BLEND_COLOR_DODGE: 331 ALOGE("Called unimplemented blend intrinsic BLEND_COLOR_DODGE"); 332 rsAssert(false); 333 break; 334 case BLEND_INVERSE_COLOR_DODGE: 335 ALOGE("Called unimplemented blend intrinsic BLEND_INVERSE_COLOR_DODGE"); 336 rsAssert(false); 337 break; 338 case BLEND_SOFT_DODGE: 339 ALOGE("Called unimplemented blend intrinsic BLEND_SOFT_DODGE"); 340 rsAssert(false); 341 break; 342 case BLEND_COLOR_BURN: 343 ALOGE("Called unimplemented blend intrinsic BLEND_COLOR_BURN"); 344 rsAssert(false); 345 break; 346 case BLEND_INVERSE_COLOR_BURN: 347 ALOGE("Called unimplemented blend intrinsic BLEND_INVERSE_COLOR_BURN"); 348 rsAssert(false); 349 break; 350 case BLEND_SOFT_BURN: 351 ALOGE("Called unimplemented blend intrinsic BLEND_SOFT_BURN"); 352 rsAssert(false); 353 break; 354 case BLEND_REFLECT: 355 ALOGE("Called unimplemented blend intrinsic BLEND_REFLECT"); 356 rsAssert(false); 357 break; 358 case BLEND_GLOW: 359 ALOGE("Called unimplemented blend intrinsic BLEND_GLOW"); 360 rsAssert(false); 361 break; 362 case BLEND_FREEZE: 363 ALOGE("Called unimplemented blend intrinsic BLEND_FREEZE"); 364 rsAssert(false); 365 break; 366 case BLEND_HEAT: 367 ALOGE("Called unimplemented blend intrinsic BLEND_HEAT"); 368 rsAssert(false); 369 break; 370 case BLEND_ADD: 371#if defined(ARCH_ARM_HAVE_NEON) 372 if((x1 + 8) < x2) { 373 uint32_t len = (x2 - x1) >> 3; 374 rsdIntrinsicBlendAdd_K(out, in, len); 375 x1 += len << 3; 376 out += len << 3; 377 in += len << 3; 378 } 379#endif 380 for (;x1 < x2; x1++, out++, in++) { 381 uint32_t iR = in->r, iG = in->g, iB = in->b, iA = in->a, 382 oR = out->r, oG = out->g, oB = out->b, oA = out->a; 383 out->r = (oR + iR) > 255 ? 255 : oR + iR; 384 out->g = (oG + iG) > 255 ? 255 : oG + iG; 385 out->b = (oB + iB) > 255 ? 255 : oB + iB; 386 out->a = (oA + iA) > 255 ? 255 : oA + iA; 387 } 388 break; 389 case BLEND_SUBTRACT: 390#if defined(ARCH_ARM_HAVE_NEON) 391 if((x1 + 8) < x2) { 392 uint32_t len = (x2 - x1) >> 3; 393 rsdIntrinsicBlendSub_K(out, in, len); 394 x1 += len << 3; 395 out += len << 3; 396 in += len << 3; 397 } 398#endif 399 for (;x1 < x2; x1++, out++, in++) { 400 int32_t iR = in->r, iG = in->g, iB = in->b, iA = in->a, 401 oR = out->r, oG = out->g, oB = out->b, oA = out->a; 402 out->r = (oR - iR) < 0 ? 0 : oR - iR; 403 out->g = (oG - iG) < 0 ? 0 : oG - iG; 404 out->b = (oB - iB) < 0 ? 0 : oB - iB; 405 out->a = (oA - iA) < 0 ? 0 : oA - iA; 406 } 407 break; 408 case BLEND_STAMP: 409 ALOGE("Called unimplemented blend intrinsic BLEND_STAMP"); 410 rsAssert(false); 411 break; 412 case BLEND_RED: 413 ALOGE("Called unimplemented blend intrinsic BLEND_RED"); 414 rsAssert(false); 415 break; 416 case BLEND_GREEN: 417 ALOGE("Called unimplemented blend intrinsic BLEND_GREEN"); 418 rsAssert(false); 419 break; 420 case BLEND_BLUE: 421 ALOGE("Called unimplemented blend intrinsic BLEND_BLUE"); 422 rsAssert(false); 423 break; 424 case BLEND_HUE: 425 ALOGE("Called unimplemented blend intrinsic BLEND_HUE"); 426 rsAssert(false); 427 break; 428 case BLEND_SATURATION: 429 ALOGE("Called unimplemented blend intrinsic BLEND_SATURATION"); 430 rsAssert(false); 431 break; 432 case BLEND_COLOR: 433 ALOGE("Called unimplemented blend intrinsic BLEND_COLOR"); 434 rsAssert(false); 435 break; 436 case BLEND_LUMINOSITY: 437 ALOGE("Called unimplemented blend intrinsic BLEND_LUMINOSITY"); 438 rsAssert(false); 439 break; 440 441 default: 442 ALOGE("Called unimplemented value %d", p->slot); 443 rsAssert(false); 444 445 } 446} 447 448void * rsdIntrinsic_InitBlend(const android::renderscript::Context *dc, 449 android::renderscript::Script *script, 450 RsdIntriniscFuncs_t *funcs) { 451 452 script->mHal.info.exportedVariableCount = 0; 453 funcs->root = ColorMatrix_uchar4; 454 455 ConvolveParams *cp = (ConvolveParams *)calloc(1, sizeof(ConvolveParams)); 456 return cp; 457} 458 459 460