blob: 7546b38373f6c869e4f6a31c4e75a077d8d9eca0 [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
Tim Murray0b575de2013-03-15 15:56:43 -070095 return (uchar4){p.x, p.y, p.z, p.w};
Jason Sams709a0972012-11-15 18:18:04 -080096}
97
98
99static short YuvCoeff[] = {
100 298, 409, -100, 516, -208, 255, 0, 0,
101 16, 16, 16, 16, 16, 16, 16, 16,
102 128, 128, 128, 128, 128, 128, 128, 128,
103 298, 298, 298, 298, 298, 298, 298, 298,
104 255, 255, 255, 255, 255, 255, 255, 255
105
106
107};
108
109extern "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 -0700110extern "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 -0700111extern "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 -0800112
113void RsdCpuScriptIntrinsicYuvToRGB::kernel(const RsForEachStubParamStruct *p,
114 uint32_t xstart, uint32_t xend,
115 uint32_t instep, uint32_t outstep) {
116 RsdCpuScriptIntrinsicYuvToRGB *cp = (RsdCpuScriptIntrinsicYuvToRGB *)p->usr;
117 if (!cp->alloc.get()) {
118 ALOGE("YuvToRGB executed without input, skipping");
119 return;
120 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800121 const uchar *pinY = (const uchar *)cp->alloc->mHal.drvState.lod[0].mallocPtr;
Tim Murray606e5002013-06-13 12:33:49 -0700122
123 size_t strideY = cp->alloc->mHal.drvState.lod[0].stride;
124
125 // calculate correct stride in legacy case
126 if (cp->alloc->mHal.drvState.lod[0].dimY == 0) {
127 strideY = p->dimX;
128 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800129 const uchar *Y = pinY + (p->y * strideY);
Jason Sams709a0972012-11-15 18:18:04 -0800130
Tim Murray606e5002013-06-13 12:33:49 -0700131 // ALOGE("pinY, %p, Y, %p, p->y, %d, strideY, %d", pinY, Y, p->y, strideY);
132 // ALOGE("dimX, %d, dimY, %d", cp->alloc->mHal.drvState.lod[0].dimX, cp->alloc->mHal.drvState.lod[0].dimY);
133 // ALOGE("p->dimX, %d, p->dimY, %d", p->dimX, p->dimY);
134
Jason Sams709a0972012-11-15 18:18:04 -0800135 uchar4 *out = (uchar4 *)p->out;
136 uint32_t x1 = xstart;
137 uint32_t x2 = xend;
138
Jason Sams61656a72013-09-03 16:21:18 -0700139 const size_t cstep = cp->alloc->mHal.drvState.yuv.step;
Jason Sams709a0972012-11-15 18:18:04 -0800140
Jason Sams61656a72013-09-03 16:21:18 -0700141 const uchar *pinU = (const uchar *)cp->alloc->mHal.drvState.lod[1].mallocPtr;
142 const size_t strideU = cp->alloc->mHal.drvState.lod[1].stride;
143 const uchar *u = pinU + ((p->y >> 1) * strideU);
Jason Sams06bd91e2013-06-11 18:38:11 -0700144
Jason Sams61656a72013-09-03 16:21:18 -0700145 const uchar *pinV = (const uchar *)cp->alloc->mHal.drvState.lod[2].mallocPtr;
146 const size_t strideV = cp->alloc->mHal.drvState.lod[2].stride;
147 const uchar *v = pinV + ((p->y >> 1) * strideV);
148
149 if (pinU == NULL) {
150 // Legacy yuv support didn't fill in uv
151 v = ((uint8_t *)cp->alloc->mHal.drvState.lod[0].mallocPtr) +
152 (strideY * p->dimY) +
153 ((p->y >> 1) * strideY);
154 u = v + 1;
155 }
156
157#if defined(ARCH_ARM_HAVE_VFP)
158 if((x2 > x1) && gArchUseSIMD) {
159 int32_t len = (x2 - x1 - 1) >> 3;
160 if(len > 0) {
161 if (cstep == 1) {
162 rsdIntrinsicYuv2_K(out, Y, u, v, len, YuvCoeff);
163 x1 += len << 3;
164 out += len << 3;
165 } else if (cstep == 2) {
166 // Check for proper interleave
167 intptr_t ipu = (intptr_t)u;
168 intptr_t ipv = (intptr_t)v;
169
170 if (ipu == (ipv + 1)) {
171 rsdIntrinsicYuv_K(out, Y, v, len, YuvCoeff);
172 x1 += len << 3;
173 out += len << 3;
174 } else if (ipu == (ipv - 1)) {
175 rsdIntrinsicYuvR_K(out, Y, u, len, YuvCoeff);
176 x1 += len << 3;
177 out += len << 3;
Jason Sams6b589092013-04-19 14:32:31 -0700178 }
Jason Sams6b589092013-04-19 14:32:31 -0700179
Jason Sams6b589092013-04-19 14:32:31 -0700180 }
Jason Sams709a0972012-11-15 18:18:04 -0800181 }
Jason Sams61656a72013-09-03 16:21:18 -0700182 }
Jason Sams6b589092013-04-19 14:32:31 -0700183#endif
Jason Sams61656a72013-09-03 16:21:18 -0700184
185 if(x2 > x1) {
186 // ALOGE("y %i %i %i", p->y, x1, x2);
187 while(x1 < x2) {
188 int cx = (x1 >> 1) * cstep;
189 *out = rsYuvToRGBA_uchar4(Y[x1], u[cx], v[cx]);
190 out++;
191 x1++;
192 *out = rsYuvToRGBA_uchar4(Y[x1], u[cx], v[cx]);
193 out++;
194 x1++;
195 }
Jason Sams709a0972012-11-15 18:18:04 -0800196 }
Jason Sams6b589092013-04-19 14:32:31 -0700197
Jason Sams709a0972012-11-15 18:18:04 -0800198}
199
200RsdCpuScriptIntrinsicYuvToRGB::RsdCpuScriptIntrinsicYuvToRGB(
Jason Samsc905efd2012-11-26 15:20:18 -0800201 RsdCpuReferenceImpl *ctx, const Script *s, const Element *e)
202 : RsdCpuScriptIntrinsic(ctx, s, e, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB) {
Jason Sams709a0972012-11-15 18:18:04 -0800203
204 mRootPtr = &kernel;
205}
206
207RsdCpuScriptIntrinsicYuvToRGB::~RsdCpuScriptIntrinsicYuvToRGB() {
208}
209
210void RsdCpuScriptIntrinsicYuvToRGB::populateScript(Script *s) {
211 s->mHal.info.exportedVariableCount = 1;
212}
213
214void RsdCpuScriptIntrinsicYuvToRGB::invokeFreeChildren() {
215 alloc.clear();
216}
217
218
Jason Samsc905efd2012-11-26 15:20:18 -0800219RsdCpuScriptImpl * rsdIntrinsic_YuvToRGB(RsdCpuReferenceImpl *ctx,
220 const Script *s, const Element *e) {
221 return new RsdCpuScriptIntrinsicYuvToRGB(ctx, s, e);
Jason Sams709a0972012-11-15 18:18:04 -0800222}
223
224