• 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     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 
rsdIntrinsic_InitBlend(const android::renderscript::Context * dc,android::renderscript::Script * script,RsdIntriniscFuncs_t * funcs)448 void * 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