1ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams/*
2ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Copyright (C) 2012 The Android Open Source Project
3ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams *
4ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * you may not use this file except in compliance with the License.
6ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * You may obtain a copy of the License at
7ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams *
8ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams *
10ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Unless required by applicable law or agreed to in writing, software
11ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * See the License for the specific language governing permissions and
14ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * limitations under the License.
15ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */
16ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
17ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
18ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#include "rsdCore.h"
19ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#include "rsdIntrinsics.h"
20ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#include "rsdAllocation.h"
21ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
22ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#include "rsdIntrinsicInlines.h"
23ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
24ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsusing namespace android;
25ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsusing namespace android::renderscript;
26ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
27ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstruct ConvolveParams {
28ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float fp[104];
29ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    short ip[104];
30ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float radius;
31ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    int iradius;
32ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    ObjectBaseRef<Allocation> alloc;
33ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams};
34ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
35ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic void ComputeGaussianWeights(ConvolveParams *cp) {
36ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // Compute gaussian weights for the blur
37ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // e is the euler's number
38ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float e = 2.718281828459045f;
39ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float pi = 3.1415926535897932f;
40ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 )
41ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // x is of the form [-radius .. 0 .. radius]
42ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // and sigma varies with radius.
43ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // Based on some experimental radius values and sigma's
44ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // we approximately fit sigma = f(radius) as
45ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // sigma = radius * 0.4  + 0.6
46ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // The larger the radius gets, the more our gaussian blur
47ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // will resemble a box blur since with large sigma
48ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // the gaussian curve begins to lose its shape
49ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float sigma = 0.4f * cp->radius + 0.6f;
50ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
51ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // Now compute the coefficients. We will store some redundant values to save
52ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    // some math during the blur calculations precompute some values
53ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float coeff1 = 1.0f / (sqrtf(2.0f * pi) * sigma);
54ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float coeff2 = - 1.0f / (2.0f * sigma * sigma);
55ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
56ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float normalizeFactor = 0.0f;
57ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float floatR = 0.0f;
58ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    int r;
59ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    cp->iradius = (float)ceil(cp->radius) + 0.5f;
60ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    for (r = -cp->iradius; r <= cp->iradius; r ++) {
61ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        floatR = (float)r;
62ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        cp->fp[r + cp->iradius] = coeff1 * powf(e, floatR * floatR * coeff2);
63ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        normalizeFactor += cp->fp[r + cp->iradius];
64ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
65ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
66ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    //Now we need to normalize the weights because all our coefficients need to add up to one
67ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    normalizeFactor = 1.0f / normalizeFactor;
68ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    for (r = -cp->iradius; r <= cp->iradius; r ++) {
69ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        cp->fp[r + cp->iradius] *= normalizeFactor;
70ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        cp->ip[r + cp->iradius] = (short)(cp->ip[r + cp->iradius] * 32768);
71ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
72ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams}
73ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
74ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic void Blur_Bind(const Context *dc, const Script *script,
75ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                             void * intrinsicData, uint32_t slot, Allocation *data) {
76ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    ConvolveParams *cp = (ConvolveParams *)intrinsicData;
77ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    rsAssert(slot == 1);
78ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    cp->alloc.set(data);
79ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams}
80ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
81ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic void Blur_SetVar(const Context *dc, const Script *script, void * intrinsicData,
82ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                               uint32_t slot, void *data, size_t dataLength) {
83ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    ConvolveParams *cp = (ConvolveParams *)intrinsicData;
84ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    rsAssert(slot == 0);
85ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
86ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    cp->radius = ((const float *)data)[0];
87ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    ComputeGaussianWeights(cp);
88ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams}
89ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
90ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
91ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
92ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic void OneV(const RsForEachStubParamStruct *p, float4 *out, int32_t x, int32_t y,
93ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                 const uchar *ptrIn, int iStride, const float* gPtr, int iradius) {
94ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
95ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    const uchar *pi = ptrIn + x*4;
96ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
97ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float4 blurredPixel = 0;
98ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    for (int r = -iradius; r <= iradius; r ++) {
99ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        int validY = rsMax((y + r), 0);
100ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        validY = rsMin(validY, (int)(p->dimY - 1));
101ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        const uchar4 *pvy = (const uchar4 *)&pi[validY * iStride];
102ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        float4 pf = convert_float4(pvy[0]);
103ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        blurredPixel += pf * gPtr[0];
104ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        gPtr++;
105ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
106ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
107ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    out->xyzw = blurredPixel;
108ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams}
109ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
110ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsextern "C" void rsdIntrinsicBlurVF_K(void *dst, const void *pin, int stride, const void *gptr, int rct, int x1, int x2);
111ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsextern "C" void rsdIntrinsicBlurHF_K(void *dst, const void *pin, const void *gptr, int rct, int x1, int x2);
112ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
113ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic void OneVF(float4 *out,
114ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                  const uchar *ptrIn, int iStride, const float* gPtr, int ct,
115ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                  int x1, int x2) {
116ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
117ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#if defined(ARCH_ARM_HAVE_NEON)
118ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    {
119ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        int t = (x2 - x1);
120ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        t &= ~1;
121ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        if(t) {
122ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams            rsdIntrinsicBlurVF_K(out, ptrIn, iStride, gPtr, ct, x1, x1 + t);
123ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        }
124ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        x1 += t;
125ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
126ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#endif
127ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
128ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    while(x2 > x1) {
129ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        const uchar *pi = ptrIn + x1 * 4;
130ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        float4 blurredPixel = 0;
131ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        const float* gp = gPtr;
132ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
133ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        for (int r = 0; r < ct; r++) {
134ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams            float4 pf = convert_float4(((const uchar4 *)pi)[0]);
135ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams            blurredPixel += pf * gp[0];
136ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams            pi += iStride;
137ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams            gp++;
138ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        }
139ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        out->xyzw = blurredPixel;
140ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        x1++;
141ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        out++;
142ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
143ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams}
144ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
145ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic void OneH(const RsForEachStubParamStruct *p, uchar4 *out, int32_t x,
146ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                const float4 *ptrIn, const float* gPtr, int iradius) {
147ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
148ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float4 blurredPixel = 0;
149ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    for (int r = -iradius; r <= iradius; r ++) {
150ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        int validX = rsMax((x + r), 0);
151ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        validX = rsMin(validX, (int)(p->dimX - 1));
152ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        float4 pf = ptrIn[validX];
153ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        blurredPixel += pf * gPtr[0];
154ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        gPtr++;
155ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
156ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
157ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    out->xyzw = convert_uchar4(blurredPixel);
158ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams}
159ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
160ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
161ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic void Blur_uchar4(const RsForEachStubParamStruct *p,
162ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                                    uint32_t xstart, uint32_t xend,
163ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                                    uint32_t instep, uint32_t outstep) {
164ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float buf[4 * 2048];
165ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    ConvolveParams *cp = (ConvolveParams *)p->usr;
166ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    DrvAllocation *din = (DrvAllocation *)cp->alloc->mHal.drv;
167ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    const uchar *pin = (const uchar *)din->lod[0].mallocPtr;
168ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
169ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    uchar4 *out = (uchar4 *)p->out;
170ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    uint32_t x1 = xstart;
171ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    uint32_t x2 = xend;
172ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
173ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    float4 *fout = (float4 *)buf;
174ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    int y = p->y;
175ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    if ((y > cp->iradius) && (y < ((int)p->dimY - cp->iradius))) {
176ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        const uchar *pi = pin + (y - cp->iradius) * din->lod[0].stride;
177ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        OneVF(fout, pi, din->lod[0].stride, cp->fp, cp->iradius * 2 + 1, x1, x2);
178ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    } else {
179ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        while(x2 > x1) {
180ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams            OneV(p, fout, x1, y, pin, din->lod[0].stride, cp->fp, cp->iradius);
181ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams            fout++;
182ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams            x1++;
183ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        }
184ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
185ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
186ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    x1 = xstart;
187ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    while ((x1 < (uint32_t)cp->iradius) && (x1 < x2)) {
188ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        OneH(p, out, x1, (float4 *)buf, cp->fp, cp->iradius);
189ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        out++;
190ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        x1++;
191ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
192ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#if defined(ARCH_ARM_HAVE_NEON)
193ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    if ((x1 + cp->iradius) < x2) {
194ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        rsdIntrinsicBlurHF_K(out, ((float4 *)buf) - cp->iradius, cp->fp, cp->iradius * 2 + 1, x1, x2 - cp->iradius);
195ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        out += (x2 - cp->iradius) - x1;
196ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        x1 = x2 - cp->iradius;
197ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
198ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#endif
199ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    while(x2 > x1) {
200ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        OneH(p, out, x1, (float4 *)buf, cp->fp, cp->iradius);
201ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        out++;
202ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        x1++;
203ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
204ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
205ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams}
206ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
207ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsvoid * rsdIntrinsic_InitBlur(const android::renderscript::Context *dc,
208ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                                    android::renderscript::Script *script,
209ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                                    RsdIntriniscFuncs_t *funcs) {
210ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
211ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    script->mHal.info.exportedVariableCount = 2;
212ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    funcs->bind = Blur_Bind;
213ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    funcs->setVar = Blur_SetVar;
214ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    funcs->root = Blur_uchar4;
215ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
216ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    ConvolveParams *cp = (ConvolveParams *)calloc(1, sizeof(ConvolveParams));
217ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    cp->radius = 5;
218ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    ComputeGaussianWeights(cp);
219ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    return cp;
220ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams}
221ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
222ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
223