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