blob: 732a245a5e241505a1d8b7b19d995e6c3b65a5e4 [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;
Jason Samse99f3e22013-09-11 18:18:54 -0700122 if (pinY == NULL) {
123 ALOGE("YuvToRGB executed without data, skipping");
124 return;
125 }
Tim Murray606e5002013-06-13 12:33:49 -0700126
127 size_t strideY = cp->alloc->mHal.drvState.lod[0].stride;
128
129 // calculate correct stride in legacy case
130 if (cp->alloc->mHal.drvState.lod[0].dimY == 0) {
131 strideY = p->dimX;
132 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800133 const uchar *Y = pinY + (p->y * strideY);
Jason Sams709a0972012-11-15 18:18:04 -0800134
135 uchar4 *out = (uchar4 *)p->out;
136 uint32_t x1 = xstart;
137 uint32_t x2 = xend;
138
Jason Sams0052f8d2013-09-19 17:27:29 -0700139 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
Jason Sams0052f8d2013-09-19 17:27:29 -0700149 //ALOGE("pinY, %p, Y, %p, p->y, %d, strideY, %d", pinY, Y, p->y, strideY);
150 //ALOGE("pinU, %p, U, %p, p->y, %d, strideU, %d", pinU, u, p->y, strideU);
151 //ALOGE("pinV, %p, V, %p, p->y, %d, strideV, %d", pinV, v, p->y, strideV);
152 //ALOGE("dimX, %d, dimY, %d", cp->alloc->mHal.drvState.lod[0].dimX, cp->alloc->mHal.drvState.lod[0].dimY);
153 //ALOGE("p->dimX, %d, p->dimY, %d", p->dimX, p->dimY);
154
Jason Sams61656a72013-09-03 16:21:18 -0700155 if (pinU == NULL) {
156 // Legacy yuv support didn't fill in uv
157 v = ((uint8_t *)cp->alloc->mHal.drvState.lod[0].mallocPtr) +
158 (strideY * p->dimY) +
159 ((p->y >> 1) * strideY);
160 u = v + 1;
Jason Sams0052f8d2013-09-19 17:27:29 -0700161 cstep = 2;
Jason Sams61656a72013-09-03 16:21:18 -0700162 }
163
164#if defined(ARCH_ARM_HAVE_VFP)
165 if((x2 > x1) && gArchUseSIMD) {
Jason Sams0052f8d2013-09-19 17:27:29 -0700166 int32_t len = (x2 - x1) >> 3;
Jason Sams61656a72013-09-03 16:21:18 -0700167 if(len > 0) {
168 if (cstep == 1) {
169 rsdIntrinsicYuv2_K(out, Y, u, v, len, YuvCoeff);
170 x1 += len << 3;
171 out += len << 3;
172 } else if (cstep == 2) {
173 // Check for proper interleave
174 intptr_t ipu = (intptr_t)u;
175 intptr_t ipv = (intptr_t)v;
176
177 if (ipu == (ipv + 1)) {
178 rsdIntrinsicYuv_K(out, Y, v, len, YuvCoeff);
179 x1 += len << 3;
180 out += len << 3;
181 } else if (ipu == (ipv - 1)) {
182 rsdIntrinsicYuvR_K(out, Y, u, len, YuvCoeff);
183 x1 += len << 3;
184 out += len << 3;
Jason Sams6b589092013-04-19 14:32:31 -0700185 }
Jason Sams6b589092013-04-19 14:32:31 -0700186
Jason Sams6b589092013-04-19 14:32:31 -0700187 }
Jason Sams709a0972012-11-15 18:18:04 -0800188 }
Jason Sams61656a72013-09-03 16:21:18 -0700189 }
Jason Sams6b589092013-04-19 14:32:31 -0700190#endif
Jason Sams61656a72013-09-03 16:21:18 -0700191
192 if(x2 > x1) {
193 // ALOGE("y %i %i %i", p->y, x1, x2);
194 while(x1 < x2) {
195 int cx = (x1 >> 1) * cstep;
196 *out = rsYuvToRGBA_uchar4(Y[x1], u[cx], v[cx]);
197 out++;
198 x1++;
199 *out = rsYuvToRGBA_uchar4(Y[x1], u[cx], v[cx]);
200 out++;
201 x1++;
202 }
Jason Sams709a0972012-11-15 18:18:04 -0800203 }
Jason Sams6b589092013-04-19 14:32:31 -0700204
Jason Sams709a0972012-11-15 18:18:04 -0800205}
206
207RsdCpuScriptIntrinsicYuvToRGB::RsdCpuScriptIntrinsicYuvToRGB(
Jason Samsc905efd2012-11-26 15:20:18 -0800208 RsdCpuReferenceImpl *ctx, const Script *s, const Element *e)
209 : RsdCpuScriptIntrinsic(ctx, s, e, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB) {
Jason Sams709a0972012-11-15 18:18:04 -0800210
211 mRootPtr = &kernel;
212}
213
214RsdCpuScriptIntrinsicYuvToRGB::~RsdCpuScriptIntrinsicYuvToRGB() {
215}
216
217void RsdCpuScriptIntrinsicYuvToRGB::populateScript(Script *s) {
218 s->mHal.info.exportedVariableCount = 1;
219}
220
221void RsdCpuScriptIntrinsicYuvToRGB::invokeFreeChildren() {
222 alloc.clear();
223}
224
225
Jason Samsc905efd2012-11-26 15:20:18 -0800226RsdCpuScriptImpl * rsdIntrinsic_YuvToRGB(RsdCpuReferenceImpl *ctx,
227 const Script *s, const Element *e) {
228 return new RsdCpuScriptIntrinsicYuvToRGB(ctx, s, e);
Jason Sams709a0972012-11-15 18:18:04 -0800229}
230
231