Home | History | Annotate | Download | only in driver
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      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 "rsdCore.h"
     19 #include "rsdIntrinsics.h"
     20 #include "rsdAllocation.h"
     21 
     22 #include "rsdIntrinsicInlines.h"
     23 
     24 using namespace android;
     25 using namespace android::renderscript;
     26 
     27 struct ConvolveParams {
     28     float fp[16];
     29     short ip[16];
     30     bool use3x3;
     31     bool useDot;
     32 };
     33 
     34 static void ColorMatrix_SetVar(const Context *dc, const Script *script, void * intrinsicData,
     35                                uint32_t slot, void *data, size_t dataLength) {
     36     ConvolveParams *cp = (ConvolveParams *)intrinsicData;
     37 
     38     rsAssert(slot == 0);
     39     memcpy (cp->fp, data, dataLength);
     40     for(int ct=0; ct < 16; ct++) {
     41         cp->ip[ct] = (short)(cp->fp[ct] * 255.f + 0.5f);
     42     }
     43 
     44     if ((cp->ip[3] == 0) && (cp->ip[7] == 0) && (cp->ip[11] == 0) &&
     45         (cp->ip[12] == 0) && (cp->ip[13] == 0) && (cp->ip[14] == 0) &&
     46         (cp->ip[15] == 255)) {
     47         cp->use3x3 = true;
     48 
     49         if ((cp->ip[0] == cp->ip[1]) && (cp->ip[0] == cp->ip[2]) &&
     50             (cp->ip[4] == cp->ip[5]) && (cp->ip[4] == cp->ip[6]) &&
     51             (cp->ip[8] == cp->ip[9]) && (cp->ip[8] == cp->ip[10])) {
     52             cp->useDot = true;
     53         }
     54     }
     55 }
     56 
     57 extern "C" void rsdIntrinsicColorMatrix4x4_K(void *dst, const void *src, const short *coef, uint32_t count);
     58 extern "C" void rsdIntrinsicColorMatrix3x3_K(void *dst, const void *src, const short *coef, uint32_t count);
     59 extern "C" void rsdIntrinsicColorMatrixDot_K(void *dst, const void *src, const short *coef, uint32_t count);
     60 
     61 static void One(const RsForEachStubParamStruct *p, uchar4 *out,
     62                 const uchar4 *py, const float* coeff) {
     63     float4 i = convert_float4(py[0]);
     64 
     65     float4 sum;
     66     sum.x = i.x * coeff[0] +
     67             i.y * coeff[4] +
     68             i.z * coeff[8] +
     69             i.w * coeff[12];
     70     sum.y = i.x * coeff[1] +
     71             i.y * coeff[5] +
     72             i.z * coeff[9] +
     73             i.w * coeff[13];
     74     sum.z = i.x * coeff[2] +
     75             i.y * coeff[6] +
     76             i.z * coeff[10] +
     77             i.w * coeff[14];
     78     sum.w = i.x * coeff[3] +
     79             i.y * coeff[7] +
     80             i.z * coeff[11] +
     81             i.w * coeff[15];
     82 
     83     sum.x = sum.x < 0 ? 0 : (sum.x > 255 ? 255 : sum.x);
     84     sum.y = sum.y < 0 ? 0 : (sum.y > 255 ? 255 : sum.y);
     85     sum.z = sum.z < 0 ? 0 : (sum.z > 255 ? 255 : sum.z);
     86     sum.w = sum.w < 0 ? 0 : (sum.w > 255 ? 255 : sum.w);
     87 
     88     *out = convert_uchar4(sum);
     89 }
     90 
     91 static void ColorMatrix_uchar4(const RsForEachStubParamStruct *p,
     92                                     uint32_t xstart, uint32_t xend,
     93                                     uint32_t instep, uint32_t outstep) {
     94     ConvolveParams *cp = (ConvolveParams *)p->usr;
     95     uchar4 *out = (uchar4 *)p->out;
     96     uchar4 *in = (uchar4 *)p->in;
     97     uint32_t x1 = xstart;
     98     uint32_t x2 = xend;
     99 
    100     in += xstart;
    101     out += xstart;
    102 
    103     if(x2 > x1) {
    104 #if defined(ARCH_ARM_HAVE_NEON)
    105         int32_t len = (x2 - x1) >> 2;
    106         if(len > 0) {
    107             if (cp->use3x3) {
    108                 if (cp->useDot) {
    109                     rsdIntrinsicColorMatrixDot_K(out, in, cp->ip, len);
    110                 } else {
    111                     rsdIntrinsicColorMatrix3x3_K(out, in, cp->ip, len);
    112                 }
    113             } else {
    114                 rsdIntrinsicColorMatrix4x4_K(out, in, cp->ip, len);
    115             }
    116             x1 += len << 2;
    117             out += len << 2;
    118             in += len << 2;
    119         }
    120 #endif
    121 
    122         while(x1 != x2) {
    123             One(p, out++, in++, cp->fp);
    124             x1++;
    125         }
    126     }
    127 }
    128 
    129 void * rsdIntrinsic_InitColorMatrix(const android::renderscript::Context *dc,
    130                                     android::renderscript::Script *script,
    131                                     RsdIntriniscFuncs_t *funcs) {
    132 
    133     script->mHal.info.exportedVariableCount = 1;
    134     funcs->setVar = ColorMatrix_SetVar;
    135     funcs->root = ColorMatrix_uchar4;
    136 
    137     ConvolveParams *cp = (ConvolveParams *)calloc(1, sizeof(ConvolveParams));
    138     cp->fp[0] = 1.f;
    139     cp->fp[5] = 1.f;
    140     cp->fp[10] = 1.f;
    141     cp->fp[15] = 1.f;
    142     for(int ct=0; ct < 16; ct++) {
    143         cp->ip[ct] = (short)(cp->fp[ct] * 255.f + 0.5f);
    144     }
    145     return cp;
    146 }
    147 
    148 
    149