blob: 4f564430a213a2c35ce58804b0487d3e0395baa3 [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 Sams6b589092013-04-19 14:32:31 -0700110extern "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 -0800111
112void RsdCpuScriptIntrinsicYuvToRGB::kernel(const RsForEachStubParamStruct *p,
113 uint32_t xstart, uint32_t xend,
114 uint32_t instep, uint32_t outstep) {
115 RsdCpuScriptIntrinsicYuvToRGB *cp = (RsdCpuScriptIntrinsicYuvToRGB *)p->usr;
116 if (!cp->alloc.get()) {
117 ALOGE("YuvToRGB executed without input, skipping");
118 return;
119 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800120 const uchar *pinY = (const uchar *)cp->alloc->mHal.drvState.lod[0].mallocPtr;
Tim Murray606e5002013-06-13 12:33:49 -0700121
122 size_t strideY = cp->alloc->mHal.drvState.lod[0].stride;
123
124 // calculate correct stride in legacy case
125 if (cp->alloc->mHal.drvState.lod[0].dimY == 0) {
126 strideY = p->dimX;
127 }
Jason Samsbc0ca6b2013-02-15 18:13:43 -0800128 const uchar *Y = pinY + (p->y * strideY);
Jason Sams709a0972012-11-15 18:18:04 -0800129
Tim Murray606e5002013-06-13 12:33:49 -0700130 // ALOGE("pinY, %p, Y, %p, p->y, %d, strideY, %d", pinY, Y, p->y, strideY);
131 // ALOGE("dimX, %d, dimY, %d", cp->alloc->mHal.drvState.lod[0].dimX, cp->alloc->mHal.drvState.lod[0].dimY);
132 // ALOGE("p->dimX, %d, p->dimY, %d", p->dimX, p->dimY);
133
Jason Sams709a0972012-11-15 18:18:04 -0800134 uchar4 *out = (uchar4 *)p->out;
135 uint32_t x1 = xstart;
136 uint32_t x2 = xend;
137
Jason Sams6b589092013-04-19 14:32:31 -0700138 switch (cp->alloc->mHal.state.yuv) {
139 // In API 17 there was no yuv format and the intrinsic treated everything as NV21
140 case 0:
Tim Murrayaa782372013-08-29 18:42:54 -0700141#if !defined(RS_SERVER)
Jason Sams6b589092013-04-19 14:32:31 -0700142 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
Jason Sams709a0972012-11-15 18:18:04 -0800143#endif
Jason Sams6b589092013-04-19 14:32:31 -0700144 {
145 const uchar *pinUV = (const uchar *)cp->alloc->mHal.drvState.lod[1].mallocPtr;
Tim Murray606e5002013-06-13 12:33:49 -0700146 size_t strideUV = cp->alloc->mHal.drvState.lod[1].stride;
Jason Sams6b589092013-04-19 14:32:31 -0700147 const uchar *uv = pinUV + ((p->y >> 1) * strideUV);
Jason Sams709a0972012-11-15 18:18:04 -0800148
Jason Sams06bd91e2013-06-11 18:38:11 -0700149 if (pinUV == NULL) {
150 // Legacy yuv support didn't fill in uv
Tim Murray606e5002013-06-13 12:33:49 -0700151 strideUV = strideY;
Jason Sams06bd91e2013-06-11 18:38:11 -0700152 uv = ((uint8_t *)cp->alloc->mHal.drvState.lod[0].mallocPtr) +
Tim Murray606e5002013-06-13 12:33:49 -0700153 (strideY * p->dimY) +
154 ((p->y >> 1) * strideUV);
Jason Sams06bd91e2013-06-11 18:38:11 -0700155 }
156
Jason Sams6b589092013-04-19 14:32:31 -0700157 if(x2 > x1) {
Jason Samsf5ef8df2013-08-06 13:49:25 -0700158 if (gArchUseSIMD) {
159 #if defined(ARCH_ARM_HAVE_VFP)
160 int32_t len = (x2 - x1 - 1) >> 3;
161 if(len > 0) {
162 // ALOGE("%p, %p, %p, %d, %p", out, Y, uv, len, YuvCoeff);
163 rsdIntrinsicYuv_K(out, Y, uv, len, YuvCoeff);
164 x1 += len << 3;
165 out += len << 3;
166 }
167 #endif
Jason Sams6b589092013-04-19 14:32:31 -0700168 }
Jason Sams6b589092013-04-19 14:32:31 -0700169
170 // ALOGE("y %i %i %i", p->y, x1, x2);
171 while(x1 < x2) {
172 uchar u = uv[(x1 & 0xffffe) + 1];
173 uchar v = uv[(x1 & 0xffffe) + 0];
174 *out = rsYuvToRGBA_uchar4(Y[x1], u, v);
175 out++;
176 x1++;
177 *out = rsYuvToRGBA_uchar4(Y[x1], u, v);
178 out++;
179 x1++;
180 }
181 }
Jason Sams709a0972012-11-15 18:18:04 -0800182 }
Jason Sams6b589092013-04-19 14:32:31 -0700183 break;
184
Tim Murrayaa782372013-08-29 18:42:54 -0700185#if !defined(RS_SERVER)
Jason Sams6b589092013-04-19 14:32:31 -0700186 case HAL_PIXEL_FORMAT_YV12:
187 {
188 const uchar *pinU = (const uchar *)cp->alloc->mHal.drvState.lod[1].mallocPtr;
189 const size_t strideU = cp->alloc->mHal.drvState.lod[1].stride;
190 const uchar *u = pinU + ((p->y >> 1) * strideU);
191
192 const uchar *pinV = (const uchar *)cp->alloc->mHal.drvState.lod[2].mallocPtr;
193 const size_t strideV = cp->alloc->mHal.drvState.lod[2].stride;
194 const uchar *v = pinV + ((p->y >> 1) * strideV);
195
196 if(x2 > x1) {
Jason Samsf5ef8df2013-08-06 13:49:25 -0700197 #if defined(ARCH_ARM_HAVE_VFP)
198 if (gArchUseSIMD) {
199 int32_t len = (x2 - x1 - 1) >> 3;
200 if(len > 0) {
201 rsdIntrinsicYuv2_K(out, Y, u, v, len, YuvCoeff);
202 x1 += len << 3;
203 out += len << 3;
204 }
Jason Sams6b589092013-04-19 14:32:31 -0700205 }
206 #endif
207
208 // ALOGE("y %i %i %i", p->y, x1, x2);
209 while(x1 < x2) {
210 uchar ut = u[x1];
211 uchar vt = v[x1];
212 *out = rsYuvToRGBA_uchar4(Y[x1], ut, vt);
213 out++;
214 x1++;
215 *out = rsYuvToRGBA_uchar4(Y[x1], ut, vt);
216 out++;
217 x1++;
218 }
219 }
220 }
221 break;
222#endif
Jason Sams709a0972012-11-15 18:18:04 -0800223 }
Jason Sams6b589092013-04-19 14:32:31 -0700224
Jason Sams709a0972012-11-15 18:18:04 -0800225}
226
227RsdCpuScriptIntrinsicYuvToRGB::RsdCpuScriptIntrinsicYuvToRGB(
Jason Samsc905efd2012-11-26 15:20:18 -0800228 RsdCpuReferenceImpl *ctx, const Script *s, const Element *e)
229 : RsdCpuScriptIntrinsic(ctx, s, e, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB) {
Jason Sams709a0972012-11-15 18:18:04 -0800230
231 mRootPtr = &kernel;
232}
233
234RsdCpuScriptIntrinsicYuvToRGB::~RsdCpuScriptIntrinsicYuvToRGB() {
235}
236
237void RsdCpuScriptIntrinsicYuvToRGB::populateScript(Script *s) {
238 s->mHal.info.exportedVariableCount = 1;
239}
240
241void RsdCpuScriptIntrinsicYuvToRGB::invokeFreeChildren() {
242 alloc.clear();
243}
244
245
Jason Samsc905efd2012-11-26 15:20:18 -0800246RsdCpuScriptImpl * rsdIntrinsic_YuvToRGB(RsdCpuReferenceImpl *ctx,
247 const Script *s, const Element *e) {
248 return new RsdCpuScriptIntrinsicYuvToRGB(ctx, s, e);
Jason Sams709a0972012-11-15 18:18:04 -0800249}
250
251