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
20110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
21c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    #include <set>
22c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    #include <string>
23110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <dlfcn.h>
24110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <stdio.h>
25c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    #include <stdlib.h>
26110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <string.h>
27661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    #include <sys/stat.h>
28c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    #include <unistd.h>
29110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
30110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/BCCContext.h>
31110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSCompilerDriver.h>
32110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSExecutable.h>
33110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSInfo.h>
34b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <bcinfo/MetadataExtractor.h>
35ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    #include <cutils/properties.h>
36b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
37b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <sys/types.h>
38b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <sys/wait.h>
39b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <unistd.h>
40110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
41709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
42ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hinesnamespace {
43c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines#ifdef RS_COMPATIBILITY_LIB
44c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
45c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// Create a len length string containing random characters from [A-Za-z0-9].
46c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hinesstatic std::string getRandomString(size_t len) {
47c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    char buf[len + 1];
48c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    for (size_t i = 0; i < len; i++) {
49c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        uint32_t r = arc4random() & 0xffff;
50c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        r %= 62;
51c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        if (r < 26) {
52c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            // lowercase
53c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            buf[i] = 'a' + r;
54c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        } else if (r < 52) {
55c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            // uppercase
56c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            buf[i] = 'A' + (r - 26);
57c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        } else {
58c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            // Use a number
59c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            buf[i] = '0' + (r - 52);
60c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        }
61c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
62c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    buf[len] = '\0';
63c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    return std::string(buf);
64c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines}
65c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
66661a62c34b6b6892346274272a5537e5e68c712cStephen Hines// Check if a path exists and attempt to create it if it doesn't.
67661a62c34b6b6892346274272a5537e5e68c712cStephen Hinesstatic bool ensureCacheDirExists(const char *path) {
68661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    if (access(path, R_OK | W_OK | X_OK) == 0) {
69661a62c34b6b6892346274272a5537e5e68c712cStephen Hines        // Done if we can rwx the directory
70661a62c34b6b6892346274272a5537e5e68c712cStephen Hines        return true;
71661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    }
72661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    if (mkdir(path, 0700) == 0) {
73661a62c34b6b6892346274272a5537e5e68c712cStephen Hines        return true;
74661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    }
75661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    return false;
76661a62c34b6b6892346274272a5537e5e68c712cStephen Hines}
77661a62c34b6b6892346274272a5537e5e68c712cStephen Hines
78c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// Attempt to load the shared library from origName, but then fall back to
79c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// creating the symlinked shared library if necessary (to ensure instancing).
80c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// This function returns the dlopen()-ed handle if successful.
81c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hinesstatic void *loadSOHelper(const char *origName, const char *cacheDir,
82c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines                          const char *resName) {
83c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // Keep track of which .so libraries have been loaded. Once a library is
84c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // in the set (per-process granularity), we must instead make a symlink to
85c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // the original shared object (randomly named .so file) and load that one
86c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // instead. If we don't do this, we end up aliasing global data between
87c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // the various Script instances (which are supposed to be completely
88c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // independent).
89c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    static std::set<std::string> LoadedLibraries;
90c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
91c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    void *loaded = NULL;
92c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
93c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // Skip everything if we don't even have the original library available.
94c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (access(origName, F_OK) != 0) {
95c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        return NULL;
96c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
97c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
98c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // Common path is that we have not loaded this Script/library before.
99c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (LoadedLibraries.find(origName) == LoadedLibraries.end()) {
100c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        loaded = dlopen(origName, RTLD_NOW | RTLD_LOCAL);
101c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        if (loaded) {
102c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            LoadedLibraries.insert(origName);
103c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        }
104c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        return loaded;
105c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
106c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
107c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    std::string newName(cacheDir);
108661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    newName.append("/com.android.renderscript.cache/");
109661a62c34b6b6892346274272a5537e5e68c712cStephen Hines
110661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    if (!ensureCacheDirExists(newName.c_str())) {
111661a62c34b6b6892346274272a5537e5e68c712cStephen Hines        ALOGE("Could not verify or create cache dir: %s", cacheDir);
112661a62c34b6b6892346274272a5537e5e68c712cStephen Hines        return NULL;
113661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    }
114661a62c34b6b6892346274272a5537e5e68c712cStephen Hines
115661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    // Construct an appropriately randomized filename for the symlink.
116661a62c34b6b6892346274272a5537e5e68c712cStephen Hines    newName.append("librs.");
117c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    newName.append(resName);
118c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    newName.append("#");
119c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    newName.append(getRandomString(6));  // 62^6 potential filename variants.
120c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    newName.append(".so");
121c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
122c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    int r = symlink(origName, newName.c_str());
123c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (r != 0) {
124c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        ALOGE("Could not create symlink %s -> %s", newName.c_str(), origName);
125c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        return NULL;
126c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
127c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    loaded = dlopen(newName.c_str(), RTLD_NOW | RTLD_LOCAL);
128c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    r = unlink(newName.c_str());
129c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (r != 0) {
130c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        ALOGE("Could not unlink symlink %s", newName.c_str());
131c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
132c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (loaded) {
133c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        LoadedLibraries.insert(newName.c_str());
134c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
135c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
136c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    return loaded;
137c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines}
138c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
139c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// Load the shared library referred to by cacheDir and resName. If we have
140c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// already loaded this library, we instead create a new symlink (in the
141c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// cache dir) and then load that. We then immediately destroy the symlink.
142c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// This is required behavior to implement script instancing for the support
143c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// library, since shared objects are loaded and de-duped by name only.
144c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hinesstatic void *loadSharedLibrary(const char *cacheDir, const char *resName) {
145c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    void *loaded = NULL;
146c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    //arc4random_stir();
147c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines#ifndef RS_SERVER
148c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    std::string scriptSOName(cacheDir);
149c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    size_t cutPos = scriptSOName.rfind("cache");
150c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (cutPos != std::string::npos) {
151c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        scriptSOName.erase(cutPos);
152c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    } else {
153c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        ALOGE("Found peculiar cacheDir (missing \"cache\"): %s", cacheDir);
154c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
155c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    scriptSOName.append("/lib/librs.");
156c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines#else
157c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    std::string scriptSOName("lib");
158c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines#endif
159c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    scriptSOName.append(resName);
160c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    scriptSOName.append(".so");
161c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
162c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // We should check if we can load the library from the standard app
163c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // location for shared libraries first.
164c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    loaded = loadSOHelper(scriptSOName.c_str(), cacheDir, resName);
165c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
166c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (loaded == NULL) {
167c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        ALOGE("Unable to open shared library (%s): %s",
168c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines              scriptSOName.c_str(), dlerror());
169c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
170c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        // One final attempt to find the library in "/system/lib".
171c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        // We do this to allow bundled applications to use the compatibility
172c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        // library fallback path. Those applications don't have a private
173c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        // library path, so they need to install to the system directly.
174c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        // Note that this is really just a testing path.
175c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        android::String8 scriptSONameSystem("/system/lib/librs.");
176c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        scriptSONameSystem.append(resName);
177c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        scriptSONameSystem.append(".so");
178c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        loaded = loadSOHelper(scriptSONameSystem.c_str(), cacheDir,
179c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines                              resName);
180c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        if (loaded == NULL) {
181c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            ALOGE("Unable to open system shared library (%s): %s",
182c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines                  scriptSONameSystem.c_str(), dlerror());
183c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        }
184c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
185c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
186c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    return loaded;
187c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines}
188c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
189c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
190c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines#else
191ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hinesstatic bool is_force_recompile() {
192ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#ifdef RS_SERVER
193ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  return false;
194ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#else
195ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  char buf[PROPERTY_VALUE_MAX];
196ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
197ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  // Re-compile if floating point precision has been overridden.
198ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  property_get("debug.rs.precision", buf, "");
199ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  if (buf[0] != '\0') {
200ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return true;
201ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  }
202ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
203ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  // Re-compile if debug.rs.forcerecompile is set.
204ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  property_get("debug.rs.forcerecompile", buf, "0");
205ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  if ((::strcmp(buf, "1") == 0) || (::strcmp(buf, "true") == 0)) {
206ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return true;
207ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  } else {
208ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return false;
209ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  }
210ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#endif  // RS_SERVER
211ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines}
212b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
213b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines//#define EXTERNAL_BCC_COMPILER 1
214b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#ifdef EXTERNAL_BCC_COMPILER
215b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hinesconst static char *BCC_EXE_PATH = "/system/bin/bcc";
216b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
217b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hinesstatic bool compileBitcode(const char *cacheDir,
218b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           const char *resName,
219b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           const char *bitcode,
220b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           size_t bitcodeSize,
221b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           const char *core_lib) {
222b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    rsAssert(cacheDir && resName && bitcode && bitcodeSize && core_lib);
223b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
224b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    android::String8 bcFilename(cacheDir);
225b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    bcFilename.append("/");
226b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    bcFilename.append(resName);
227b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    bcFilename.append(".bc");
228b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    FILE *bcfile = fopen(bcFilename.string(), "w");
229b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (!bcfile) {
230b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not write to %s", bcFilename.string());
231b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
232b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
233b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    size_t nwritten = fwrite(bitcode, 1, bitcodeSize, bcfile);
234b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    fclose(bcfile);
235b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (nwritten != bitcodeSize) {
236b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not write %zu bytes to %s", bitcodeSize,
237b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              bcFilename.string());
238b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
239b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
240b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
241b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    pid_t pid = fork();
242b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    switch (pid) {
243b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case -1: {  // Error occurred (we attempt no recovery)
244b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Couldn't fork for bcc compiler execution");
245b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
246b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
247b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case 0: {  // Child process
248b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        // Execute the bcc compiler.
249b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        execl(BCC_EXE_PATH,
250b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              BCC_EXE_PATH,
251b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              "-o", resName,
252b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              "-output_path", cacheDir,
253b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              "-bclib", core_lib,
254b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              bcFilename.string(),
255b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines              (char *) NULL);
256b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("execl() failed: %s", strerror(errno));
257b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        abort();
258b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
259b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
260b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    default: {  // Parent process (actual driver)
261b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        // Wait on child process to finish compiling the source.
262b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        int status = 0;
263b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        pid_t w = waitpid(pid, &status, 0);
264b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        if (w == -1) {
265b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            ALOGE("Could not wait for bcc compiler");
266b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            return false;
267b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        }
268b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
269b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
270b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            return true;
271b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        }
272b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
273b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("bcc compiler terminated unexpectedly");
274b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
275b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
276b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
277b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines}
278b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#endif  // EXTERNAL_BCC_COMPILER
279b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
280ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#endif  // !defined(RS_COMPATIBILITY_LIB)
281c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines}  // namespace
282ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
283709a0978ae141198018ca9769f8d96292a8928e6Jason Samsnamespace android {
284709a0978ae141198018ca9769f8d96292a8928e6Jason Samsnamespace renderscript {
285709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
286709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
287110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
288110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define MAXLINE 500
289110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define MAKE_STR_HELPER(S) #S
290110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define MAKE_STR(S) MAKE_STR_HELPER(S)
291110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_VAR_STR "exportVarCount: "
292110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_VAR_STR_LEN strlen(EXPORT_VAR_STR)
293110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_FUNC_STR "exportFuncCount: "
294110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_FUNC_STR_LEN strlen(EXPORT_FUNC_STR)
295110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_FOREACH_STR "exportForEachCount: "
296110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_FOREACH_STR_LEN strlen(EXPORT_FOREACH_STR)
297110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define OBJECT_SLOT_STR "objectSlotCount: "
298110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define OBJECT_SLOT_STR_LEN strlen(OBJECT_SLOT_STR)
299110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
300110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams// Copy up to a newline or size chars from str -> s, updating str
301110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams// Returns s when successful and NULL when '\0' is finally reached.
302110f181b7966212a36ef18016f9b81c7322d0a2fJason Samsstatic char* strgets(char *s, int size, const char **ppstr) {
303110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (!ppstr || !*ppstr || **ppstr == '\0' || size < 1) {
304110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        return NULL;
305110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
306110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
307110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int i;
308110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    for (i = 0; i < (size - 1); i++) {
309110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        s[i] = **ppstr;
310110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        (*ppstr)++;
311110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (s[i] == '\0') {
312110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            return s;
313110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        } else if (s[i] == '\n') {
314110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            s[i+1] = '\0';
315110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            return s;
316110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
317110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
318110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
319110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // size has been exceeded.
320110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    s[i] = '\0';
321110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
322110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    return s;
323110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams}
324110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
325709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
326709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptImpl::RsdCpuScriptImpl(RsdCpuReferenceImpl *ctx, const Script *s) {
327709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx = ctx;
328709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mScript = s;
329709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
330110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
331110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mScriptSO = NULL;
332110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mInvokeFunctions = NULL;
333110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mForEachFunctions = NULL;
334110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mFieldAddress = NULL;
335110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mFieldIsObject = NULL;
336110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mForEachSignatures = NULL;
337110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
338110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCompilerContext = NULL;
339110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCompilerDriver = NULL;
340110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mExecutable = NULL;
341110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
342110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
343709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRoot = NULL;
344709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRootExpand = NULL;
345709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mInit = NULL;
346709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mFreeChildren = NULL;
347709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
348709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
349709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mBoundAllocs = NULL;
350709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mIntrinsicData = NULL;
351709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mIsThreadable = true;
352709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
353709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
354709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
355709a0978ae141198018ca9769f8d96292a8928e6Jason Samsbool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir,
356709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                            uint8_t const *bitcode, size_t bitcodeSize,
357709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                            uint32_t flags) {
358709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc);
359709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("rsdScriptInit %p %p", rsc, script);
360709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
361709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->lockMutex();
362709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
363110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
364ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    bcc::RSExecutable *exec = NULL;
365709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
366709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerContext = NULL;
367709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver = NULL;
368709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mExecutable = NULL;
369709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
370709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerContext = new bcc::BCCContext();
371709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerContext == NULL) {
372709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGE("bcc: FAILS to create compiler context (out of memory)");
373709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->unlockMutex();
374709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return false;
375709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
376709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
377709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver = new bcc::RSCompilerDriver();
378709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerDriver == NULL) {
379709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGE("bcc: FAILS to create compiler driver (out of memory)");
380709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->unlockMutex();
381709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return false;
382709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
383709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
384709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver->setRSRuntimeLookupFunction(lookupRuntimeStub);
385709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver->setRSRuntimeLookupContext(this);
386709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
387b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    // Run any compiler setup functions we have been provided with.
388b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    RSSetupCompilerCallback setupCompilerCallback =
389b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines            mCtx->getSetupCompilerCallback();
390b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    if (setupCompilerCallback != NULL) {
391b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines        setupCompilerCallback(mCompilerDriver);
392b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    }
393b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines
394b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    const char *core_lib = bcc::RSInfo::LibCLCorePath;
395b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
396b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    bcinfo::MetadataExtractor ME((const char *) bitcode, bitcodeSize);
397b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (!ME.extract()) {
398b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not extract metadata from bitcode");
399b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
400b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
401b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
402b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    enum bcinfo::RSFloatPrecision prec = ME.getRSFloatPrecision();
403b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    switch (prec) {
404b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case bcinfo::RS_FP_Imprecise:
405b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case bcinfo::RS_FP_Relaxed:
406b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#if defined(ARCH_ARM_HAVE_NEON)
407b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        // NEON-capable devices can use an accelerated math library for all
408b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        // reduced precision scripts.
409b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        core_lib = bcc::RSInfo::LibCLCoreNEONPath;
410b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#endif
411b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        break;
412b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case bcinfo::RS_FP_Full:
413b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        break;
414b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    default:
415b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Unknown precision for bitcode");
416b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
417b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
418b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
419b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#if defined(ARCH_X86_HAVE_SSE2)
420b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    // SSE2- or above capable devices will use an optimized library.
421b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    core_lib = bcc::RSInfo::LibCLCoreX86Path;
422b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#endif
423b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
4241d476620399d54774e4fd386c1d23cc583d49522Stephen Hines    RSSelectRTCallback selectRTCallback = mCtx->getSelectRTCallback();
4251d476620399d54774e4fd386c1d23cc583d49522Stephen Hines    if (selectRTCallback != NULL) {
4261d476620399d54774e4fd386c1d23cc583d49522Stephen Hines        core_lib = selectRTCallback((const char *)bitcode, bitcodeSize);
4271d476620399d54774e4fd386c1d23cc583d49522Stephen Hines    }
428cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines
429cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines    if (mCtx->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
430cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines        // Use the libclcore_debug.bc instead of the default library.
431cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines        core_lib = bcc::RSInfo::LibCLCoreDebugPath;
432f47e8b4b86bf194e65398032f3f5f47a6da89f3fStephen Hines        mCompilerDriver->setDebugContext(true);
433ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        // Skip the cache lookup
434ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    } else if (!is_force_recompile()) {
435ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        // Attempt to just load the script from cache first if we can.
436ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        exec = mCompilerDriver->loadScript(cacheDir, resName,
437ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                           (const char *)bitcode, bitcodeSize);
438ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    }
439ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
440ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    if (exec == NULL) {
441b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#ifdef EXTERNAL_BCC_COMPILER
442b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        bool built = compileBitcode(cacheDir, resName, (const char *)bitcode,
443b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                                    bitcodeSize, core_lib);
444b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#else
445ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        bool built = mCompilerDriver->build(*mCompilerContext, cacheDir,
446ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                            resName, (const char *)bitcode,
447ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                            bitcodeSize, core_lib,
448ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                            mCtx->getLinkRuntimeCallback());
449b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines#endif  // EXTERNAL_BCC_COMPILER
450ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        if (built) {
451ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines            exec = mCompilerDriver->loadScript(cacheDir, resName,
452ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                               (const char *)bitcode,
453ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines                                               bitcodeSize);
454ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines        }
455cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines    }
456709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
457709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (exec == NULL) {
458709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGE("bcc: FAILS to prepare executable for '%s'", resName);
459709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->unlockMutex();
460709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return false;
461709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
462709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
463709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mExecutable = exec;
464709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
465709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    exec->setThreadable(mIsThreadable);
466709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!exec->syncInfo()) {
467709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGW("bcc: FAILS to synchronize the RS info file to the disk");
468709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
469709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
470709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRoot = reinterpret_cast<int (*)()>(exec->getSymbolAddress("root"));
471709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRootExpand =
472709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        reinterpret_cast<int (*)()>(exec->getSymbolAddress("root.expand"));
473709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mInit = reinterpret_cast<void (*)()>(exec->getSymbolAddress("init"));
474709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mFreeChildren =
475709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        reinterpret_cast<void (*)()>(exec->getSymbolAddress(".rs.dtor"));
476709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
477709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
4781d476620399d54774e4fd386c1d23cc583d49522Stephen Hines    const bcc::RSInfo *info = &mExecutable->getInfo();
479709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (info->getExportVarNames().size()) {
480709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mBoundAllocs = new Allocation *[info->getExportVarNames().size()];
481709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        memset(mBoundAllocs, 0, sizeof(void *) * info->getExportVarNames().size());
482709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
483709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
484110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
485110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
486c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    mScriptSO = loadSharedLibrary(cacheDir, resName);
487110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
488110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
489110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        char line[MAXLINE];
490110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mRoot = (RootFunc_t) dlsym(mScriptSO, "root");
491110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mRoot) {
492110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found root(): %p", mRoot);
493110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
494110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mRootExpand = (RootFunc_t) dlsym(mScriptSO, "root.expand");
495110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mRootExpand) {
496110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found root.expand(): %p", mRootExpand);
497110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
498110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mInit = (InvokeFunc_t) dlsym(mScriptSO, "init");
499110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mInit) {
500110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found init(): %p", mInit);
501110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
502110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mFreeChildren = (InvokeFunc_t) dlsym(mScriptSO, ".rs.dtor");
503110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mFreeChildren) {
504110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found .rs.dtor(): %p", mFreeChildren);
505110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
506110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
507110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        const char *rsInfo = (const char *) dlsym(mScriptSO, ".rs.info");
508110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (rsInfo) {
509110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found .rs.info(): %p - %s", rsInfo, rsInfo);
510110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
511110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
512110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t varCount = 0;
513110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
514110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
515110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
516110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, EXPORT_VAR_STR "%zu", &varCount) != 1) {
517110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid export var count!: %s", line);
518110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
519110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
520110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
521110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mExportedVariableCount = varCount;
522110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        //ALOGE("varCount: %zu", varCount);
523110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (varCount > 0) {
524110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            // Start by creating/zeroing this member, since we don't want to
525110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            // accidentally clean up invalid pointers later (if we error out).
526110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mFieldIsObject = new bool[varCount];
527110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mFieldIsObject == NULL) {
528110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
529110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
530110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            memset(mFieldIsObject, 0, varCount * sizeof(*mFieldIsObject));
531110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mFieldAddress = new void*[varCount];
532110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mFieldAddress == NULL) {
533110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
534110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
535110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < varCount; ++i) {
536110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
537110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
538110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
539110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                char *c = strrchr(line, '\n');
540110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (c) {
541110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    *c = '\0';
542110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
543110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mFieldAddress[i] = dlsym(mScriptSO, line);
544110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (mFieldAddress[i] == NULL) {
545110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Failed to find variable address for %s: %s",
546110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                          line, dlerror());
547110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    // Not a critical error if we don't find a global variable.
548110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
549110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                else {
550110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //ALOGE("Found variable %s at %p", line,
551110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //mFieldAddress[i]);
552110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
553110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
554110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
555110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
556110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t funcCount = 0;
557110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
558110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
559110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
560110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, EXPORT_FUNC_STR "%zu", &funcCount) != 1) {
561110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid export func count!: %s", line);
562110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
563110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
564110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
565110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mExportedFunctionCount = funcCount;
566110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        //ALOGE("funcCount: %zu", funcCount);
567110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
568110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (funcCount > 0) {
569110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mInvokeFunctions = new InvokeFunc_t[funcCount];
570110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mInvokeFunctions == NULL) {
571110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
572110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
573110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < funcCount; ++i) {
574110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
575110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
576110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
577110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                char *c = strrchr(line, '\n');
578110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (c) {
579110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    *c = '\0';
580110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
581110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
582110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mInvokeFunctions[i] = (InvokeFunc_t) dlsym(mScriptSO, line);
583110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (mInvokeFunctions[i] == NULL) {
584110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Failed to get function address for %s(): %s",
585110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                          line, dlerror());
586110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
587110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
588110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                else {
589110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //ALOGE("Found InvokeFunc_t %s at %p", line, mInvokeFunctions[i]);
590110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
591110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
592110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
593110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
594110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t forEachCount = 0;
595110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
596110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
597110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
598110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, EXPORT_FOREACH_STR "%zu", &forEachCount) != 1) {
599110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid export forEach count!: %s", line);
600110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
601110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
602110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
603110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (forEachCount > 0) {
604110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
605110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mForEachSignatures = new uint32_t[forEachCount];
606110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mForEachSignatures == NULL) {
607110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
608110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
609110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mForEachFunctions = new ForEachFunc_t[forEachCount];
610110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mForEachFunctions == NULL) {
611110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
612110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
613110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < forEachCount; ++i) {
614110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                unsigned int tmpSig = 0;
615110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                char tmpName[MAXLINE];
616110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
617110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
618110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
619110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
620110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (sscanf(line, "%u - %" MAKE_STR(MAXLINE) "s",
621110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                           &tmpSig, tmpName) != 2) {
622110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Invalid export forEach!: %s", line);
623110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
624110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
625110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
626110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                // Lookup the expanded ForEach kernel.
627110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                strncat(tmpName, ".expand", MAXLINE-1-strlen(tmpName));
628110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mForEachSignatures[i] = tmpSig;
629110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mForEachFunctions[i] =
630110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                        (ForEachFunc_t) dlsym(mScriptSO, tmpName);
631ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                if (i != 0 && mForEachFunctions[i] == NULL) {
632110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    // Ignore missing root.expand functions.
633110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    // root() is always specified at location 0.
634ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                    ALOGE("Failed to find forEach function address for %s: %s",
635ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                          tmpName, dlerror());
636ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                    goto error;
637110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
638110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                else {
639110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //ALOGE("Found forEach %s at %p", tmpName, mForEachFunctions[i]);
640110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
641110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
642110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
643110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
644110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t objectSlotCount = 0;
645110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
646110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
647110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
648110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, OBJECT_SLOT_STR "%zu", &objectSlotCount) != 1) {
649110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid object slot count!: %s", line);
650110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
651110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
652110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
653110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (objectSlotCount > 0) {
654110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            rsAssert(varCount > 0);
655110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < objectSlotCount; ++i) {
656110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                uint32_t varNum = 0;
657110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
658110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
659110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
660110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (sscanf(line, "%u", &varNum) != 1) {
661110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Invalid object slot!: %s", line);
662110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
663110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
664110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
665110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (varNum < varCount) {
666110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    mFieldIsObject[varNum] = true;
667110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
668110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
669110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
670110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
671110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (varCount > 0) {
672110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mBoundAllocs = new Allocation *[varCount];
673110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            memset(mBoundAllocs, 0, varCount * sizeof(*mBoundAllocs));
674110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
675110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
676110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mScriptSO == (void*)1) {
677110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //rsdLookupRuntimeStub(script, "acos");
678110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
679c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    } else {
680c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        goto error;
681110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
682110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
683110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
684709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->unlockMutex();
685709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return true;
686110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
687110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
688110f181b7966212a36ef18016f9b81c7322d0a2fJason Samserror:
689110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
690110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCtx->unlockMutex();
691110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mInvokeFunctions;
692110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mForEachFunctions;
693110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mFieldAddress;
694110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mFieldIsObject;
695110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mForEachSignatures;
696110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mBoundAllocs;
697110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
698110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        dlclose(mScriptSO);
699110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
700110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    return false;
701110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
702709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
703709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
704709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::populateScript(Script *script) {
705110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
706709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    const bcc::RSInfo *info = &mExecutable->getInfo();
707709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
708709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // Copy info over to runtime
709709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedFunctionCount = info->getExportFuncNames().size();
710709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedVariableCount = info->getExportVarNames().size();
71147935ac8e3dd619f758abd576605a564e33bb59cTobias Grosser    script->mHal.info.exportedForeachFuncList = info->getExportForeachFuncs().array();
712709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedPragmaCount = info->getPragmas().size();
713709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedPragmaKeyList =
714709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const_cast<const char**>(mExecutable->getPragmaKeys().array());
715709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedPragmaValueList =
716709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const_cast<const char**>(mExecutable->getPragmaValues().array());
717709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
718709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mRootExpand) {
719709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        script->mHal.info.root = mRootExpand;
720709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
721709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        script->mHal.info.root = mRoot;
722709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
723110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
724110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // Copy info over to runtime
725110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedFunctionCount = mExportedFunctionCount;
726110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedVariableCount = mExportedVariableCount;
727110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedPragmaCount = 0;
728110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedPragmaKeyList = 0;
729110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedPragmaValueList = 0;
730110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
731110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // Bug, need to stash in metadata
732110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mRootExpand) {
733110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        script->mHal.info.root = mRootExpand;
734110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    } else {
735110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        script->mHal.info.root = mRoot;
736110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
737110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
738709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
739709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
740709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
741709a0978ae141198018ca9769f8d96292a8928e6Jason Samstypedef void (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
742709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
743709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::forEachMtlsSetup(const Allocation * ain, Allocation * aout,
744709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        const void * usr, uint32_t usrLen,
745709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        const RsScriptCall *sc,
746709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        MTLaunchStruct *mtls) {
747709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
748709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memset(mtls, 0, sizeof(MTLaunchStruct));
749709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
7503a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    // possible for this to occur if IO_OUTPUT/IO_INPUT with no bound surface
7513a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    if (ain && (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr == NULL) {
752ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null in allocations");
7533a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray        return;
7543a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    }
7553a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    if (aout && (const uint8_t *)aout->mHal.drvState.lod[0].mallocPtr == NULL) {
756ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null out allocations");
7573a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray        return;
7583a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    }
7593a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray
760709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (ain) {
761709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimX = ain->getType()->getDimX();
762709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimY = ain->getType()->getDimY();
763709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimZ = ain->getType()->getDimZ();
764709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mtls->dimArray = ain->getType()->getDimArray();
765709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else if (aout) {
766709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimX = aout->getType()->getDimX();
767709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimY = aout->getType()->getDimY();
768709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.dimZ = aout->getType()->getDimZ();
769709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mtls->dimArray = aout->getType()->getDimArray();
770709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
771709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
772709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
773709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
774709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
775709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!sc || (sc->xEnd == 0)) {
776709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->xEnd = mtls->fep.dimX;
777709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
778709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->xStart < mtls->fep.dimX);
779709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->xEnd <= mtls->fep.dimX);
780709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->xStart < sc->xEnd);
781709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->xStart = rsMin(mtls->fep.dimX, sc->xStart);
782709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->xEnd = rsMin(mtls->fep.dimX, sc->xEnd);
783709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (mtls->xStart >= mtls->xEnd) return;
784709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
785709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
786709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!sc || (sc->yEnd == 0)) {
787709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->yEnd = mtls->fep.dimY;
788709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
789709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->yStart < mtls->fep.dimY);
790709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->yEnd <= mtls->fep.dimY);
791709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->yStart < sc->yEnd);
792709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->yStart = rsMin(mtls->fep.dimY, sc->yStart);
793709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->yEnd = rsMin(mtls->fep.dimY, sc->yEnd);
794709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (mtls->yStart >= mtls->yEnd) return;
795709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
796709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
797d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray    if (!sc || (sc->zEnd == 0)) {
798d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        mtls->zEnd = mtls->fep.dimZ;
799d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray    } else {
800d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        rsAssert(sc->zStart < mtls->fep.dimZ);
801d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        rsAssert(sc->zEnd <= mtls->fep.dimZ);
802d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        rsAssert(sc->zStart < sc->zEnd);
803d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        mtls->zStart = rsMin(mtls->fep.dimZ, sc->zStart);
804d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        mtls->zEnd = rsMin(mtls->fep.dimZ, sc->zEnd);
805d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        if (mtls->zStart >= mtls->zEnd) return;
806d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray    }
807d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray
808709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->xEnd = rsMax((uint32_t)1, mtls->xEnd);
809709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->yEnd = rsMax((uint32_t)1, mtls->yEnd);
810709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->zEnd = rsMax((uint32_t)1, mtls->zEnd);
811709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->arrayEnd = rsMax((uint32_t)1, mtls->arrayEnd);
812709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
813709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(!ain || (ain->getType()->getDimZ() == 0));
814709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
815709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->rsc = mCtx;
816709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->ain = ain;
817709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->aout = aout;
818709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.usr = usr;
819709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.usrLen = usrLen;
820709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->mSliceSize = 1;
821709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->mSliceNum = 0;
822709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
823709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.ptrIn = NULL;
824709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.eStrideIn = 0;
825709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->isThreadable = mIsThreadable;
826709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
827709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (ain) {
828709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.ptrIn = (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr;
829709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.eStrideIn = ain->getType()->getElementSizeBytes();
830709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.yStrideIn = ain->mHal.drvState.lod[0].stride;
831709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
832709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
833709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.ptrOut = NULL;
834709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.eStrideOut = 0;
835709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (aout) {
836709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.ptrOut = (uint8_t *)aout->mHal.drvState.lod[0].mallocPtr;
837709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.eStrideOut = aout->getType()->getElementSizeBytes();
838709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.yStrideOut = aout->mHal.drvState.lod[0].stride;
839709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
840709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
841709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
842709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
843709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeForEach(uint32_t slot,
844709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const Allocation * ain,
845709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     Allocation * aout,
846709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const void * usr,
847709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     uint32_t usrLen,
848709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const RsScriptCall *sc) {
849709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
850709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    MTLaunchStruct mtls;
851709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    forEachMtlsSetup(ain, aout, usr, usrLen, sc, &mtls);
852709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    forEachKernelSetup(slot, &mtls);
853709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
854709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
855709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->launchThreads(ain, aout, sc, &mtls);
856709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
857709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
858709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
859709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::forEachKernelSetup(uint32_t slot, MTLaunchStruct *mtls) {
860709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->script = this;
861709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.slot = slot;
862110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
863709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(slot < mExecutable->getExportForeachFuncAddrs().size());
864709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->kernel = reinterpret_cast<ForEachFunc_t>(
865709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                      mExecutable->getExportForeachFuncAddrs()[slot]);
866709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(mtls->kernel != NULL);
867709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->sig = mExecutable->getInfo().getExportForeachFuncs()[slot].second;
868110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
869110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mtls->kernel = reinterpret_cast<ForEachFunc_t>(mForEachFunctions[slot]);
870110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    rsAssert(mtls->kernel != NULL);
871110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mtls->sig = mForEachSignatures[slot];
872110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
873709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
874709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
875709a0978ae141198018ca9769f8d96292a8928e6Jason Samsint RsdCpuScriptImpl::invokeRoot() {
876709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
877709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int ret = mRoot();
878709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
879709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return ret;
880709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
881709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
882709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeInit() {
883709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mInit) {
884709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mInit();
885709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
886709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
887709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
888709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeFreeChildren() {
889709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mFreeChildren) {
890709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mFreeChildren();
891709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
892709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
893709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
894709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeFunction(uint32_t slot, const void *params,
895709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                      size_t paramLength) {
896709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("invoke %p %p %i %p %i", dc, script, slot, params, paramLength);
897709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
898709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
899709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    reinterpret_cast<void (*)(const void *, uint32_t)>(
900110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
901709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mExecutable->getExportFuncAddrs()[slot])(params, paramLength);
902110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
903110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mInvokeFunctions[slot])(params, paramLength);
904110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
905709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
906709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
907709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
908709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalVar(uint32_t slot, const void *data, size_t dataLength) {
909709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(!script->mFieldIsObject[slot]);
910709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("setGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength);
911709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
912709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //if (mIntrinsicID) {
913709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mIntrinsicFuncs.setVar(dc, script, drv->mIntrinsicData, slot, data, dataLength);
914709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //return;
915709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //}
916709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
917110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
918709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
919709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                          mExecutable->getExportVarAddrs()[slot]);
920110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
921110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
922110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
923709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
924709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
925709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
926709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
927709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
928709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, data, dataLength);
929709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
930709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
9319c64239ebbfa4170190ede812e69150035e008e0Tim Murrayvoid RsdCpuScriptImpl::getGlobalVar(uint32_t slot, void *data, size_t dataLength) {
9329c64239ebbfa4170190ede812e69150035e008e0Tim Murray    //rsAssert(!script->mFieldIsObject[slot]);
9339c64239ebbfa4170190ede812e69150035e008e0Tim Murray    //ALOGE("getGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength);
9349c64239ebbfa4170190ede812e69150035e008e0Tim Murray
9359c64239ebbfa4170190ede812e69150035e008e0Tim Murray#ifndef RS_COMPATIBILITY_LIB
9369c64239ebbfa4170190ede812e69150035e008e0Tim Murray    int32_t *srcPtr = reinterpret_cast<int32_t *>(
9379c64239ebbfa4170190ede812e69150035e008e0Tim Murray                          mExecutable->getExportVarAddrs()[slot]);
9389c64239ebbfa4170190ede812e69150035e008e0Tim Murray#else
9399c64239ebbfa4170190ede812e69150035e008e0Tim Murray    int32_t *srcPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
9409c64239ebbfa4170190ede812e69150035e008e0Tim Murray#endif
9419c64239ebbfa4170190ede812e69150035e008e0Tim Murray    if (!srcPtr) {
9429c64239ebbfa4170190ede812e69150035e008e0Tim Murray        //ALOGV("Calling setVar on slot = %i which is null", slot);
9439c64239ebbfa4170190ede812e69150035e008e0Tim Murray        return;
9449c64239ebbfa4170190ede812e69150035e008e0Tim Murray    }
9459c64239ebbfa4170190ede812e69150035e008e0Tim Murray    memcpy(data, srcPtr, dataLength);
9469c64239ebbfa4170190ede812e69150035e008e0Tim Murray}
9479c64239ebbfa4170190ede812e69150035e008e0Tim Murray
9489c64239ebbfa4170190ede812e69150035e008e0Tim Murray
949709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalVarWithElemDims(uint32_t slot, const void *data, size_t dataLength,
950709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                                const Element *elem,
951709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                                const size_t *dims, size_t dimLength) {
952709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
953110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
954709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
955709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mExecutable->getExportVarAddrs()[slot]);
956110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
957110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
958110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
959709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
960709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
961709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
962709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
963709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
964709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // We want to look at dimension in terms of integer components,
965709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // but dimLength is given in terms of bytes.
966709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    dimLength /= sizeof(int);
967709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
968709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // Only a single dimension is currently supported.
969709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(dimLength == 1);
970709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (dimLength == 1) {
971709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        // First do the increment loop.
972709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        size_t stride = elem->getSizeBytes();
973709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const char *cVal = reinterpret_cast<const char *>(data);
974709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        for (size_t i = 0; i < dims[0]; i++) {
975709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            elem->incRefs(cVal);
976709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            cVal += stride;
977709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
978709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
979709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        // Decrement loop comes after (to prevent race conditions).
980709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        char *oldVal = reinterpret_cast<char *>(destPtr);
981709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        for (size_t i = 0; i < dims[0]; i++) {
982709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            elem->decRefs(oldVal);
983709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            oldVal += stride;
984709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
985709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
986709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
987709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, data, dataLength);
988709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
989709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
990709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalBind(uint32_t slot, Allocation *data) {
991709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
992709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(!script->mFieldIsObject[slot]);
993709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("setGlobalBind %p %p %i %p", dc, script, slot, data);
994709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
995110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
996709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
997709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                          mExecutable->getExportVarAddrs()[slot]);
998110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
999110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
1000110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
1001709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
1002709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
1003709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
1004709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1005709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1006709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    void *ptr = NULL;
1007709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mBoundAllocs[slot] = data;
1008709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if(data) {
1009709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ptr = data->mHal.drvState.lod[0].mallocPtr;
1010709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1011709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, &ptr, sizeof(void *));
1012709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1013709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1014709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalObj(uint32_t slot, ObjectBase *data) {
1015709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1016709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(script->mFieldIsObject[slot]);
1017709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("setGlobalObj %p %p %i %p", dc, script, slot, data);
1018709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1019709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //if (mIntrinsicID) {
1020709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mIntrinsicFuncs.setVarObj(dc, script, drv->mIntrinsicData, slot, alloc);
1021709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //return;
1022709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //}
1023709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1024110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
1025709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
1026709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                          mExecutable->getExportVarAddrs()[slot]);
1027110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
1028110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
1029110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
1030709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
1031709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
1032709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
1033709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1034709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1035709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsrSetObject(mCtx->getContext(), (ObjectBase **)destPtr, data);
1036709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1037709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1038709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptImpl::~RsdCpuScriptImpl() {
1039110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
1040709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mExecutable) {
1041709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Vector<void *>::const_iterator var_addr_iter =
1042709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getExportVarAddrs().begin();
1043709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Vector<void *>::const_iterator var_addr_end =
1044709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getExportVarAddrs().end();
1045709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1046709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_iter =
1047709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getInfo().getObjectSlots().begin();
1048709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_end =
1049709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getInfo().getObjectSlots().end();
1050709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1051709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        while ((var_addr_iter != var_addr_end) &&
1052709a0978ae141198018ca9769f8d96292a8928e6Jason Sams               (is_object_iter != is_object_end)) {
1053709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            // The field address can be NULL if the script-side has optimized
1054709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            // the corresponding global variable away.
1055709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            ObjectBase **obj_addr =
1056709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                reinterpret_cast<ObjectBase **>(*var_addr_iter);
1057709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            if (*is_object_iter) {
1058709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                if (*var_addr_iter != NULL) {
1059709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                    rsrClearObject(mCtx->getContext(), obj_addr);
1060709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                }
1061709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            }
1062709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            var_addr_iter++;
1063709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            is_object_iter++;
1064709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
1065709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1066709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1067709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerContext) {
1068709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mCompilerContext;
1069709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1070709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerDriver) {
1071709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mCompilerDriver;
1072709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1073709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mExecutable) {
1074709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mExecutable;
1075709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1076709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mBoundAllocs) {
1077709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete[] mBoundAllocs;
1078709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1079110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
1080110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mFieldIsObject) {
1081110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        for (size_t i = 0; i < mExportedVariableCount; ++i) {
1082110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mFieldIsObject[i]) {
1083110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (mFieldAddress[i] != NULL) {
1084110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ObjectBase **obj_addr =
1085110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                        reinterpret_cast<ObjectBase **>(mFieldAddress[i]);
1086110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    rsrClearObject(mCtx->getContext(), obj_addr);
1087110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
1088110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
1089110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
1090110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
1091110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
1092110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mInvokeFunctions) delete[] mInvokeFunctions;
1093110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mForEachFunctions) delete[] mForEachFunctions;
1094110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mFieldAddress) delete[] mFieldAddress;
1095110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mFieldIsObject) delete[] mFieldIsObject;
1096110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mForEachSignatures) delete[] mForEachSignatures;
1097110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mBoundAllocs) delete[] mBoundAllocs;
1098110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
1099110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        dlclose(mScriptSO);
1100110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
1101110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
1102709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1103709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1104709a0978ae141198018ca9769f8d96292a8928e6Jason SamsAllocation * RsdCpuScriptImpl::getAllocationForPointer(const void *ptr) const {
1105709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!ptr) {
1106709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return NULL;
1107709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1108709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1109709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    for (uint32_t ct=0; ct < mScript->mHal.info.exportedVariableCount; ct++) {
1110709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Allocation *a = mBoundAllocs[ct];
1111709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (!a) continue;
1112709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (a->mHal.drvState.lod[0].mallocPtr == ptr) {
1113709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            return a;
1114709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
1115709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1116709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    ALOGE("rsGetAllocation, failed to find %p", ptr);
1117709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return NULL;
1118709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1119709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
112017e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Samsvoid RsdCpuScriptImpl::preLaunch(uint32_t slot, const Allocation * ain,
112117e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams                       Allocation * aout, const void * usr,
112217e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams                       uint32_t usrLen, const RsScriptCall *sc)
112317e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams{
112417e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams}
112517e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams
112617e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Samsvoid RsdCpuScriptImpl::postLaunch(uint32_t slot, const Allocation * ain,
112717e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams                        Allocation * aout, const void * usr,
112817e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams                        uint32_t usrLen, const RsScriptCall *sc)
112917e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams{
113017e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams}
113117e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams
1132709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1133709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1134709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1135