rsCpuScript.cpp revision b58d9adf52f0216c0281c749023bdd5b52236875
1709a0978ae141198018ca9769f8d96292a8928e6Jason Sams/*
2709a0978ae141198018ca9769f8d96292a8928e6Jason Sams * Copyright (C) 2011-2012 The Android Open Source Project
3709a0978ae141198018ca9769f8d96292a8928e6Jason Sams *
4709a0978ae141198018ca9769f8d96292a8928e6Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5709a0978ae141198018ca9769f8d96292a8928e6Jason Sams * you may not use this file except in compliance with the License.
6709a0978ae141198018ca9769f8d96292a8928e6Jason Sams * You may obtain a copy of the License at
7709a0978ae141198018ca9769f8d96292a8928e6Jason Sams *
8709a0978ae141198018ca9769f8d96292a8928e6Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9709a0978ae141198018ca9769f8d96292a8928e6Jason Sams *
10709a0978ae141198018ca9769f8d96292a8928e6Jason Sams * Unless required by applicable law or agreed to in writing, software
11709a0978ae141198018ca9769f8d96292a8928e6Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12709a0978ae141198018ca9769f8d96292a8928e6Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13709a0978ae141198018ca9769f8d96292a8928e6Jason Sams * See the License for the specific language governing permissions and
14709a0978ae141198018ca9769f8d96292a8928e6Jason Sams * limitations under the License.
15709a0978ae141198018ca9769f8d96292a8928e6Jason Sams */
16709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
17709a0978ae141198018ca9769f8d96292a8928e6Jason Sams#include "rsCpuCore.h"
18709a0978ae141198018ca9769f8d96292a8928e6Jason Sams#include "rsCpuScript.h"
19709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
200b575de8ed0b628d84d256f5846500b0385979bdTim Murray#ifndef RS_SERVER
21709a0978ae141198018ca9769f8d96292a8928e6Jason Sams#include "utils/Vector.h"
22709a0978ae141198018ca9769f8d96292a8928e6Jason Sams#include "utils/Timers.h"
23709a0978ae141198018ca9769f8d96292a8928e6Jason Sams#include "utils/StopWatch.h"
240b575de8ed0b628d84d256f5846500b0385979bdTim Murray#endif
25709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
26110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
27110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <dlfcn.h>
28110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <stdio.h>
29110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <string.h>
30110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
31110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/BCCContext.h>
32110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSCompilerDriver.h>
33110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSExecutable.h>
34110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSInfo.h>
35b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <bcinfo/MetadataExtractor.h>
36ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    #include <cutils/properties.h>
37b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
38b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <sys/types.h>
39b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <sys/wait.h>
40b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <unistd.h>
41110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
42709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
43ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#ifndef RS_COMPATIBILITY_LIB
44ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hinesnamespace {
45ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hinesstatic bool is_force_recompile() {
46ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#ifdef RS_SERVER
47ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  return false;
48ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#else
49ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  char buf[PROPERTY_VALUE_MAX];
50ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
51ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  // Re-compile if floating point precision has been overridden.
52ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  property_get("debug.rs.precision", buf, "");
53ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  if (buf[0] != '\0') {
54ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return true;
55ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  }
56ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
57ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  // Re-compile if debug.rs.forcerecompile is set.
58ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  property_get("debug.rs.forcerecompile", buf, "0");
59ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  if ((::strcmp(buf, "1") == 0) || (::strcmp(buf, "true") == 0)) {
60ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return true;
61ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  } else {
62ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return false;
63ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  }
64ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#endif  // RS_SERVER
65ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines}
66b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
67b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines//#define EXTERNAL_BCC_COMPILER 1
68b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#ifdef EXTERNAL_BCC_COMPILER
69b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hinesconst static char *BCC_EXE_PATH = "/system/bin/bcc";
70b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
71b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hinesstatic bool compileBitcode(const char *cacheDir,
72b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           const char *resName,
73b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           const char *bitcode,
74b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           size_t bitcodeSize,
75b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           const char *core_lib) {
76b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    rsAssert(cacheDir && resName && bitcode && bitcodeSize && core_lib);
77b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
78b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    android::String8 bcFilename(cacheDir);
79b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    bcFilename.append("/");
80b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    bcFilename.append(resName);
81b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    bcFilename.append(".bc");
82b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    FILE *bcfile = fopen(bcFilename.string(), "w");
83b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (!bcfile) {
84b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not write to %s", bcFilename.string());
85b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
86b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
87b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    size_t nwritten = fwrite(bitcode, 1, bitcodeSize, bcfile);
88b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    fclose(bcfile);
89b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (nwritten != bitcodeSize) {
90b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not write %zu bytes to %s", bitcodeSize,
91b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              bcFilename.string());
92b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
93b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
94b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
95b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    pid_t pid = fork();
96b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    switch (pid) {
97b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case -1: {  // Error occurred (we attempt no recovery)
98b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Couldn't fork for bcc compiler execution");
99b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
100b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
101b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case 0: {  // Child process
102b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        // Execute the bcc compiler.
103b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        execl(BCC_EXE_PATH,
104b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              BCC_EXE_PATH,
105b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              "-o", resName,
106b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              "-output_path", cacheDir,
107b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              "-bclib", core_lib,
108b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              bcFilename.string(),
109b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              (char *) NULL);
110b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("execl() failed: %s", strerror(errno));
111b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        abort();
112b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
113b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
114b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    default: {  // Parent process (actual driver)
115b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        // Wait on child process to finish compiling the source.
116b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        int status = 0;
117b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        pid_t w = waitpid(pid, &status, 0);
118b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        if (w == -1) {
119b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            ALOGE("Could not wait for bcc compiler");
120b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            return false;
121b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        }
122b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
123b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
124b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            return true;
125b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        }
126b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
127b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("bcc compiler terminated unexpectedly");
128b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
129b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
130b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
131b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines}
132b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#endif  // EXTERNAL_BCC_COMPILER
133b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
134ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines}  // namespace
135ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#endif  // !defined(RS_COMPATIBILITY_LIB)
136ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
137709a0978ae141198018ca9769f8d96292a8928e6Jason Samsnamespace android {
138709a0978ae141198018ca9769f8d96292a8928e6Jason Samsnamespace renderscript {
139709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
140709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
141110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
142110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define MAXLINE 500
143110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define MAKE_STR_HELPER(S) #S
144110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define MAKE_STR(S) MAKE_STR_HELPER(S)
145110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_VAR_STR "exportVarCount: "
146110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_VAR_STR_LEN strlen(EXPORT_VAR_STR)
147110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_FUNC_STR "exportFuncCount: "
148110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_FUNC_STR_LEN strlen(EXPORT_FUNC_STR)
149110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_FOREACH_STR "exportForEachCount: "
150110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_FOREACH_STR_LEN strlen(EXPORT_FOREACH_STR)
151110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define OBJECT_SLOT_STR "objectSlotCount: "
152110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define OBJECT_SLOT_STR_LEN strlen(OBJECT_SLOT_STR)
153110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
154110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams// Copy up to a newline or size chars from str -> s, updating str
155110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams// Returns s when successful and NULL when '\0' is finally reached.
156110f181b7966212a36ef18016f9b81c7322d0a2fJason Samsstatic char* strgets(char *s, int size, const char **ppstr) {
157110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (!ppstr || !*ppstr || **ppstr == '\0' || size < 1) {
158110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        return NULL;
159110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
160110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
161110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int i;
162110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    for (i = 0; i < (size - 1); i++) {
163110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        s[i] = **ppstr;
164110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        (*ppstr)++;
165110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (s[i] == '\0') {
166110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            return s;
167110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        } else if (s[i] == '\n') {
168110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            s[i+1] = '\0';
169110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            return s;
170110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
171110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
172110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
173110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // size has been exceeded.
174110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    s[i] = '\0';
175110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
176110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    return s;
177110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams}
178110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
179709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
180709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptImpl::RsdCpuScriptImpl(RsdCpuReferenceImpl *ctx, const Script *s) {
181709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx = ctx;
182709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mScript = s;
183709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
184110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
185110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mScriptSO = NULL;
186110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mInvokeFunctions = NULL;
187110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mForEachFunctions = NULL;
188110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mFieldAddress = NULL;
189110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mFieldIsObject = NULL;
190110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mForEachSignatures = NULL;
191110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
192110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCompilerContext = NULL;
193110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCompilerDriver = NULL;
194110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mExecutable = NULL;
195110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
196110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
197709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRoot = NULL;
198709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRootExpand = NULL;
199709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mInit = NULL;
200709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mFreeChildren = NULL;
201709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
202709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
203709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mBoundAllocs = NULL;
204709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mIntrinsicData = NULL;
205709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mIsThreadable = true;
206709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
207709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
208709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
209709a0978ae141198018ca9769f8d96292a8928e6Jason Samsbool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir,
210709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                            uint8_t const *bitcode, size_t bitcodeSize,
211709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                            uint32_t flags) {
212709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc);
213709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("rsdScriptInit %p %p", rsc, script);
214709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
215709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->lockMutex();
216709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
217110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
218ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    bcc::RSExecutable *exec = NULL;
219709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
220709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerContext = NULL;
221709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver = NULL;
222709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mExecutable = NULL;
223709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
224709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerContext = new bcc::BCCContext();
225709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerContext == NULL) {
226709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGE("bcc: FAILS to create compiler context (out of memory)");
227709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->unlockMutex();
228709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return false;
229709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
230709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
231709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver = new bcc::RSCompilerDriver();
232709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerDriver == NULL) {
233709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGE("bcc: FAILS to create compiler driver (out of memory)");
234709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->unlockMutex();
235709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return false;
236709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
237709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
238709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver->setRSRuntimeLookupFunction(lookupRuntimeStub);
239709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver->setRSRuntimeLookupContext(this);
240709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
241b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    // Run any compiler setup functions we have been provided with.
242b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    RSSetupCompilerCallback setupCompilerCallback =
243b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines            mCtx->getSetupCompilerCallback();
244b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    if (setupCompilerCallback != NULL) {
245b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines        setupCompilerCallback(mCompilerDriver);
246b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    }
247b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines
248b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    const char *core_lib = bcc::RSInfo::LibCLCorePath;
249b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
250b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    bcinfo::MetadataExtractor ME((const char *) bitcode, bitcodeSize);
251b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (!ME.extract()) {
252b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not extract metadata from bitcode");
253b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
254b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
255b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
256b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    enum bcinfo::RSFloatPrecision prec = ME.getRSFloatPrecision();
257b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    switch (prec) {
258b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case bcinfo::RS_FP_Imprecise:
259b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case bcinfo::RS_FP_Relaxed:
260b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#if defined(ARCH_ARM_HAVE_NEON)
261b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        // NEON-capable devices can use an accelerated math library for all
262b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        // reduced precision scripts.
263b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        core_lib = bcc::RSInfo::LibCLCoreNEONPath;
264b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#endif
265b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        break;
266b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case bcinfo::RS_FP_Full:
267b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        break;
268b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    default:
269b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Unknown precision for bitcode");
270b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
271b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
272b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
273b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#if defined(ARCH_X86_HAVE_SSE2)
274b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    // SSE2- or above capable devices will use an optimized library.
275b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    core_lib = bcc::RSInfo::LibCLCoreX86Path;
276b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#endif
277b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
2781d476620399d54774e4fd386c1d23cc583d49522Stephen Hines    RSSelectRTCallback selectRTCallback = mCtx->getSelectRTCallback();
2791d476620399d54774e4fd386c1d23cc583d49522Stephen Hines    if (selectRTCallback != NULL) {
2801d476620399d54774e4fd386c1d23cc583d49522Stephen Hines        core_lib = selectRTCallback((const char *)bitcode, bitcodeSize);
2811d476620399d54774e4fd386c1d23cc583d49522Stephen Hines    }
282cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines
283cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines    if (mCtx->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
284cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines        // Use the libclcore_debug.bc instead of the default library.
285cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines        core_lib = bcc::RSInfo::LibCLCoreDebugPath;
286f47e8b4b86bf194e65398032f3f5f47a6da89f3fStephen Hines        mCompilerDriver->setDebugContext(true);
287ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        // Skip the cache lookup
288ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    } else if (!is_force_recompile()) {
289ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        // Attempt to just load the script from cache first if we can.
290ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        exec = mCompilerDriver->loadScript(cacheDir, resName,
291ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                           (const char *)bitcode, bitcodeSize);
292ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    }
293ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
294ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    if (exec == NULL) {
295b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#ifdef EXTERNAL_BCC_COMPILER
296b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        bool built = compileBitcode(cacheDir, resName, (const char *)bitcode,
297b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                                    bitcodeSize, core_lib);
298b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#else
299ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        bool built = mCompilerDriver->build(*mCompilerContext, cacheDir,
300ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                            resName, (const char *)bitcode,
301ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                            bitcodeSize, core_lib,
302ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                            mCtx->getLinkRuntimeCallback());
303b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#endif  // EXTERNAL_BCC_COMPILER
304ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        if (built) {
305ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines            exec = mCompilerDriver->loadScript(cacheDir, resName,
306ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                               (const char *)bitcode,
307ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                               bitcodeSize);
308ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        }
309cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines    }
310709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
311709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (exec == NULL) {
312709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGE("bcc: FAILS to prepare executable for '%s'", resName);
313709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->unlockMutex();
314709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return false;
315709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
316709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
317709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mExecutable = exec;
318709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
319709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    exec->setThreadable(mIsThreadable);
320709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!exec->syncInfo()) {
321709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGW("bcc: FAILS to synchronize the RS info file to the disk");
322709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
323709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
324709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRoot = reinterpret_cast<int (*)()>(exec->getSymbolAddress("root"));
325709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRootExpand =
326709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        reinterpret_cast<int (*)()>(exec->getSymbolAddress("root.expand"));
327709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mInit = reinterpret_cast<void (*)()>(exec->getSymbolAddress("init"));
328709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mFreeChildren =
329709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        reinterpret_cast<void (*)()>(exec->getSymbolAddress(".rs.dtor"));
330709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
331709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
3321d476620399d54774e4fd386c1d23cc583d49522Stephen Hines    const bcc::RSInfo *info = &mExecutable->getInfo();
333709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (info->getExportVarNames().size()) {
334709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mBoundAllocs = new Allocation *[info->getExportVarNames().size()];
335709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        memset(mBoundAllocs, 0, sizeof(void *) * info->getExportVarNames().size());
336709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
337709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
338110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
339110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
3400b575de8ed0b628d84d256f5846500b0385979bdTim Murray#ifndef RS_SERVER
341110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    String8 scriptSOName(cacheDir);
342110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    scriptSOName = scriptSOName.getPathDir();
343110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    scriptSOName.appendPath("lib");
344110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    scriptSOName.append("/librs.");
3450b575de8ed0b628d84d256f5846500b0385979bdTim Murray#else
3460b575de8ed0b628d84d256f5846500b0385979bdTim Murray    String8 scriptSOName("lib");
3470b575de8ed0b628d84d256f5846500b0385979bdTim Murray#endif
348110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    scriptSOName.append(resName);
349110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    scriptSOName.append(".so");
350110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
351110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    //script->mHal.drv = drv;
352110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
353110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    //ALOGV("Opening up shared object: %s", scriptSOName.string());
354110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mScriptSO = dlopen(scriptSOName.string(), RTLD_NOW | RTLD_LOCAL);
355110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO == NULL) {
356110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        ALOGE("Unable to open shared library (%s): %s",
357110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams              scriptSOName.string(), dlerror());
358110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
359110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        // One final attempt to find the library in "/system/lib".
360110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        // We do this to allow bundled applications to use the compatibility
361110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        // library fallback path. Those applications don't have a private
362110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        // library path, so they need to install to the system directly.
363110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        String8 scriptSONameSystem("/system/lib/librs.");
364110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        scriptSONameSystem.append(resName);
365110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        scriptSONameSystem.append(".so");
366110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mScriptSO = dlopen(scriptSONameSystem.string(), RTLD_NOW | RTLD_LOCAL);
367110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mScriptSO == NULL) {
368110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Unable to open system shared library (%s): %s",
369110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                  scriptSONameSystem.string(), dlerror());
370110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
371110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
372110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
373110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
374110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
375110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        char line[MAXLINE];
376110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mRoot = (RootFunc_t) dlsym(mScriptSO, "root");
377110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mRoot) {
378110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found root(): %p", mRoot);
379110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
380110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mRootExpand = (RootFunc_t) dlsym(mScriptSO, "root.expand");
381110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mRootExpand) {
382110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found root.expand(): %p", mRootExpand);
383110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
384110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mInit = (InvokeFunc_t) dlsym(mScriptSO, "init");
385110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mInit) {
386110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found init(): %p", mInit);
387110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
388110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mFreeChildren = (InvokeFunc_t) dlsym(mScriptSO, ".rs.dtor");
389110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mFreeChildren) {
390110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found .rs.dtor(): %p", mFreeChildren);
391110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
392110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
393110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        const char *rsInfo = (const char *) dlsym(mScriptSO, ".rs.info");
394110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (rsInfo) {
395110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found .rs.info(): %p - %s", rsInfo, rsInfo);
396110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
397110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
398110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t varCount = 0;
399110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
400110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
401110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
402110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, EXPORT_VAR_STR "%zu", &varCount) != 1) {
403110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid export var count!: %s", line);
404110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
405110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
406110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
407110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mExportedVariableCount = varCount;
408110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        //ALOGE("varCount: %zu", varCount);
409110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (varCount > 0) {
410110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            // Start by creating/zeroing this member, since we don't want to
411110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            // accidentally clean up invalid pointers later (if we error out).
412110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mFieldIsObject = new bool[varCount];
413110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mFieldIsObject == NULL) {
414110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
415110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
416110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            memset(mFieldIsObject, 0, varCount * sizeof(*mFieldIsObject));
417110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mFieldAddress = new void*[varCount];
418110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mFieldAddress == NULL) {
419110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
420110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
421110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < varCount; ++i) {
422110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
423110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
424110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
425110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                char *c = strrchr(line, '\n');
426110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (c) {
427110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    *c = '\0';
428110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
429110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mFieldAddress[i] = dlsym(mScriptSO, line);
430110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (mFieldAddress[i] == NULL) {
431110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Failed to find variable address for %s: %s",
432110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                          line, dlerror());
433110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    // Not a critical error if we don't find a global variable.
434110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
435110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                else {
436110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //ALOGE("Found variable %s at %p", line,
437110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //mFieldAddress[i]);
438110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
439110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
440110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
441110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
442110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t funcCount = 0;
443110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
444110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
445110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
446110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, EXPORT_FUNC_STR "%zu", &funcCount) != 1) {
447110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid export func count!: %s", line);
448110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
449110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
450110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
451110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mExportedFunctionCount = funcCount;
452110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        //ALOGE("funcCount: %zu", funcCount);
453110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
454110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (funcCount > 0) {
455110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mInvokeFunctions = new InvokeFunc_t[funcCount];
456110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mInvokeFunctions == NULL) {
457110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
458110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
459110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < funcCount; ++i) {
460110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
461110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
462110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
463110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                char *c = strrchr(line, '\n');
464110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (c) {
465110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    *c = '\0';
466110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
467110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
468110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mInvokeFunctions[i] = (InvokeFunc_t) dlsym(mScriptSO, line);
469110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (mInvokeFunctions[i] == NULL) {
470110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Failed to get function address for %s(): %s",
471110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                          line, dlerror());
472110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
473110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
474110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                else {
475110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //ALOGE("Found InvokeFunc_t %s at %p", line, mInvokeFunctions[i]);
476110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
477110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
478110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
479110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
480110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t forEachCount = 0;
481110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
482110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
483110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
484110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, EXPORT_FOREACH_STR "%zu", &forEachCount) != 1) {
485110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid export forEach count!: %s", line);
486110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
487110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
488110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
489110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (forEachCount > 0) {
490110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
491110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mForEachSignatures = new uint32_t[forEachCount];
492110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mForEachSignatures == NULL) {
493110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
494110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
495110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mForEachFunctions = new ForEachFunc_t[forEachCount];
496110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mForEachFunctions == NULL) {
497110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
498110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
499110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < forEachCount; ++i) {
500110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                unsigned int tmpSig = 0;
501110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                char tmpName[MAXLINE];
502110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
503110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
504110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
505110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
506110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (sscanf(line, "%u - %" MAKE_STR(MAXLINE) "s",
507110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                           &tmpSig, tmpName) != 2) {
508110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Invalid export forEach!: %s", line);
509110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
510110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
511110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
512110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                // Lookup the expanded ForEach kernel.
513110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                strncat(tmpName, ".expand", MAXLINE-1-strlen(tmpName));
514110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mForEachSignatures[i] = tmpSig;
515110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mForEachFunctions[i] =
516110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                        (ForEachFunc_t) dlsym(mScriptSO, tmpName);
517ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                if (i != 0 && mForEachFunctions[i] == NULL) {
518110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    // Ignore missing root.expand functions.
519110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    // root() is always specified at location 0.
520ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                    ALOGE("Failed to find forEach function address for %s: %s",
521ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                          tmpName, dlerror());
522ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                    goto error;
523110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
524110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                else {
525110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //ALOGE("Found forEach %s at %p", tmpName, mForEachFunctions[i]);
526110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
527110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
528110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
529110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
530110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t objectSlotCount = 0;
531110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
532110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
533110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
534110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, OBJECT_SLOT_STR "%zu", &objectSlotCount) != 1) {
535110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid object slot count!: %s", line);
536110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
537110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
538110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
539110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (objectSlotCount > 0) {
540110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            rsAssert(varCount > 0);
541110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < objectSlotCount; ++i) {
542110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                uint32_t varNum = 0;
543110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
544110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
545110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
546110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (sscanf(line, "%u", &varNum) != 1) {
547110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Invalid object slot!: %s", line);
548110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
549110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
550110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
551110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (varNum < varCount) {
552110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    mFieldIsObject[varNum] = true;
553110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
554110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
555110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
556110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
557110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (varCount > 0) {
558110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mBoundAllocs = new Allocation *[varCount];
559110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            memset(mBoundAllocs, 0, varCount * sizeof(*mBoundAllocs));
560110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
561110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
562110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mScriptSO == (void*)1) {
563110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //rsdLookupRuntimeStub(script, "acos");
564110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
565110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
566110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
567110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
568709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->unlockMutex();
569709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return true;
570110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
571110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
572110f181b7966212a36ef18016f9b81c7322d0a2fJason Samserror:
573110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
574110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCtx->unlockMutex();
575110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mInvokeFunctions;
576110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mForEachFunctions;
577110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mFieldAddress;
578110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mFieldIsObject;
579110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mForEachSignatures;
580110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mBoundAllocs;
581110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
582110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        dlclose(mScriptSO);
583110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
584110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    return false;
585110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
586709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
587709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
588709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::populateScript(Script *script) {
589110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
590709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    const bcc::RSInfo *info = &mExecutable->getInfo();
591709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
592709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // Copy info over to runtime
593709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedFunctionCount = info->getExportFuncNames().size();
594709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedVariableCount = info->getExportVarNames().size();
59547935ac8e3dd619f758abd576605a564e33bb59cTobias Grosser    script->mHal.info.exportedForeachFuncList = info->getExportForeachFuncs().array();
596709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedPragmaCount = info->getPragmas().size();
597709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedPragmaKeyList =
598709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const_cast<const char**>(mExecutable->getPragmaKeys().array());
599709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedPragmaValueList =
600709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const_cast<const char**>(mExecutable->getPragmaValues().array());
601709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
602709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mRootExpand) {
603709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        script->mHal.info.root = mRootExpand;
604709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
605709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        script->mHal.info.root = mRoot;
606709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
607110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
608110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // Copy info over to runtime
609110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedFunctionCount = mExportedFunctionCount;
610110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedVariableCount = mExportedVariableCount;
611110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedPragmaCount = 0;
612110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedPragmaKeyList = 0;
613110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedPragmaValueList = 0;
614110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
615110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // Bug, need to stash in metadata
616110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mRootExpand) {
617110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        script->mHal.info.root = mRootExpand;
618110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    } else {
619110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        script->mHal.info.root = mRoot;
620110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
621110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
622709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
623709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
624709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
625709a0978ae141198018ca9769f8d96292a8928e6Jason Samstypedef void (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
626709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
627709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::forEachMtlsSetup(const Allocation * ain, Allocation * aout,
628709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        const void * usr, uint32_t usrLen,
629709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        const RsScriptCall *sc,
630709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        MTLaunchStruct *mtls) {
631709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
632709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memset(mtls, 0, sizeof(MTLaunchStruct));
633709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
6343a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    // possible for this to occur if IO_OUTPUT/IO_INPUT with no bound surface
6353a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    if (ain && (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr == NULL) {
6363a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
6373a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray        return;
6383a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    }
6393a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    if (aout && (const uint8_t *)aout->mHal.drvState.lod[0].mallocPtr == NULL) {
6403a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
6413a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray        return;
6423a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    }
6433a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray
644709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (ain) {
645709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimX = ain->getType()->getDimX();
646709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimY = ain->getType()->getDimY();
647709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimZ = ain->getType()->getDimZ();
648709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mtls->dimArray = ain->getType()->getDimArray();
649709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else if (aout) {
650709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimX = aout->getType()->getDimX();
651709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimY = aout->getType()->getDimY();
652709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimZ = aout->getType()->getDimZ();
653709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mtls->dimArray = aout->getType()->getDimArray();
654709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
655709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
656709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
657709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
658709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
659709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!sc || (sc->xEnd == 0)) {
660709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->xEnd = mtls->fep.dimX;
661709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
662709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->xStart < mtls->fep.dimX);
663709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->xEnd <= mtls->fep.dimX);
664709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->xStart < sc->xEnd);
665709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->xStart = rsMin(mtls->fep.dimX, sc->xStart);
666709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->xEnd = rsMin(mtls->fep.dimX, sc->xEnd);
667709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (mtls->xStart >= mtls->xEnd) return;
668709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
669709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
670709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!sc || (sc->yEnd == 0)) {
671709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->yEnd = mtls->fep.dimY;
672709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
673709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->yStart < mtls->fep.dimY);
674709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->yEnd <= mtls->fep.dimY);
675709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->yStart < sc->yEnd);
676709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->yStart = rsMin(mtls->fep.dimY, sc->yStart);
677709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->yEnd = rsMin(mtls->fep.dimY, sc->yEnd);
678709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (mtls->yStart >= mtls->yEnd) return;
679709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
680709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
681d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray    if (!sc || (sc->zEnd == 0)) {
682d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        mtls->zEnd = mtls->fep.dimZ;
683d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray    } else {
684d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        rsAssert(sc->zStart < mtls->fep.dimZ);
685d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        rsAssert(sc->zEnd <= mtls->fep.dimZ);
686d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        rsAssert(sc->zStart < sc->zEnd);
687d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        mtls->zStart = rsMin(mtls->fep.dimZ, sc->zStart);
688d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        mtls->zEnd = rsMin(mtls->fep.dimZ, sc->zEnd);
689d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        if (mtls->zStart >= mtls->zEnd) return;
690d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray    }
691d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray
692709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->xEnd = rsMax((uint32_t)1, mtls->xEnd);
693709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->yEnd = rsMax((uint32_t)1, mtls->yEnd);
694709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->zEnd = rsMax((uint32_t)1, mtls->zEnd);
695709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->arrayEnd = rsMax((uint32_t)1, mtls->arrayEnd);
696709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
697709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(!ain || (ain->getType()->getDimZ() == 0));
698709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
699709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->rsc = mCtx;
700709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->ain = ain;
701709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->aout = aout;
702709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.usr = usr;
703709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.usrLen = usrLen;
704709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->mSliceSize = 1;
705709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->mSliceNum = 0;
706709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
707709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.ptrIn = NULL;
708709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.eStrideIn = 0;
709709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->isThreadable = mIsThreadable;
710709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
711709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (ain) {
712709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.ptrIn = (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr;
713709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.eStrideIn = ain->getType()->getElementSizeBytes();
714709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.yStrideIn = ain->mHal.drvState.lod[0].stride;
715709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
716709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
717709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.ptrOut = NULL;
718709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.eStrideOut = 0;
719709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (aout) {
720709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.ptrOut = (uint8_t *)aout->mHal.drvState.lod[0].mallocPtr;
721709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.eStrideOut = aout->getType()->getElementSizeBytes();
722709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.yStrideOut = aout->mHal.drvState.lod[0].stride;
723709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
724709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
725709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
726709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
727709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeForEach(uint32_t slot,
728709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const Allocation * ain,
729709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     Allocation * aout,
730709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const void * usr,
731709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     uint32_t usrLen,
732709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const RsScriptCall *sc) {
733709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
734709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    MTLaunchStruct mtls;
735709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    forEachMtlsSetup(ain, aout, usr, usrLen, sc, &mtls);
736709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    forEachKernelSetup(slot, &mtls);
737709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
738709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
739709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->launchThreads(ain, aout, sc, &mtls);
740709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
741709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
742709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
743709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::forEachKernelSetup(uint32_t slot, MTLaunchStruct *mtls) {
744709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->script = this;
745709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.slot = slot;
746110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
747709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(slot < mExecutable->getExportForeachFuncAddrs().size());
748709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->kernel = reinterpret_cast<ForEachFunc_t>(
749709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                      mExecutable->getExportForeachFuncAddrs()[slot]);
750709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(mtls->kernel != NULL);
751709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->sig = mExecutable->getInfo().getExportForeachFuncs()[slot].second;
752110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
753110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mtls->kernel = reinterpret_cast<ForEachFunc_t>(mForEachFunctions[slot]);
754110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    rsAssert(mtls->kernel != NULL);
755110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mtls->sig = mForEachSignatures[slot];
756110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
757709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
758709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
759709a0978ae141198018ca9769f8d96292a8928e6Jason Samsint RsdCpuScriptImpl::invokeRoot() {
760709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
761709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int ret = mRoot();
762709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
763709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return ret;
764709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
765709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
766709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeInit() {
767709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mInit) {
768709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mInit();
769709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
770709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
771709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
772709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeFreeChildren() {
773709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mFreeChildren) {
774709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mFreeChildren();
775709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
776709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
777709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
778709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeFunction(uint32_t slot, const void *params,
779709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                      size_t paramLength) {
780709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("invoke %p %p %i %p %i", dc, script, slot, params, paramLength);
781709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
782709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
783709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    reinterpret_cast<void (*)(const void *, uint32_t)>(
784110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
785709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mExecutable->getExportFuncAddrs()[slot])(params, paramLength);
786110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
787110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mInvokeFunctions[slot])(params, paramLength);
788110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
789709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
790709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
791709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
792709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalVar(uint32_t slot, const void *data, size_t dataLength) {
793709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(!script->mFieldIsObject[slot]);
794709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("setGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength);
795709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
796709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //if (mIntrinsicID) {
797709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mIntrinsicFuncs.setVar(dc, script, drv->mIntrinsicData, slot, data, dataLength);
798709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //return;
799709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //}
800709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
801110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
802709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
803709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                          mExecutable->getExportVarAddrs()[slot]);
804110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
805110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
806110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
807709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
808709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
809709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
810709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
811709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
812709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, data, dataLength);
813709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
814709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
8159c64239ebbfa4170190ede812e69150035e008e0Tim Murrayvoid RsdCpuScriptImpl::getGlobalVar(uint32_t slot, void *data, size_t dataLength) {
8169c64239ebbfa4170190ede812e69150035e008e0Tim Murray    //rsAssert(!script->mFieldIsObject[slot]);
8179c64239ebbfa4170190ede812e69150035e008e0Tim Murray    //ALOGE("getGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength);
8189c64239ebbfa4170190ede812e69150035e008e0Tim Murray
8199c64239ebbfa4170190ede812e69150035e008e0Tim Murray#ifndef RS_COMPATIBILITY_LIB
8209c64239ebbfa4170190ede812e69150035e008e0Tim Murray    int32_t *srcPtr = reinterpret_cast<int32_t *>(
8219c64239ebbfa4170190ede812e69150035e008e0Tim Murray                          mExecutable->getExportVarAddrs()[slot]);
8229c64239ebbfa4170190ede812e69150035e008e0Tim Murray#else
8239c64239ebbfa4170190ede812e69150035e008e0Tim Murray    int32_t *srcPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
8249c64239ebbfa4170190ede812e69150035e008e0Tim Murray#endif
8259c64239ebbfa4170190ede812e69150035e008e0Tim Murray    if (!srcPtr) {
8269c64239ebbfa4170190ede812e69150035e008e0Tim Murray        //ALOGV("Calling setVar on slot = %i which is null", slot);
8279c64239ebbfa4170190ede812e69150035e008e0Tim Murray        return;
8289c64239ebbfa4170190ede812e69150035e008e0Tim Murray    }
8299c64239ebbfa4170190ede812e69150035e008e0Tim Murray    memcpy(data, srcPtr, dataLength);
8309c64239ebbfa4170190ede812e69150035e008e0Tim Murray}
8319c64239ebbfa4170190ede812e69150035e008e0Tim Murray
8329c64239ebbfa4170190ede812e69150035e008e0Tim Murray
833709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalVarWithElemDims(uint32_t slot, const void *data, size_t dataLength,
834709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                                const Element *elem,
835709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                                const size_t *dims, size_t dimLength) {
836709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
837110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
838709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
839709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mExecutable->getExportVarAddrs()[slot]);
840110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
841110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
842110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
843709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
844709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
845709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
846709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
847709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
848709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // We want to look at dimension in terms of integer components,
849709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // but dimLength is given in terms of bytes.
850709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    dimLength /= sizeof(int);
851709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
852709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // Only a single dimension is currently supported.
853709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(dimLength == 1);
854709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (dimLength == 1) {
855709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        // First do the increment loop.
856709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        size_t stride = elem->getSizeBytes();
857709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const char *cVal = reinterpret_cast<const char *>(data);
858709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        for (size_t i = 0; i < dims[0]; i++) {
859709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            elem->incRefs(cVal);
860709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            cVal += stride;
861709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
862709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
863709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        // Decrement loop comes after (to prevent race conditions).
864709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        char *oldVal = reinterpret_cast<char *>(destPtr);
865709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        for (size_t i = 0; i < dims[0]; i++) {
866709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            elem->decRefs(oldVal);
867709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            oldVal += stride;
868709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
869709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
870709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
871709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, data, dataLength);
872709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
873709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
874709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalBind(uint32_t slot, Allocation *data) {
875709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
876709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(!script->mFieldIsObject[slot]);
877709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("setGlobalBind %p %p %i %p", dc, script, slot, data);
878709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
879110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
880709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
881709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                          mExecutable->getExportVarAddrs()[slot]);
882110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
883110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
884110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
885709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
886709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
887709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
888709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
889709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
890709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    void *ptr = NULL;
891709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mBoundAllocs[slot] = data;
892709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if(data) {
893709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ptr = data->mHal.drvState.lod[0].mallocPtr;
894709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
895709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, &ptr, sizeof(void *));
896709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
897709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
898709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalObj(uint32_t slot, ObjectBase *data) {
899709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
900709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(script->mFieldIsObject[slot]);
901709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("setGlobalObj %p %p %i %p", dc, script, slot, data);
902709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
903709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //if (mIntrinsicID) {
904709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mIntrinsicFuncs.setVarObj(dc, script, drv->mIntrinsicData, slot, alloc);
905709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //return;
906709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //}
907709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
908110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
909709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
910709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                          mExecutable->getExportVarAddrs()[slot]);
911110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
912110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
913110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
914709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
915709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
916709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
917709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
918709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
919709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsrSetObject(mCtx->getContext(), (ObjectBase **)destPtr, data);
920709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
921709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
922709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptImpl::~RsdCpuScriptImpl() {
923110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
924709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mExecutable) {
925709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Vector<void *>::const_iterator var_addr_iter =
926709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getExportVarAddrs().begin();
927709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Vector<void *>::const_iterator var_addr_end =
928709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getExportVarAddrs().end();
929709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
930709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_iter =
931709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getInfo().getObjectSlots().begin();
932709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_end =
933709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getInfo().getObjectSlots().end();
934709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
935709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        while ((var_addr_iter != var_addr_end) &&
936709a0978ae141198018ca9769f8d96292a8928e6Jason Sams               (is_object_iter != is_object_end)) {
937709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            // The field address can be NULL if the script-side has optimized
938709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            // the corresponding global variable away.
939709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            ObjectBase **obj_addr =
940709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                reinterpret_cast<ObjectBase **>(*var_addr_iter);
941709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            if (*is_object_iter) {
942709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                if (*var_addr_iter != NULL) {
943709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                    rsrClearObject(mCtx->getContext(), obj_addr);
944709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                }
945709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            }
946709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            var_addr_iter++;
947709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            is_object_iter++;
948709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
949709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
950709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
951709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerContext) {
952709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mCompilerContext;
953709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
954709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerDriver) {
955709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mCompilerDriver;
956709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
957709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mExecutable) {
958709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mExecutable;
959709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
960709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mBoundAllocs) {
961709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete[] mBoundAllocs;
962709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
963110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
964110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mFieldIsObject) {
965110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        for (size_t i = 0; i < mExportedVariableCount; ++i) {
966110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mFieldIsObject[i]) {
967110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (mFieldAddress[i] != NULL) {
968110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ObjectBase **obj_addr =
969110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                        reinterpret_cast<ObjectBase **>(mFieldAddress[i]);
970110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    rsrClearObject(mCtx->getContext(), obj_addr);
971110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
972110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
973110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
974110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
975110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
976110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mInvokeFunctions) delete[] mInvokeFunctions;
977110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mForEachFunctions) delete[] mForEachFunctions;
978110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mFieldAddress) delete[] mFieldAddress;
979110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mFieldIsObject) delete[] mFieldIsObject;
980110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mForEachSignatures) delete[] mForEachSignatures;
981110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mBoundAllocs) delete[] mBoundAllocs;
982110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
983110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        dlclose(mScriptSO);
984110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
985110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
986709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
987709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
988709a0978ae141198018ca9769f8d96292a8928e6Jason SamsAllocation * RsdCpuScriptImpl::getAllocationForPointer(const void *ptr) const {
989709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!ptr) {
990709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return NULL;
991709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
992709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
993709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    for (uint32_t ct=0; ct < mScript->mHal.info.exportedVariableCount; ct++) {
994709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Allocation *a = mBoundAllocs[ct];
995709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (!a) continue;
996709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (a->mHal.drvState.lod[0].mallocPtr == ptr) {
997709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            return a;
998709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
999709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1000709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    ALOGE("rsGetAllocation, failed to find %p", ptr);
1001709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return NULL;
1002709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1003709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1004709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1005709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1006709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1007