rsdBcc.cpp revision 378d30b1da622e0e75e551e95fafb18ff3a3f88e
1bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams/*
2ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines * Copyright (C) 2011-2012 The Android Open Source Project
3bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *
4bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * you may not use this file except in compliance with the License.
6bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * You may obtain a copy of the License at
7bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *
8bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *
10bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * Unless required by applicable law or agreed to in writing, software
11bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * See the License for the specific language governing permissions and
14bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * limitations under the License.
15bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams */
16bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
17bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsdCore.h"
18bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsdBcc.h"
1987fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams#include "rsdRuntime.h"
20807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams#include "rsdAllocation.h"
21bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
22a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao#include <bcc/BCCContext.h>
23378d30b1da622e0e75e551e95fafb18ff3a3f88eStephen Hines#include <bcc/Renderscript/RSCompilerDriver.h>
24378d30b1da622e0e75e551e95fafb18ff3a3f88eStephen Hines#include <bcc/Renderscript/RSExecutable.h>
25378d30b1da622e0e75e551e95fafb18ff3a3f88eStephen Hines#include <bcc/Renderscript/RSInfo.h>
26689821f178503af951a3d9dd558ef8eace6537cdStephen Hines
27bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsContext.h"
282980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines#include "rsElement.h"
29bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsScriptC.h"
30bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
31a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao#include "utils/Vector.h"
32bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "utils/Timers.h"
33bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "utils/StopWatch.h"
34bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
35bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android;
36bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android::renderscript;
37bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
38bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsstruct DrvScript {
39bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    int (*mRoot)();
40ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines    int (*mRootExpand)();
41bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    void (*mInit)();
424ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines    void (*mFreeChildren)();
43bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
44a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    bcc::BCCContext *mCompilerContext;
45a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    bcc::RSCompilerDriver *mCompilerDriver;
46a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    bcc::RSExecutable *mExecutable;
47807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
48807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    Allocation **mBoundAllocs;
49bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams};
50bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
51ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hinestypedef void (*outer_foreach_t)(
52ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines    const android::renderscript::RsForEachStubParamStruct *,
53ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines    uint32_t x1, uint32_t x2,
54ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines    uint32_t instep, uint32_t outstep);
5583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
56cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic Script * setTLS(Script *sc) {
5783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    ScriptTLSStruct * tls = (ScriptTLSStruct *)pthread_getspecific(rsdgThreadTLSKey);
58cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsAssert(tls);
59cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Script *old = tls->mScript;
60cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    tls->mScript = sc;
61cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    return old;
62cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
63cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
64cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
65bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsbool rsdScriptInit(const Context *rsc,
66bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                     ScriptC *script,
67bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                     char const *resName,
68bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                     char const *cacheDir,
69bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                     uint8_t const *bitcode,
70bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                     size_t bitcodeSize,
7187fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams                     uint32_t flags) {
72af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc);
730ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams    //ALOGE("rsdScriptInit %p %p", rsc, script);
74bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
7583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
761415ca46b289604fd727310e4f6ae3c8c68276c9Logan Chien
77ebee9480507562109314cca00753a09002a91e7dStephen Hines    const char* coreLib = "/system/lib/libclcore.bc";
78a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    bcc::RSInfo::FloatPrecision prec;
79a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    bcc::RSExecutable *exec;
80a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    const bcc::RSInfo *info;
81bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    DrvScript *drv = (DrvScript *)calloc(1, sizeof(DrvScript));
82bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (drv == NULL) {
8383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        goto error;
84bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
85bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    script->mHal.drv = drv;
86bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
87a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mCompilerContext = NULL;
88a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mCompilerDriver = NULL;
89a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mExecutable = NULL;
90070cb235d9f094048c0260aa72d5acf61ed840a3Stephen Hines
91a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mCompilerContext = new bcc::BCCContext();
92a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    if (drv->mCompilerContext == NULL) {
93a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        ALOGE("bcc: FAILS to create compiler context (out of memory)");
9483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        goto error;
95bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
96bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
97a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mCompilerDriver = new bcc::RSCompilerDriver();
98a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    if (drv->mCompilerDriver == NULL) {
99a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        ALOGE("bcc: FAILS to create compiler driver (out of memory)");
100070cb235d9f094048c0260aa72d5acf61ed840a3Stephen Hines        goto error;
101070cb235d9f094048c0260aa72d5acf61ed840a3Stephen Hines    }
102bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
103a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    script->mHal.info.isThreadable = true;
104bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
105a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mCompilerDriver->setRSRuntimeLookupFunction(rsdLookupRuntimeStub);
106a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mCompilerDriver->setRSRuntimeLookupContext(script);
107bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
108a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    exec = drv->mCompilerDriver->build(*drv->mCompilerContext,
109a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao                                       cacheDir, resName,
110a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao                                       (const char *)bitcode, bitcodeSize);
111bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
112a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    if (exec == NULL) {
113a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        ALOGE("bcc: FAILS to prepare executable for '%s'", resName);
114a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        goto error;
1154419977d78018a9933c7f455fe001f644f2d638bStephen Hines    }
1163815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines
117a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mExecutable = exec;
118070cb235d9f094048c0260aa72d5acf61ed840a3Stephen Hines
119a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    exec->setThreadable(script->mHal.info.isThreadable);
120a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    if (!exec->syncInfo()) {
121a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        ALOGW("bcc: FAILS to synchronize the RS info file to the disk");
122070cb235d9f094048c0260aa72d5acf61ed840a3Stephen Hines    }
123ec3fc1163c01e18b1454057723c451f0d96868adShih-wei Liao
124a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mRoot = reinterpret_cast<int (*)()>(exec->getSymbolAddress("root"));
125a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mRootExpand =
126a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        reinterpret_cast<int (*)()>(exec->getSymbolAddress("root.expand"));
127a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mInit = reinterpret_cast<void (*)()>(exec->getSymbolAddress("init"));
128a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    drv->mFreeChildren =
129a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        reinterpret_cast<void (*)()>(exec->getSymbolAddress(".rs.dtor"));
130a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao
131a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    info = &drv->mExecutable->getInfo();
132bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    // Copy info over to runtime
133a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    script->mHal.info.exportedFunctionCount = info->getExportFuncNames().size();
134a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    script->mHal.info.exportedVariableCount = info->getExportVarNames().size();
135a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    script->mHal.info.exportedPragmaCount = info->getPragmas().size();
136a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    script->mHal.info.exportedPragmaKeyList =
137a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        const_cast<const char**>(exec->getPragmaKeys().array());
138a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    script->mHal.info.exportedPragmaValueList =
139a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        const_cast<const char**>(exec->getPragmaValues().array());
140ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines
141ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines    if (drv->mRootExpand) {
142a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        script->mHal.info.root = drv->mRootExpand;
143ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines    } else {
144a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        script->mHal.info.root = drv->mRoot;
145ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines    }
146bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
147807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    if (script->mHal.info.exportedVariableCount) {
148807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        drv->mBoundAllocs = new Allocation *[script->mHal.info.exportedVariableCount];
149807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        memset(drv->mBoundAllocs, 0, sizeof(void *) * script->mHal.info.exportedVariableCount);
150807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
151807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
15283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
153bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    return true;
154bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
155bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samserror:
156bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
15783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
158a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    if (drv) {
159a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        delete drv->mCompilerContext;
160a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        delete drv->mCompilerDriver;
161a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        delete drv->mExecutable;
162807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        delete[] drv->mBoundAllocs;
163a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        free(drv);
164cbb0b8aceedb9146ba901cba1fbd6d1e9ca88f51Stephen Hines    }
165a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    script->mHal.drv = NULL;
166bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    return false;
167bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
168bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
169bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
170cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samstypedef struct {
171cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Context *rsc;
172cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Script *script;
1734419977d78018a9933c7f455fe001f644f2d638bStephen Hines    ForEachFunc_t kernel;
1743815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    uint32_t sig;
175cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    const Allocation * ain;
176cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Allocation * aout;
177cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    const void * usr;
178451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams    size_t usrLen;
179cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
180cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t mSliceSize;
181cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    volatile int mSliceNum;
182cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
183cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    const uint8_t *ptrIn;
184cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t eStrideIn;
185cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint8_t *ptrOut;
186cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t eStrideOut;
187cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
188f22c8ace148b69847aaf5ad1829e9ec95a44df6cJason Sams    uint32_t yStrideIn;
189f22c8ace148b69847aaf5ad1829e9ec95a44df6cJason Sams    uint32_t yStrideOut;
190f22c8ace148b69847aaf5ad1829e9ec95a44df6cJason Sams
191cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t xStart;
192cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t xEnd;
193cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t yStart;
194cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t yEnd;
195cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t zStart;
196cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t zEnd;
197cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t arrayStart;
198cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t arrayEnd;
199cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
200cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t dimX;
201cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t dimY;
202cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t dimZ;
203cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t dimArray;
204cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams} MTLaunchStruct;
2053815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hinestypedef void (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
206cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
207cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void wc_xy(void *usr, uint32_t idx) {
208cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
209451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams    RsForEachStubParamStruct p;
210451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams    memset(&p, 0, sizeof(p));
211451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams    p.usr = mtls->usr;
212451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams    p.usr_len = mtls->usrLen;
2133815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
2143815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    uint32_t sig = mtls->sig;
215cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
2164419977d78018a9933c7f455fe001f644f2d638bStephen Hines    outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
217cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (1) {
218cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
219cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
220cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        uint32_t yEnd = yStart + mtls->mSliceSize;
221cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        yEnd = rsMin(yEnd, mtls->yEnd);
222cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (yEnd <= yStart) {
223cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            return;
224cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
225cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
226af12ac6a08651464f8d823add667c706f993b587Steve Block        //ALOGE("usr idx %i, x %i,%i  y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
227af12ac6a08651464f8d823add667c706f993b587Steve Block        //ALOGE("usr ptr in %p,  out %p", mtls->ptrIn, mtls->ptrOut);
228451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams        for (p.y = yStart; p.y < yEnd; p.y++) {
229f22c8ace148b69847aaf5ad1829e9ec95a44df6cJason Sams            p.out = mtls->ptrOut + (mtls->yStrideOut * p.y);
230f22c8ace148b69847aaf5ad1829e9ec95a44df6cJason Sams            p.in = mtls->ptrIn + (mtls->yStrideIn * p.y);
231ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines            fn(&p, mtls->xStart, mtls->xEnd, mtls->eStrideIn, mtls->eStrideOut);
232cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
233cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
234cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
235cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
236cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void wc_x(void *usr, uint32_t idx) {
237cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
238451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams    RsForEachStubParamStruct p;
239451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams    memset(&p, 0, sizeof(p));
240451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams    p.usr = mtls->usr;
241451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams    p.usr_len = mtls->usrLen;
2423815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
2433815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    uint32_t sig = mtls->sig;
244cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
2454419977d78018a9933c7f455fe001f644f2d638bStephen Hines    outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
246cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (1) {
247cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
248cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
249cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        uint32_t xEnd = xStart + mtls->mSliceSize;
250cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        xEnd = rsMin(xEnd, mtls->xEnd);
251cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (xEnd <= xStart) {
252cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            return;
253cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
254cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
255af12ac6a08651464f8d823add667c706f993b587Steve Block        //ALOGE("usr slice %i idx %i, x %i,%i", slice, idx, xStart, xEnd);
256af12ac6a08651464f8d823add667c706f993b587Steve Block        //ALOGE("usr ptr in %p,  out %p", mtls->ptrIn, mtls->ptrOut);
25796cd1361e25f0dab881aa416d206fc4574dc602eJason Sams
25870415115431f3c52e1da44ba838962ff3b22eb69Jason Sams        p.out = mtls->ptrOut + (mtls->eStrideOut * xStart);
25970415115431f3c52e1da44ba838962ff3b22eb69Jason Sams        p.in = mtls->ptrIn + (mtls->eStrideIn * xStart);
260ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines        fn(&p, xStart, xEnd, mtls->eStrideIn, mtls->eStrideOut);
261cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
262cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
263cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
264cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid rsdScriptInvokeForEach(const Context *rsc,
265cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams                            Script *s,
26635e429ebf817130d8590d11d441a77aa697bd7d4Jason Sams                            uint32_t slot,
267cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams                            const Allocation * ain,
268cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams                            Allocation * aout,
269cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams                            const void * usr,
270cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams                            uint32_t usrLen,
271cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams                            const RsScriptCall *sc) {
272cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
27387fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal * dc = (RsdHal *)rsc->mHal.drv;
274cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
275cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    MTLaunchStruct mtls;
276cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    memset(&mtls, 0, sizeof(mtls));
277cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
2780ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams    //ALOGE("for each script %p  in %p   out %p", s, ain, aout);
2790ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams
2803815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines    DrvScript *drv = (DrvScript *)s->mHal.drv;
281a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    rsAssert(slot < drv->mExecutable->getExportForeachFuncAddrs().size());
282a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    mtls.kernel = reinterpret_cast<ForEachFunc_t>(
283a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao                      drv->mExecutable->getExportForeachFuncAddrs()[slot]);
2844419977d78018a9933c7f455fe001f644f2d638bStephen Hines    rsAssert(mtls.kernel != NULL);
285a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    mtls.sig = drv->mExecutable->getInfo().getExportForeachFuncs()[slot].second;
286a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao
287cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (ain) {
288cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.dimX = ain->getType()->getDimX();
289cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.dimY = ain->getType()->getDimY();
290cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.dimZ = ain->getType()->getDimZ();
291cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        //mtls.dimArray = ain->getType()->getDimArray();
292cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    } else if (aout) {
293cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.dimX = aout->getType()->getDimX();
294cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.dimY = aout->getType()->getDimY();
295cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.dimZ = aout->getType()->getDimZ();
296cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        //mtls.dimArray = aout->getType()->getDimArray();
297cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    } else {
298cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsc->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
299cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        return;
300cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
301bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
302cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (!sc || (sc->xEnd == 0)) {
303cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.xEnd = mtls.dimX;
304cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    } else {
305cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsAssert(sc->xStart < mtls.dimX);
306cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsAssert(sc->xEnd <= mtls.dimX);
307cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsAssert(sc->xStart < sc->xEnd);
308cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.xStart = rsMin(mtls.dimX, sc->xStart);
309cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.xEnd = rsMin(mtls.dimX, sc->xEnd);
310cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (mtls.xStart >= mtls.xEnd) return;
311cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
312cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
313cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (!sc || (sc->yEnd == 0)) {
314cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.yEnd = mtls.dimY;
315cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    } else {
316cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsAssert(sc->yStart < mtls.dimY);
317cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsAssert(sc->yEnd <= mtls.dimY);
318cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsAssert(sc->yStart < sc->yEnd);
319cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.yStart = rsMin(mtls.dimY, sc->yStart);
320cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.yEnd = rsMin(mtls.dimY, sc->yEnd);
321cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (mtls.yStart >= mtls.yEnd) return;
322cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
323cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
324cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.xEnd = rsMax((uint32_t)1, mtls.xEnd);
325cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.yEnd = rsMax((uint32_t)1, mtls.yEnd);
326cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.zEnd = rsMax((uint32_t)1, mtls.zEnd);
327cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.arrayEnd = rsMax((uint32_t)1, mtls.arrayEnd);
328cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
329eed1b156ca3e439f3d178ce99a4fa736527b15f9Stephen Hines    rsAssert(!ain || (ain->getType()->getDimZ() == 0));
330cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
331cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Context *mrsc = (Context *)rsc;
332cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Script * oldTLS = setTLS(s);
333cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
334cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.rsc = mrsc;
335cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.ain = ain;
336cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.aout = aout;
337cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.script = s;
338cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.usr = usr;
339451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams    mtls.usrLen = usrLen;
340cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.mSliceSize = 10;
341cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.mSliceNum = 0;
342cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
343cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.ptrIn = NULL;
344cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.eStrideIn = 0;
345cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (ain) {
346807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        DrvAllocation *aindrv = (DrvAllocation *)ain->mHal.drv;
34761a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        mtls.ptrIn = (const uint8_t *)aindrv->lod[0].mallocPtr;
348cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.eStrideIn = ain->getType()->getElementSizeBytes();
349807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        mtls.yStrideIn = aindrv->lod[0].stride;
350cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
351cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
352cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.ptrOut = NULL;
353cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    mtls.eStrideOut = 0;
354cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (aout) {
355807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        DrvAllocation *aoutdrv = (DrvAllocation *)aout->mHal.drv;
35661a4bb734b91ced09fbfee4214c6f253cb66e5f0Jason Sams        mtls.ptrOut = (uint8_t *)aoutdrv->lod[0].mallocPtr;
357cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        mtls.eStrideOut = aout->getType()->getElementSizeBytes();
358807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        mtls.yStrideOut = aoutdrv->lod[0].stride;
359cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
360cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
361aa152101cc4d04597d9aefc3e5a1454eaf39d2ccJason Sams    if ((dc->mWorkers.mCount > 1) && s->mHal.info.isThreadable && !dc->mInForEach) {
362aa152101cc4d04597d9aefc3e5a1454eaf39d2ccJason Sams        dc->mInForEach = true;
363cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (mtls.dimY > 1) {
3640ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams            mtls.mSliceSize = mtls.dimY / (dc->mWorkers.mCount * 4);
3650ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams            if(mtls.mSliceSize < 1) {
3660ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams                mtls.mSliceSize = 1;
3670ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams            }
3680ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams
369cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            rsdLaunchThreads(mrsc, wc_xy, &mtls);
370cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        } else {
3710ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams            mtls.mSliceSize = mtls.dimX / (dc->mWorkers.mCount * 4);
3720ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams            if(mtls.mSliceSize < 1) {
3730ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams                mtls.mSliceSize = 1;
3740ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams            }
3750ab9f9f6b1fb31cda536ae4aeaed258f78ee1447Jason Sams
376cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            rsdLaunchThreads(mrsc, wc_x, &mtls);
377cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
378aa152101cc4d04597d9aefc3e5a1454eaf39d2ccJason Sams        dc->mInForEach = false;
379cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
380af12ac6a08651464f8d823add667c706f993b587Steve Block        //ALOGE("launch 1");
381cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    } else {
382451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams        RsForEachStubParamStruct p;
383451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams        memset(&p, 0, sizeof(p));
384451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams        p.usr = mtls.usr;
385451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams        p.usr_len = mtls.usrLen;
3863815badf95a7dca8aa278e3e12f07a3924a82319Stephen Hines        uint32_t sig = mtls.sig;
387451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams
388af12ac6a08651464f8d823add667c706f993b587Steve Block        //ALOGE("launch 3");
3894419977d78018a9933c7f455fe001f644f2d638bStephen Hines        outer_foreach_t fn = (outer_foreach_t) mtls.kernel;
390451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams        for (p.ar[0] = mtls.arrayStart; p.ar[0] < mtls.arrayEnd; p.ar[0]++) {
391451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams            for (p.z = mtls.zStart; p.z < mtls.zEnd; p.z++) {
392451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams                for (p.y = mtls.yStart; p.y < mtls.yEnd; p.y++) {
393451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams                    uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * p.ar[0] +
394451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams                                      mtls.dimX * mtls.dimY * p.z +
395451cf2e16555c96eaaf9d8180e29dd97a5d6cbd7Jason Sams                                      mtls.dimX * p.y;
39670415115431f3c52e1da44ba838962ff3b22eb69Jason Sams                    p.out = mtls.ptrOut + (mtls.eStrideOut * offset);
39770415115431f3c52e1da44ba838962ff3b22eb69Jason Sams                    p.in = mtls.ptrIn + (mtls.eStrideIn * offset);
398ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines                    fn(&p, mtls.xStart, mtls.xEnd, mtls.eStrideIn,
399ee7aa2e3900f807ee41bb9735da86b3eb4cc2e70Stephen Hines                       mtls.eStrideOut);
400cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams                }
401cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            }
402cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
403cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
404cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
405cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    setTLS(oldTLS);
406cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
407cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
408cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
409cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsint rsdScriptInvokeRoot(const Context *dc, Script *script) {
410bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    DrvScript *drv = (DrvScript *)script->mHal.drv;
411cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
412cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Script * oldTLS = setTLS(script);
413cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int ret = drv->mRoot();
414cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    setTLS(oldTLS);
415cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
416cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    return ret;
417bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
418bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
419cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid rsdScriptInvokeInit(const Context *dc, Script *script) {
420bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    DrvScript *drv = (DrvScript *)script->mHal.drv;
421bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
422bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (drv->mInit) {
423bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        drv->mInit();
424bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
425bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
426bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
4274ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hinesvoid rsdScriptInvokeFreeChildren(const Context *dc, Script *script) {
4284ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines    DrvScript *drv = (DrvScript *)script->mHal.drv;
4294ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines
4304ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines    if (drv->mFreeChildren) {
4314ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines        drv->mFreeChildren();
4324ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines    }
4334ee16ffbd9d1d72e1757c9b26715597fdc044117Stephen Hines}
434bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
435cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid rsdScriptInvokeFunction(const Context *dc, Script *script,
436bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                            uint32_t slot,
437bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                            const void *params,
438bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                            size_t paramLength) {
439bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    DrvScript *drv = (DrvScript *)script->mHal.drv;
440af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("invoke %p %p %i %p %i", dc, script, slot, params, paramLength);
441bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
442cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Script * oldTLS = setTLS(script);
443a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    reinterpret_cast<void (*)(const void *, uint32_t)>(
444a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        drv->mExecutable->getExportFuncAddrs()[slot])(params, paramLength);
445cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    setTLS(oldTLS);
446bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
447bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
448bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsvoid rsdScriptSetGlobalVar(const Context *dc, const Script *script,
449bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams                           uint32_t slot, void *data, size_t dataLength) {
450bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    DrvScript *drv = (DrvScript *)script->mHal.drv;
451bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    //rsAssert(!script->mFieldIsObject[slot]);
452af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("setGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength);
453bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
454a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    int32_t *destPtr = reinterpret_cast<int32_t *>(
455a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao                          drv->mExecutable->getExportVarAddrs()[slot]);
456bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (!destPtr) {
4576598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        //ALOGV("Calling setVar on slot = %i which is null", slot);
458bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        return;
459bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
460bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
461bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    memcpy(destPtr, data, dataLength);
462bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
463bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
4642980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hinesvoid rsdScriptSetGlobalVarWithElemDims(
4652980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        const android::renderscript::Context *dc,
4662980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        const android::renderscript::Script *script,
4672980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        uint32_t slot, void *data, size_t dataLength,
4682980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        const android::renderscript::Element *elem,
4692980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        const size_t *dims, size_t dimLength) {
4702980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    DrvScript *drv = (DrvScript *)script->mHal.drv;
4712980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines
472a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    int32_t *destPtr = reinterpret_cast<int32_t *>(
473a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        drv->mExecutable->getExportVarAddrs()[slot]);
4742980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    if (!destPtr) {
4752980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        //ALOGV("Calling setVar on slot = %i which is null", slot);
4762980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        return;
4772980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    }
4782980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines
4792980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    // We want to look at dimension in terms of integer components,
4802980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    // but dimLength is given in terms of bytes.
4812980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    dimLength /= sizeof(int);
4822980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines
4832980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    // Only a single dimension is currently supported.
4842980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    rsAssert(dimLength == 1);
4852980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    if (dimLength == 1) {
4862980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        // First do the increment loop.
4872980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        size_t stride = elem->getSizeBytes();
4882980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        char *cVal = reinterpret_cast<char *>(data);
4892980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        for (size_t i = 0; i < dims[0]; i++) {
4902980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines            elem->incRefs(cVal);
4912980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines            cVal += stride;
4922980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        }
4932980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines
4942980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        // Decrement loop comes after (to prevent race conditions).
4952980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        char *oldVal = reinterpret_cast<char *>(destPtr);
4962980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        for (size_t i = 0; i < dims[0]; i++) {
4972980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines            elem->decRefs(oldVal);
4982980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines            oldVal += stride;
4992980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines        }
5002980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    }
5012980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines
5022980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines    memcpy(destPtr, data, dataLength);
5032980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines}
5042980f07d3dbbca727e8efe24ace7e7928a935648Stephen Hines
505807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Samsvoid rsdScriptSetGlobalBind(const Context *dc, const Script *script, uint32_t slot, Allocation *data) {
506bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    DrvScript *drv = (DrvScript *)script->mHal.drv;
507807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
508bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    //rsAssert(!script->mFieldIsObject[slot]);
509af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("setGlobalBind %p %p %i %p", dc, script, slot, data);
510bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
511a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    int32_t *destPtr = reinterpret_cast<int32_t *>(
512a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao                          drv->mExecutable->getExportVarAddrs()[slot]);
513bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (!destPtr) {
5146598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        //ALOGV("Calling setVar on slot = %i which is null", slot);
515bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        return;
516bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
517bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
518807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    void *ptr = NULL;
519807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    drv->mBoundAllocs[slot] = data;
520807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    if(data) {
521807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        DrvAllocation *allocDrv = (DrvAllocation *)data->mHal.drv;
522807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        ptr = allocDrv->lod[0].mallocPtr;
523807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
524807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    memcpy(destPtr, &ptr, sizeof(void *));
525bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
526bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
527bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsvoid rsdScriptSetGlobalObj(const Context *dc, const Script *script, uint32_t slot, ObjectBase *data) {
528bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    DrvScript *drv = (DrvScript *)script->mHal.drv;
529bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    //rsAssert(script->mFieldIsObject[slot]);
530af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("setGlobalObj %p %p %i %p", dc, script, slot, data);
531bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
532a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    int32_t *destPtr = reinterpret_cast<int32_t *>(
533a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao                          drv->mExecutable->getExportVarAddrs()[slot]);
534bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (!destPtr) {
5356598201f1c4f409defac9a5af789fb53a7cc00f8Steve Block        //ALOGV("Calling setVar on slot = %i which is null", slot);
536bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        return;
537bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
538bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
53987fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    rsrSetObject(dc, script, (ObjectBase **)destPtr, data);
540bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
541bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
542bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsvoid rsdScriptDestroy(const Context *dc, Script *script) {
543bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    DrvScript *drv = (DrvScript *)script->mHal.drv;
544bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
545a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    if (drv == NULL) {
546a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        return;
547a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    }
548a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao
549a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    if (drv->mExecutable) {
550a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        Vector<void *>::const_iterator var_addr_iter =
551a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao            drv->mExecutable->getExportVarAddrs().begin();
552a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        Vector<void *>::const_iterator var_addr_end =
553a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao            drv->mExecutable->getExportVarAddrs().end();
554a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao
555a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_iter =
556a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao            drv->mExecutable->getInfo().getObjectSlots().begin();
557a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_end =
558a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao            drv->mExecutable->getInfo().getObjectSlots().end();
559a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao
560a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao        while ((var_addr_iter != var_addr_end) &&
561a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao               (is_object_iter != is_object_end)) {
562a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao            // The field address can be NULL if the script-side has optimized
563a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao            // the corresponding global variable away.
564a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao            ObjectBase **obj_addr =
565a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao                reinterpret_cast<ObjectBase **>(*var_addr_iter);
566a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao            if (*is_object_iter) {
567a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao                if (*var_addr_iter != NULL) {
568a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao                    rsrClearObject(dc, script, obj_addr);
5698d43eafdd2684b7bcb2554e65676dc914b7eabd7Stephen Hines                }
570bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams            }
571a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao            var_addr_iter++;
572a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao            is_object_iter++;
573bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        }
574070cb235d9f094048c0260aa72d5acf61ed840a3Stephen Hines    }
575070cb235d9f094048c0260aa72d5acf61ed840a3Stephen Hines
576a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    delete drv->mCompilerContext;
577a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    delete drv->mCompilerDriver;
578a3af2cd3cc684aee2a090475f797936f3bd1b8cbShih-wei Liao    delete drv->mExecutable;
579807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    delete[] drv->mBoundAllocs;
580bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    free(drv);
581bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    script->mHal.drv = NULL;
582bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
583807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
584807fdc4b6f3fb893015ee136565d6151bb2332d3Jason SamsAllocation * rsdScriptGetAllocationForPointer(const android::renderscript::Context *dc,
585807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams                                              const android::renderscript::Script *sc,
586807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams                                              const void *ptr) {
587807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    DrvScript *drv = (DrvScript *)sc->mHal.drv;
588807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    if (!ptr) {
589807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        return NULL;
590807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
591807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
592807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    for (uint32_t ct=0; ct < sc->mHal.info.exportedVariableCount; ct++) {
593807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        Allocation *a = drv->mBoundAllocs[ct];
594807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        if (!a) continue;
595807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        DrvAllocation *adrv = (DrvAllocation *)a->mHal.drv;
596807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        if (adrv->lod[0].mallocPtr == ptr) {
597807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams            return a;
598807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams        }
599807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    }
600807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    ALOGE("rsGetAllocation, failed to find %p", ptr);
601807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    return NULL;
602807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams}
603807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams
604