rsdIntrinsicBlend.cpp revision 36889a0ecf564e3d47e7f69bb030c6b927061792
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 32static void One(const RsForEachStubParamStruct *p, uchar4 *out, 33 const uchar4 *py, const float* coeff) { 34 float4 i = convert_float4(py[0]); 35 36 float4 sum; 37 sum.x = i.x * coeff[0] + 38 i.y * coeff[4] + 39 i.z * coeff[8] + 40 i.w * coeff[12]; 41 sum.y = i.x * coeff[1] + 42 i.y * coeff[5] + 43 i.z * coeff[9] + 44 i.w * coeff[13]; 45 sum.z = i.x * coeff[2] + 46 i.y * coeff[6] + 47 i.z * coeff[10] + 48 i.w * coeff[14]; 49 sum.w = i.x * coeff[3] + 50 i.y * coeff[7] + 51 i.z * coeff[11] + 52 i.w * coeff[15]; 53 54 sum.x = sum.x < 0 ? 0 : (sum.x > 255 ? 255 : sum.x); 55 sum.y = sum.y < 0 ? 0 : (sum.y > 255 ? 255 : sum.y); 56 sum.z = sum.z < 0 ? 0 : (sum.z > 255 ? 255 : sum.z); 57 sum.w = sum.w < 0 ? 0 : (sum.w > 255 ? 255 : sum.w); 58 59 *out = convert_uchar4(sum); 60} 61 62enum { 63 BLEND_CLEAR = 0, 64 BLEND_SRC = 1, 65 BLEND_DST = 2, 66 BLEND_SRC_OVER = 3, 67 BLEND_DST_OVER = 4, 68 BLEND_SRC_IN = 5, 69 BLEND_DST_IN = 6, 70 BLEND_SRC_OUT = 7, 71 BLEND_DST_OUT = 8, 72 BLEND_SRC_ATOP = 9, 73 BLEND_DST_ATOP = 10, 74 BLEND_XOR = 11, 75 76 BLEND_NORMAL = 12, 77 BLEND_AVERAGE = 13, 78 BLEND_MULTIPLY = 14, 79 BLEND_SCREEN = 15, 80 BLEND_DARKEN = 16, 81 BLEND_LIGHTEN = 17, 82 BLEND_OVERLAY = 18, 83 BLEND_HARDLIGHT = 19, 84 BLEND_SOFTLIGHT = 20, 85 BLEND_DIFFERENCE = 21, 86 BLEND_NEGATION = 22, 87 BLEND_EXCLUSION = 23, 88 BLEND_COLOR_DODGE = 24, 89 BLEND_INVERSE_COLOR_DODGE = 25, 90 BLEND_SOFT_DODGE = 26, 91 BLEND_COLOR_BURN = 27, 92 BLEND_INVERSE_COLOR_BURN = 28, 93 BLEND_SOFT_BURN = 29, 94 BLEND_REFLECT = 30, 95 BLEND_GLOW = 31, 96 BLEND_FREEZE = 32, 97 BLEND_HEAT = 33, 98 BLEND_ADD = 34, 99 BLEND_SUBTRACT = 35, 100 BLEND_STAMP = 36, 101 BLEND_RED = 37, 102 BLEND_GREEN = 38, 103 BLEND_BLUE = 39, 104 BLEND_HUE = 40, 105 BLEND_SATURATION = 41, 106 BLEND_COLOR = 42, 107 BLEND_LUMINOSITY = 43 108}; 109 110static void ColorMatrix_uchar4(const RsForEachStubParamStruct *p, 111 uint32_t xstart, uint32_t xend, 112 uint32_t instep, uint32_t outstep) { 113 ConvolveParams *cp = (ConvolveParams *)p->usr; 114 115 // instep/outstep can be ignored--sizeof(uchar4) known at compile time 116 uchar4 *out = (uchar4 *)p->out; 117 uchar4 *in = (uchar4 *)p->in; 118 uint32_t x1 = xstart; 119 uint32_t x2 = xend; 120 121 in += xstart; 122 out += xstart; 123 124 switch (p->slot) { 125 case BLEND_CLEAR: 126 for (;x1 < x2; x1++, out++) { 127 *out = 0; 128 } 129 break; 130 case BLEND_SRC: 131 for (;x1 < x2; x1++, out++, in++) { 132 *out = *in; 133 } 134 break; 135 //BLEND_DST is a NOP 136 case BLEND_DST: 137 break; 138 case BLEND_SRC_OVER: 139 for (;x1 < x2; x1++, out++, in++) { 140 short4 in_s = convert_short4(*in); 141 short4 out_s = convert_short4(*out); 142 in_s = in_s + ((out_s * (short4)(255 - in_s.a)) >> (short4)8); 143 *out = convert_uchar4(in_s); 144 } 145 break; 146 case BLEND_DST_OVER: 147 for (;x1 < x2; x1++, out++, in++) { 148 short4 in_s = convert_short4(*in); 149 short4 out_s = convert_short4(*out); 150 in_s = out_s + ((in_s * (short4)(255 - out_s.a)) >> (short4)8); 151 *out = convert_uchar4(in_s); 152 } 153 break; 154 case BLEND_SRC_IN: 155 for (;x1 < x2; x1++, out++, in++) { 156 short4 in_s = convert_short4(*in); 157 in_s = (in_s * out->a) >> (short4)8; 158 *out = convert_uchar4(in_s); 159 } 160 break; 161 case BLEND_DST_IN: 162 for (;x1 < x2; x1++, out++, in++) { 163 short4 out_s = convert_short4(*out); 164 out_s = (out_s * in->a) >> (short4)8; 165 *out = convert_uchar4(out_s); 166 } 167 break; 168 case BLEND_SRC_OUT: 169 for (;x1 < x2; x1++, out++, in++) { 170 short4 in_s = convert_short4(*in); 171 in_s = (in_s * (short4)(255 - out->a)) >> (short4)8; 172 *out = convert_uchar4(in_s); 173 } 174 break; 175 case BLEND_DST_OUT: 176 for (;x1 < x2; x1++, out++, in++) { 177 short4 out_s = convert_short4(*out); 178 out_s = (out_s * (short4)(255 - in->a)) >> (short4)8; 179 *out = convert_uchar4(out_s); 180 } 181 break; 182 case BLEND_SRC_ATOP: 183 for (;x1 < x2; x1++, out++, in++) { 184 short4 in_s = convert_short4(*in); 185 short4 out_s = convert_short4(*out); 186 out_s.rgb = ((in_s.rgb * out_s.a) >> (short3)8) + 187 ((out_s.rgb * ((short3)255 - (short3)in_s.a)) >> (short3)8); 188 *out = convert_uchar4(out_s); 189 } 190 break; 191 case BLEND_DST_ATOP: 192 for (;x1 < x2; x1++, out++, in++) { 193 short4 in_s = convert_short4(*in); 194 short4 out_s = convert_short4(*out); 195 out_s.rgb = ((out_s.rgb * in_s.a) >> (short3)8) + 196 ((in_s.rgb * ((short3)255 - (short3)out_s.a)) >> (short3)8); 197 *out = convert_uchar4(out_s); 198 } 199 break; 200 case BLEND_XOR: 201 for (;x1 < x2; x1++, out++, in++) { 202 *out = *in ^ *out; 203 } 204 break; 205 case BLEND_NORMAL: 206 ALOGE("Called unimplemented blend intrinsic BLEND_NORMAL"); 207 rsAssert(false); 208 break; 209 case BLEND_AVERAGE: 210 ALOGE("Called unimplemented blend intrinsic BLEND_AVERAGE"); 211 rsAssert(false); 212 break; 213 case BLEND_MULTIPLY: 214 for (;x1 < x2; x1++, out++, in++) { 215 *out = convert_uchar4((convert_short4(*in) * convert_short4(*out)) 216 >> (short4)8); 217 } 218 break; 219 case BLEND_SCREEN: 220 ALOGE("Called unimplemented blend intrinsic BLEND_SCREEN"); 221 rsAssert(false); 222 break; 223 case BLEND_DARKEN: 224 ALOGE("Called unimplemented blend intrinsic BLEND_DARKEN"); 225 rsAssert(false); 226 break; 227 case BLEND_LIGHTEN: 228 ALOGE("Called unimplemented blend intrinsic BLEND_LIGHTEN"); 229 rsAssert(false); 230 break; 231 case BLEND_OVERLAY: 232 ALOGE("Called unimplemented blend intrinsic BLEND_OVERLAY"); 233 rsAssert(false); 234 break; 235 case BLEND_HARDLIGHT: 236 ALOGE("Called unimplemented blend intrinsic BLEND_HARDLIGHT"); 237 rsAssert(false); 238 break; 239 case BLEND_SOFTLIGHT: 240 ALOGE("Called unimplemented blend intrinsic BLEND_SOFTLIGHT"); 241 rsAssert(false); 242 break; 243 case BLEND_DIFFERENCE: 244 ALOGE("Called unimplemented blend intrinsic BLEND_DIFFERENCE"); 245 rsAssert(false); 246 break; 247 case BLEND_NEGATION: 248 ALOGE("Called unimplemented blend intrinsic BLEND_NEGATION"); 249 rsAssert(false); 250 break; 251 case BLEND_EXCLUSION: 252 ALOGE("Called unimplemented blend intrinsic BLEND_EXCLUSION"); 253 rsAssert(false); 254 break; 255 case BLEND_COLOR_DODGE: 256 ALOGE("Called unimplemented blend intrinsic BLEND_COLOR_DODGE"); 257 rsAssert(false); 258 break; 259 case BLEND_INVERSE_COLOR_DODGE: 260 ALOGE("Called unimplemented blend intrinsic BLEND_INVERSE_COLOR_DODGE"); 261 rsAssert(false); 262 break; 263 case BLEND_SOFT_DODGE: 264 ALOGE("Called unimplemented blend intrinsic BLEND_SOFT_DODGE"); 265 rsAssert(false); 266 break; 267 case BLEND_COLOR_BURN: 268 ALOGE("Called unimplemented blend intrinsic BLEND_COLOR_BURN"); 269 rsAssert(false); 270 break; 271 case BLEND_INVERSE_COLOR_BURN: 272 ALOGE("Called unimplemented blend intrinsic BLEND_INVERSE_COLOR_BURN"); 273 rsAssert(false); 274 break; 275 case BLEND_SOFT_BURN: 276 ALOGE("Called unimplemented blend intrinsic BLEND_SOFT_BURN"); 277 rsAssert(false); 278 break; 279 case BLEND_REFLECT: 280 ALOGE("Called unimplemented blend intrinsic BLEND_REFLECT"); 281 rsAssert(false); 282 break; 283 case BLEND_GLOW: 284 ALOGE("Called unimplemented blend intrinsic BLEND_GLOW"); 285 rsAssert(false); 286 break; 287 case BLEND_FREEZE: 288 ALOGE("Called unimplemented blend intrinsic BLEND_FREEZE"); 289 rsAssert(false); 290 break; 291 case BLEND_HEAT: 292 ALOGE("Called unimplemented blend intrinsic BLEND_HEAT"); 293 rsAssert(false); 294 break; 295 case BLEND_ADD: 296 for (;x1 < x2; x1++, out++, in++) { 297 uint32_t iR = in->r, iG = in->g, iB = in->b, iA = in->a, 298 oR = out->r, oG = out->g, oB = out->b, oA = out->a; 299 out->r = (oR + iR) > 255 ? 255 : oR + iR; 300 out->g = (oG + iG) > 255 ? 255 : oG + iG; 301 out->b = (oB + iB) > 255 ? 255 : oB + iB; 302 out->a = (oA + iA) > 255 ? 255 : oA + iA; 303 } 304 break; 305 case BLEND_SUBTRACT: 306 for (;x1 < x2; x1++, out++, in++) { 307 int32_t iR = in->r, iG = in->g, iB = in->b, iA = in->a, 308 oR = out->r, oG = out->g, oB = out->b, oA = out->a; 309 out->r = (oR - iR) < 0 ? 0 : oR - iR; 310 out->g = (oG - iG) < 0 ? 0 : oG - iG; 311 out->b = (oB - iB) < 0 ? 0 : oB - iB; 312 out->a = (oA - iA) < 0 ? 0 : oA - iA; 313 } 314 break; 315 case BLEND_STAMP: 316 ALOGE("Called unimplemented blend intrinsic BLEND_STAMP"); 317 rsAssert(false); 318 break; 319 case BLEND_RED: 320 ALOGE("Called unimplemented blend intrinsic BLEND_RED"); 321 rsAssert(false); 322 break; 323 case BLEND_GREEN: 324 ALOGE("Called unimplemented blend intrinsic BLEND_GREEN"); 325 rsAssert(false); 326 break; 327 case BLEND_BLUE: 328 ALOGE("Called unimplemented blend intrinsic BLEND_BLUE"); 329 rsAssert(false); 330 break; 331 case BLEND_HUE: 332 ALOGE("Called unimplemented blend intrinsic BLEND_HUE"); 333 rsAssert(false); 334 break; 335 case BLEND_SATURATION: 336 ALOGE("Called unimplemented blend intrinsic BLEND_SATURATION"); 337 rsAssert(false); 338 break; 339 case BLEND_COLOR: 340 ALOGE("Called unimplemented blend intrinsic BLEND_COLOR"); 341 rsAssert(false); 342 break; 343 case BLEND_LUMINOSITY: 344 ALOGE("Called unimplemented blend intrinsic BLEND_LUMINOSITY"); 345 rsAssert(false); 346 break; 347 348 default: 349 ALOGE("Called unimplemented value %d", p->slot); 350 rsAssert(false); 351 352 } 353 354 if(x2 > x1) { 355 while(x1 != x2) { 356 One(p, out++, in++, cp->f); 357 x1++; 358 } 359 } 360} 361 362void * rsdIntrinsic_InitBlend(const android::renderscript::Context *dc, 363 android::renderscript::Script *script, 364 RsdIntriniscFuncs_t *funcs) { 365 366 script->mHal.info.exportedVariableCount = 0; 367 funcs->root = ColorMatrix_uchar4; 368 369 ConvolveParams *cp = (ConvolveParams *)calloc(1, sizeof(ConvolveParams)); 370 return cp; 371} 372 373 374