rsCpuIntrinsicYuvToRGB.cpp revision c905efd76fdcc1b8846b229bf7d991d185a7b4b7
101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams/* 201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * Copyright (C) 2012 The Android Open Source Project 301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * 401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * you may not use this file except in compliance with the License. 601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * You may obtain a copy of the License at 701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * 801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * 1001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * Unless required by applicable law or agreed to in writing, software 1101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 1201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * See the License for the specific language governing permissions and 1401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * limitations under the License. 1501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams */ 1601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 1701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 18709a0978ae141198018ca9769f8d96292a8928e6Jason Sams#include "rsCpuIntrinsic.h" 19709a0978ae141198018ca9769f8d96292a8928e6Jason Sams#include "rsCpuIntrinsicInlines.h" 2001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 2101f03a04da629b9a3e3ff33287dd277b12c54148Jason Samsusing namespace android; 2201f03a04da629b9a3e3ff33287dd277b12c54148Jason Samsusing namespace android::renderscript; 2301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 24709a0978ae141198018ca9769f8d96292a8928e6Jason Samsnamespace android { 25709a0978ae141198018ca9769f8d96292a8928e6Jason Samsnamespace renderscript { 26709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 27709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 28709a0978ae141198018ca9769f8d96292a8928e6Jason Samsclass RsdCpuScriptIntrinsicYuvToRGB : public RsdCpuScriptIntrinsic { 29709a0978ae141198018ca9769f8d96292a8928e6Jason Samspublic: 30709a0978ae141198018ca9769f8d96292a8928e6Jason Sams virtual void populateScript(Script *); 31709a0978ae141198018ca9769f8d96292a8928e6Jason Sams virtual void invokeFreeChildren(); 32709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 33709a0978ae141198018ca9769f8d96292a8928e6Jason Sams virtual void setGlobalObj(uint32_t slot, ObjectBase *data); 34709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 35709a0978ae141198018ca9769f8d96292a8928e6Jason Sams virtual ~RsdCpuScriptIntrinsicYuvToRGB(); 36c905efd76fdcc1b8846b229bf7d991d185a7b4b7Jason Sams RsdCpuScriptIntrinsicYuvToRGB(RsdCpuReferenceImpl *ctx, const Script *s, const Element *e); 37709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 38709a0978ae141198018ca9769f8d96292a8928e6Jason Samsprotected: 3901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams ObjectBaseRef<Allocation> alloc; 40709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 41709a0978ae141198018ca9769f8d96292a8928e6Jason Sams static void kernel(const RsForEachStubParamStruct *p, 42709a0978ae141198018ca9769f8d96292a8928e6Jason Sams uint32_t xstart, uint32_t xend, 43709a0978ae141198018ca9769f8d96292a8928e6Jason Sams uint32_t instep, uint32_t outstep); 4401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams}; 4501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 46709a0978ae141198018ca9769f8d96292a8928e6Jason Sams} 47709a0978ae141198018ca9769f8d96292a8928e6Jason Sams} 48709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 49709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 50709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptIntrinsicYuvToRGB::setGlobalObj(uint32_t slot, ObjectBase *data) { 5101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams rsAssert(slot == 0); 52709a0978ae141198018ca9769f8d96292a8928e6Jason Sams alloc.set(static_cast<Allocation *>(data)); 5301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams} 5401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 5501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 5601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 57709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 5801f03a04da629b9a3e3ff33287dd277b12c54148Jason Samsstatic uchar4 rsYuvToRGBA_uchar4(uchar y, uchar u, uchar v) { 5901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams short Y = ((short)y) - 16; 6001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams short U = ((short)u) - 128; 6101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams short V = ((short)v) - 128; 6201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 6301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams short4 p; 6401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.r = (Y * 298 + V * 409 + 128) >> 8; 6501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.g = (Y * 298 - U * 100 - V * 208 + 128) >> 8; 6601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.b = (Y * 298 + U * 516 + 128) >> 8; 6701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.a = 255; 6801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.r < 0) { 6901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.r = 0; 7001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 7101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.r > 255) { 7201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.r = 255; 7301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 7401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.g < 0) { 7501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.g = 0; 7601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 7701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.g > 255) { 7801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.g = 255; 7901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 8001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.b < 0) { 8101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.b = 0; 8201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 8301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.b > 255) { 8401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.b = 255; 8501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 8601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 8701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams return (uchar4){p.r, p.g, p.b, p.a}; 8801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams} 8901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 90915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 91915aa964a1a312f5e06c115112a3aea14fd31b33Jason Samsstatic short YuvCoeff[] = { 92915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 298, 409, -100, 516, -208, 255, 0, 0, 93915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 16, 16, 16, 16, 16, 16, 16, 16, 94915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 128, 128, 128, 128, 128, 128, 128, 128, 95915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 298, 298, 298, 298, 298, 298, 298, 298, 96915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 255, 255, 255, 255, 255, 255, 255, 255 97915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 98915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 99915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams}; 100915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 101915aa964a1a312f5e06c115112a3aea14fd31b33Jason Samsextern "C" void rsdIntrinsicYuv_K(void *dst, const uchar *Y, const uchar *uv, uint32_t count, const short *param); 10201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 103709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptIntrinsicYuvToRGB::kernel(const RsForEachStubParamStruct *p, 104709a0978ae141198018ca9769f8d96292a8928e6Jason Sams uint32_t xstart, uint32_t xend, 105709a0978ae141198018ca9769f8d96292a8928e6Jason Sams uint32_t instep, uint32_t outstep) { 106709a0978ae141198018ca9769f8d96292a8928e6Jason Sams RsdCpuScriptIntrinsicYuvToRGB *cp = (RsdCpuScriptIntrinsicYuvToRGB *)p->usr; 107b801b949e286275b5d19a33135235ba68d3a19a9Jason Sams if (!cp->alloc.get()) { 108b801b949e286275b5d19a33135235ba68d3a19a9Jason Sams ALOGE("YuvToRGB executed without input, skipping"); 109b801b949e286275b5d19a33135235ba68d3a19a9Jason Sams return; 110b801b949e286275b5d19a33135235ba68d3a19a9Jason Sams } 111709a0978ae141198018ca9769f8d96292a8928e6Jason Sams const uchar *pin = (const uchar *)cp->alloc->mHal.drvState.lod[0].mallocPtr; 112709a0978ae141198018ca9769f8d96292a8928e6Jason Sams const size_t stride = cp->alloc->mHal.drvState.lod[0].stride; 11301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 11401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams const uchar *Y = pin + (p->y * p->dimX); 11501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams const uchar *uv = pin + (p->dimX * p->dimY); 11601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uv += (p->y>>1) * p->dimX; 11701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 11801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uchar4 *out = (uchar4 *)p->out; 11901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uint32_t x1 = xstart; 12001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uint32_t x2 = xend; 12101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 12201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(x2 > x1) { 123915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams#if defined(ARCH_ARM_HAVE_NEON) 124915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams int32_t len = (x2 - x1 - 1) >> 3; 12501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(len > 0) { 126915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams rsdIntrinsicYuv_K(out, Y, uv, len, YuvCoeff); 127915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams x1 += len << 3; 128915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams out += len << 3; 12901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 13001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams#endif 13101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 13201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams // ALOGE("y %i %i %i", p->y, x1, x2); 13301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams while(x1 < x2) { 13401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uchar u = uv[(x1 & 0xffffe) + 1]; 13501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uchar v = uv[(x1 & 0xffffe) + 0]; 13601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams *out = rsYuvToRGBA_uchar4(Y[x1], u, v); 13701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams out++; 13801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams x1++; 13901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams *out = rsYuvToRGBA_uchar4(Y[x1], u, v); 14001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams out++; 14101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams x1++; 14201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 14301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 14401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams} 14501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 146709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptIntrinsicYuvToRGB::RsdCpuScriptIntrinsicYuvToRGB( 147c905efd76fdcc1b8846b229bf7d991d185a7b4b7Jason Sams RsdCpuReferenceImpl *ctx, const Script *s, const Element *e) 148c905efd76fdcc1b8846b229bf7d991d185a7b4b7Jason Sams : RsdCpuScriptIntrinsic(ctx, s, e, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB) { 149709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 150709a0978ae141198018ca9769f8d96292a8928e6Jason Sams mRootPtr = &kernel; 151709a0978ae141198018ca9769f8d96292a8928e6Jason Sams} 152709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 153709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptIntrinsicYuvToRGB::~RsdCpuScriptIntrinsicYuvToRGB() { 154709a0978ae141198018ca9769f8d96292a8928e6Jason Sams} 155709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 156709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptIntrinsicYuvToRGB::populateScript(Script *s) { 157709a0978ae141198018ca9769f8d96292a8928e6Jason Sams s->mHal.info.exportedVariableCount = 1; 158709a0978ae141198018ca9769f8d96292a8928e6Jason Sams} 159709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 160709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptIntrinsicYuvToRGB::invokeFreeChildren() { 161709a0978ae141198018ca9769f8d96292a8928e6Jason Sams alloc.clear(); 162709a0978ae141198018ca9769f8d96292a8928e6Jason Sams} 163709a0978ae141198018ca9769f8d96292a8928e6Jason Sams 16401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 165c905efd76fdcc1b8846b229bf7d991d185a7b4b7Jason SamsRsdCpuScriptImpl * rsdIntrinsic_YuvToRGB(RsdCpuReferenceImpl *ctx, 166c905efd76fdcc1b8846b229bf7d991d185a7b4b7Jason Sams const Script *s, const Element *e) { 167c905efd76fdcc1b8846b229bf7d991d185a7b4b7Jason Sams return new RsdCpuScriptIntrinsicYuvToRGB(ctx, s, e); 16801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams} 16901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 17001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 171