blob: 22f0962cd38dabc8285e2cc35a6c0d537e58a806 [file] [log] [blame]
Jason Sams709a0972012-11-15 18:18:04 -08001/*
Jason Samsbc0ca6b2013-02-15 18:13:43 -08002 * Copyright (C) 2013 The Android Open Source Project
Jason Sams709a0972012-11-15 18:18:04 -08003 *
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 "rsCpuIntrinsic.h"
19#include "rsCpuIntrinsicInlines.h"
20
Tim Murrayaa782372013-08-29 18:42:54 -070021#ifdef RS_COMPATIBILITY_LIB
22#include "rsCompatibilityLib.h"
23#endif
24
Jason Sams6b589092013-04-19 14:32:31 -070025#ifndef RS_COMPATIBILITY_LIB
26#include "hardware/gralloc.h"
27#endif
28
Jason Sams709a0972012-11-15 18:18:04 -080029using namespace android;
30using namespace android::renderscript;
31
32namespace android {
33namespace renderscript {
34
35
36class RsdCpuScriptIntrinsicYuvToRGB : public RsdCpuScriptIntrinsic {
37public:
38 virtual void populateScript(Script *);
39 virtual void invokeFreeChildren();
40
41 virtual void setGlobalObj(uint32_t slot, ObjectBase *data);
42
43 virtual ~RsdCpuScriptIntrinsicYuvToRGB();
Jason Samsc905efd2012-11-26 15:20:18 -080044 RsdCpuScriptIntrinsicYuvToRGB(RsdCpuReferenceImpl *ctx, const Script *s, const Element *e);
Jason Sams709a0972012-11-15 18:18:04 -080045
46protected:
47 ObjectBaseRef<Allocation> alloc;
48
49 static void kernel(const RsForEachStubParamStruct *p,
50 uint32_t xstart, uint32_t xend,
51 uint32_t instep, uint32_t outstep);
52};
53
54}
55}
56
57
58void RsdCpuScriptIntrinsicYuvToRGB::setGlobalObj(uint32_t slot, ObjectBase *data) {
59 rsAssert(slot == 0);
60 alloc.set(static_cast<Allocation *>(data));
61}
62
63
64
65
66static uchar4 rsYuvToRGBA_uchar4(uchar y, uchar u, uchar v) {
67 short Y = ((short)y) - 16;
68 short U = ((short)u) - 128;
69 short V = ((short)v) - 128;
70
71 short4 p;
Tim Murray0b575de2013-03-15 15:56:43 -070072 p.x = (Y * 298 + V * 409 + 128) >> 8;
73 p.y = (Y * 298 - U * 100 - V * 208 + 128) >> 8;
74 p.z = (Y * 298 + U * 516 + 128) >> 8;
75 p.w = 255;
76 if(p.x < 0) {
77 p.x = 0;
Jason Sams709a0972012-11-15 18:18:04 -080078 }
Tim Murray0b575de2013-03-15 15:56:43 -070079 if(p.x > 255) {
80 p.x = 255;
Jason Sams709a0972012-11-15 18:18:04 -080081 }
Tim Murray0b575de2013-03-15 15:56:43 -070082 if(p.y < 0) {
83 p.y = 0;
Jason Sams709a0972012-11-15 18:18:04 -080084 }
Tim Murray0b575de2013-03-15 15:56:43 -070085 if(p.y > 255) {
86 p.y = 255;
Jason Sams709a0972012-11-15 18:18:04 -080087 }
Tim Murray0b575de2013-03-15 15:56:43 -070088 if(p.z < 0) {
89 p.z = 0;
Jason Sams709a0972012-11-15 18:18:04 -080090 }
Tim Murray0b575de2013-03-15 15:56:43 -070091 if(p.z > 255) {
92 p.z = 255;
Jason Sams709a0972012-11-15 18:18:04 -080093 }
94
synergy dev8994abb2013-12-05 00:24:37 -080095 return (uchar4){static_cast<uchar>(p.x), static_cast<uchar>(p.y),
96 static_cast<uchar>(p.z), static_cast<uchar>(p.w)};
Jason Sams709a0972012-11-15 18:18:04 -080097}
98
99
100static short YuvCoeff[] = {
101 298, 409, -100, 516, -208, 255, 0, 0,
102 16, 16, 16, 16, 16, 16, 16, 16,
103 128, 128, 128, 128, 128, 128, 128, 128,
104 298, 298, 298, 298, 298, 298, 298, 298,
105 255, 255, 255, 255, 255, 255, 255, 255
106
107
108};
109
110extern "C" void rsdIntrinsicYuv_K(void *dst, const uchar *Y, const uchar *uv, uint32_t count, const short *param);
Jason Sams61656a72013-09-03 16:21:18 -0700111extern "C" void rsdIntrinsicYuvR_K(void *dst, const uchar *Y, const uchar *uv, uint32_t count, const short *param);
Jason Sams6b589092013-04-19 14:32:31 -0700112extern "C" void rsdIntrinsicYuv2_K(void *dst, const uchar *Y, const uchar *u, const uchar *v, uint32_t count, const short *param);
Jason Sams709a0972012-11-15 18:18:04 -0800113
114void RsdCpuScriptIntrinsicYuvToRGB::kernel(const RsForEachStubParamStruct *p,
115 uint32_t xstart, uint32_t xend,
116 uint32_t instep, uint32_t outstep) {
117 RsdCpuScriptIntrinsicYuvToRGB *cp = (RsdCpuScriptIntrinsicYuvToRGB *)p->usr;
118 if (!cp->alloc.get()) {
119 ALOGE("YuvToRGB executed without input, skipping");
120 return;
121 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800122 const uchar *pinY = (const uchar *)cp->alloc->mHal.drvState.lod[0].mallocPtr;
Jason Samse99f3e22013-09-11 18:18:54 -0700123 if (pinY == NULL) {
124 ALOGE("YuvToRGB executed without data, skipping");
125 return;
126 }
Tim Murray606e5002013-06-13 12:33:49 -0700127
128 size_t strideY = cp->alloc->mHal.drvState.lod[0].stride;
129
130 // calculate correct stride in legacy case
131 if (cp->alloc->mHal.drvState.lod[0].dimY == 0) {
132 strideY = p->dimX;
133 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800134 const uchar *Y = pinY + (p->y * strideY);
Jason Sams709a0972012-11-15 18:18:04 -0800135
136 uchar4 *out = (uchar4 *)p->out;
137 uint32_t x1 = xstart;
138 uint32_t x2 = xend;
139
Jason Sams0052f8d2013-09-19 17:27:29 -0700140 size_t cstep = cp->alloc->mHal.drvState.yuv.step;
Jason Sams709a0972012-11-15 18:18:04 -0800141
Jason Sams61656a72013-09-03 16:21:18 -0700142 const uchar *pinU = (const uchar *)cp->alloc->mHal.drvState.lod[1].mallocPtr;
143 const size_t strideU = cp->alloc->mHal.drvState.lod[1].stride;
144 const uchar *u = pinU + ((p->y >> 1) * strideU);
Jason Sams06bd91e2013-06-11 18:38:11 -0700145
Jason Sams61656a72013-09-03 16:21:18 -0700146 const uchar *pinV = (const uchar *)cp->alloc->mHal.drvState.lod[2].mallocPtr;
147 const size_t strideV = cp->alloc->mHal.drvState.lod[2].stride;
148 const uchar *v = pinV + ((p->y >> 1) * strideV);
149
Jason Sams0052f8d2013-09-19 17:27:29 -0700150 //ALOGE("pinY, %p, Y, %p, p->y, %d, strideY, %d", pinY, Y, p->y, strideY);
151 //ALOGE("pinU, %p, U, %p, p->y, %d, strideU, %d", pinU, u, p->y, strideU);
152 //ALOGE("pinV, %p, V, %p, p->y, %d, strideV, %d", pinV, v, p->y, strideV);
153 //ALOGE("dimX, %d, dimY, %d", cp->alloc->mHal.drvState.lod[0].dimX, cp->alloc->mHal.drvState.lod[0].dimY);
154 //ALOGE("p->dimX, %d, p->dimY, %d", p->dimX, p->dimY);
155
Jason Sams61656a72013-09-03 16:21:18 -0700156 if (pinU == NULL) {
157 // Legacy yuv support didn't fill in uv
158 v = ((uint8_t *)cp->alloc->mHal.drvState.lod[0].mallocPtr) +
159 (strideY * p->dimY) +
160 ((p->y >> 1) * strideY);
161 u = v + 1;
Jason Sams0052f8d2013-09-19 17:27:29 -0700162 cstep = 2;
Jason Sams61656a72013-09-03 16:21:18 -0700163 }
164
165#if defined(ARCH_ARM_HAVE_VFP)
166 if((x2 > x1) && gArchUseSIMD) {
Jason Sams4a1495f2013-09-30 13:11:26 -0700167 // The neon paths may over-read by up to 8 bytes
168 int32_t len = (x2 - x1 - 8) >> 3;
Jason Sams61656a72013-09-03 16:21:18 -0700169 if(len > 0) {
170 if (cstep == 1) {
171 rsdIntrinsicYuv2_K(out, Y, u, v, len, YuvCoeff);
172 x1 += len << 3;
173 out += len << 3;
174 } else if (cstep == 2) {
175 // Check for proper interleave
176 intptr_t ipu = (intptr_t)u;
177 intptr_t ipv = (intptr_t)v;
178
179 if (ipu == (ipv + 1)) {
180 rsdIntrinsicYuv_K(out, Y, v, len, YuvCoeff);
181 x1 += len << 3;
182 out += len << 3;
183 } else if (ipu == (ipv - 1)) {
184 rsdIntrinsicYuvR_K(out, Y, u, len, YuvCoeff);
185 x1 += len << 3;
186 out += len << 3;
Jason Sams6b589092013-04-19 14:32:31 -0700187 }
Jason Sams6b589092013-04-19 14:32:31 -0700188
Jason Sams6b589092013-04-19 14:32:31 -0700189 }
Jason Sams709a0972012-11-15 18:18:04 -0800190 }
Jason Sams61656a72013-09-03 16:21:18 -0700191 }
Jason Sams6b589092013-04-19 14:32:31 -0700192#endif
Jason Sams61656a72013-09-03 16:21:18 -0700193
194 if(x2 > x1) {
195 // ALOGE("y %i %i %i", p->y, x1, x2);
196 while(x1 < x2) {
197 int cx = (x1 >> 1) * cstep;
198 *out = rsYuvToRGBA_uchar4(Y[x1], u[cx], v[cx]);
199 out++;
200 x1++;
201 *out = rsYuvToRGBA_uchar4(Y[x1], u[cx], v[cx]);
202 out++;
203 x1++;
204 }
Jason Sams709a0972012-11-15 18:18:04 -0800205 }
Jason Sams6b589092013-04-19 14:32:31 -0700206
Jason Sams709a0972012-11-15 18:18:04 -0800207}
208
209RsdCpuScriptIntrinsicYuvToRGB::RsdCpuScriptIntrinsicYuvToRGB(
Jason Samsc905efd2012-11-26 15:20:18 -0800210 RsdCpuReferenceImpl *ctx, const Script *s, const Element *e)
211 : RsdCpuScriptIntrinsic(ctx, s, e, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB) {
Jason Sams709a0972012-11-15 18:18:04 -0800212
213 mRootPtr = &kernel;
214}
215
216RsdCpuScriptIntrinsicYuvToRGB::~RsdCpuScriptIntrinsicYuvToRGB() {
217}
218
219void RsdCpuScriptIntrinsicYuvToRGB::populateScript(Script *s) {
220 s->mHal.info.exportedVariableCount = 1;
221}
222
223void RsdCpuScriptIntrinsicYuvToRGB::invokeFreeChildren() {
224 alloc.clear();
225}
226
227
Jason Samsc905efd2012-11-26 15:20:18 -0800228RsdCpuScriptImpl * rsdIntrinsic_YuvToRGB(RsdCpuReferenceImpl *ctx,
229 const Script *s, const Element *e) {
230 return new RsdCpuScriptIntrinsicYuvToRGB(ctx, s, e);
Jason Sams709a0972012-11-15 18:18:04 -0800231}
232
233