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
79ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet *
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>
27ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    #include <sys/stat.h>
28c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    #include <unistd.h>
29110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
30110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/BCCContext.h>
3182e0a6779cb1006921153081fb33374197e7c9deStephen Hines    #include <bcc/Config/Config.h>
32110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSCompilerDriver.h>
33110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSExecutable.h>
34110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSInfo.h>
35b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <bcinfo/MetadataExtractor.h>
36ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    #include <cutils/properties.h>
37b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
38b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <sys/types.h>
39b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <sys/wait.h>
40b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <unistd.h>
41005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines
42005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines    #include <string>
43005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines    #include <vector>
44110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
45709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
46ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hinesnamespace {
47c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines#ifdef RS_COMPATIBILITY_LIB
48c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
49c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// Create a len length string containing random characters from [A-Za-z0-9].
50c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hinesstatic std::string getRandomString(size_t len) {
51c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    char buf[len + 1];
52c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    for (size_t i = 0; i < len; i++) {
53c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        uint32_t r = arc4random() & 0xffff;
54c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        r %= 62;
55c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        if (r < 26) {
56c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            // lowercase
57c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            buf[i] = 'a' + r;
58c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        } else if (r < 52) {
59c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            // uppercase
60c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            buf[i] = 'A' + (r - 26);
61c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        } else {
62c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            // Use a number
63c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            buf[i] = '0' + (r - 52);
64c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        }
65c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
66c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    buf[len] = '\0';
67c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    return std::string(buf);
68c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines}
69c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
70ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines// Check if a path exists and attempt to create it if it doesn't.
71ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hinesstatic bool ensureCacheDirExists(const char *path) {
72ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    if (access(path, R_OK | W_OK | X_OK) == 0) {
73ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines        // Done if we can rwx the directory
74ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines        return true;
75ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    }
76ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    if (mkdir(path, 0700) == 0) {
77ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines        return true;
78ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    }
79ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    return false;
80ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines}
81ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines
82c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// Attempt to load the shared library from origName, but then fall back to
83c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// creating the symlinked shared library if necessary (to ensure instancing).
84c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// This function returns the dlopen()-ed handle if successful.
85c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hinesstatic void *loadSOHelper(const char *origName, const char *cacheDir,
86c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines                          const char *resName) {
87c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // Keep track of which .so libraries have been loaded. Once a library is
88c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // in the set (per-process granularity), we must instead make a symlink to
89c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // the original shared object (randomly named .so file) and load that one
90c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // instead. If we don't do this, we end up aliasing global data between
91c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // the various Script instances (which are supposed to be completely
92c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // independent).
93c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    static std::set<std::string> LoadedLibraries;
94c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
95c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    void *loaded = NULL;
96c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
97c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // Skip everything if we don't even have the original library available.
98c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (access(origName, F_OK) != 0) {
99c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        return NULL;
100c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
101c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
102c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // Common path is that we have not loaded this Script/library before.
103c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (LoadedLibraries.find(origName) == LoadedLibraries.end()) {
104c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        loaded = dlopen(origName, RTLD_NOW | RTLD_LOCAL);
105c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        if (loaded) {
106c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            LoadedLibraries.insert(origName);
107c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        }
108c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        return loaded;
109c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
110c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
111c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    std::string newName(cacheDir);
112ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    newName.append("/com.android.renderscript.cache/");
113ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines
114ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    if (!ensureCacheDirExists(newName.c_str())) {
115ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines        ALOGE("Could not verify or create cache dir: %s", cacheDir);
116ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines        return NULL;
117ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    }
118ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines
119ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    // Construct an appropriately randomized filename for the symlink.
120ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    newName.append("librs.");
121c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    newName.append(resName);
122c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    newName.append("#");
123c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    newName.append(getRandomString(6));  // 62^6 potential filename variants.
124c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    newName.append(".so");
125c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
126c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    int r = symlink(origName, newName.c_str());
127c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (r != 0) {
128c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        ALOGE("Could not create symlink %s -> %s", newName.c_str(), origName);
129c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        return NULL;
130c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
131c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    loaded = dlopen(newName.c_str(), RTLD_NOW | RTLD_LOCAL);
132c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    r = unlink(newName.c_str());
133c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (r != 0) {
134c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        ALOGE("Could not unlink symlink %s", newName.c_str());
135c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
136c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (loaded) {
137c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        LoadedLibraries.insert(newName.c_str());
138c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
139c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
140c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    return loaded;
141c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines}
142c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
143c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// Load the shared library referred to by cacheDir and resName. If we have
144c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// already loaded this library, we instead create a new symlink (in the
145c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// cache dir) and then load that. We then immediately destroy the symlink.
146c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// This is required behavior to implement script instancing for the support
147c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines// library, since shared objects are loaded and de-duped by name only.
148c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hinesstatic void *loadSharedLibrary(const char *cacheDir, const char *resName) {
149c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    void *loaded = NULL;
150c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    //arc4random_stir();
151c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines#ifndef RS_SERVER
152c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    std::string scriptSOName(cacheDir);
153c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    size_t cutPos = scriptSOName.rfind("cache");
154c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (cutPos != std::string::npos) {
155c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        scriptSOName.erase(cutPos);
156c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    } else {
157c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        ALOGE("Found peculiar cacheDir (missing \"cache\"): %s", cacheDir);
158c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
159c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    scriptSOName.append("/lib/librs.");
160c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines#else
161c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    std::string scriptSOName("lib");
162c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines#endif
163c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    scriptSOName.append(resName);
164c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    scriptSOName.append(".so");
165c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
166c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // We should check if we can load the library from the standard app
167c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    // location for shared libraries first.
168c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    loaded = loadSOHelper(scriptSOName.c_str(), cacheDir, resName);
169c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
170c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    if (loaded == NULL) {
171c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        ALOGE("Unable to open shared library (%s): %s",
172c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines              scriptSOName.c_str(), dlerror());
173c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
174c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        // One final attempt to find the library in "/system/lib".
175c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        // We do this to allow bundled applications to use the compatibility
176c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        // library fallback path. Those applications don't have a private
177c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        // library path, so they need to install to the system directly.
178c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        // Note that this is really just a testing path.
179c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        android::String8 scriptSONameSystem("/system/lib/librs.");
180c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        scriptSONameSystem.append(resName);
181c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        scriptSONameSystem.append(".so");
182c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        loaded = loadSOHelper(scriptSONameSystem.c_str(), cacheDir,
183c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines                              resName);
184c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        if (loaded == NULL) {
185c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines            ALOGE("Unable to open system shared library (%s): %s",
186c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines                  scriptSONameSystem.c_str(), dlerror());
187c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        }
188c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    }
189c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
190c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    return loaded;
191c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines}
192c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
1939ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#else  // RS_COMPATIBILITY_LIB is not defined
194c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines
195ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hinesstatic bool is_force_recompile() {
196ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#ifdef RS_SERVER
197ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  return false;
198ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#else
199ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  char buf[PROPERTY_VALUE_MAX];
200ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
201ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  // Re-compile if floating point precision has been overridden.
202ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  property_get("debug.rs.precision", buf, "");
203ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  if (buf[0] != '\0') {
204ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return true;
205ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  }
206ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
207ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  // Re-compile if debug.rs.forcerecompile is set.
208ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  property_get("debug.rs.forcerecompile", buf, "0");
209ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  if ((::strcmp(buf, "1") == 0) || (::strcmp(buf, "true") == 0)) {
210ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return true;
211ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  } else {
212ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return false;
213ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  }
214ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#endif  // RS_SERVER
215ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines}
216b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
217b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hinesconst static char *BCC_EXE_PATH = "/system/bin/bcc";
218b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
21940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouilletstatic void setCompileArguments(std::vector<const char*>* args, const android::String8& bcFileName,
22040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                                const char* cacheDir, const char* resName, const char* core_lib,
22140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                                bool useRSDebugContext, const char* bccPluginName) {
22240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    rsAssert(cacheDir && resName && core_lib);
22340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(BCC_EXE_PATH);
22440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-o");
22540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(resName);
22640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-output_path");
22740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(cacheDir);
22840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-bclib");
22940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(core_lib);
23040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-mtriple");
23140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(DEFAULT_TARGET_TRIPLE_STRING);
23240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
233c8d7a9313bb9bf980a4f88cf1b4a6437b7b95797Tim Murray    // Enable workaround for A53 codegen by default.
234c8d7a9313bb9bf980a4f88cf1b4a6437b7b95797Tim Murray#if defined(__aarch64__) && !defined(DISABLE_A53_WORKAROUND)
235c8d7a9313bb9bf980a4f88cf1b4a6437b7b95797Tim Murray    args->push_back("-aarch64-fix-cortex-a53-835769");
236c8d7a9313bb9bf980a4f88cf1b4a6437b7b95797Tim Murray#endif
237c8d7a9313bb9bf980a4f88cf1b4a6437b7b95797Tim Murray
23840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    // Execute the bcc compiler.
23940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    if (useRSDebugContext) {
24040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        args->push_back("-rs-debug-ctx");
24140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    } else {
24240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        // Only load additional libraries for compiles that don't use
24340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        // the debug context.
24440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        if (bccPluginName && strlen(bccPluginName) > 0) {
24540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            args->push_back("-load");
24640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            args->push_back(bccPluginName);
24740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        }
24840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    }
24940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
25040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(bcFileName.string());
25140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(NULL);
25240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet}
25340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
25440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouilletstatic bool compileBitcode(const android::String8& bcFileName,
255b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           const char *bitcode,
256b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           size_t bitcodeSize,
25740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                           const char** compileArguments,
25840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                           const std::string& compileCommandLine) {
25940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    rsAssert(bitcode && bitcodeSize);
26040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
26140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    FILE *bcfile = fopen(bcFileName.string(), "w");
262b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (!bcfile) {
26340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        ALOGE("Could not write to %s", bcFileName.string());
264b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
265b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
266b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    size_t nwritten = fwrite(bitcode, 1, bitcodeSize, bcfile);
267b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    fclose(bcfile);
268b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (nwritten != bitcodeSize) {
269b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not write %zu bytes to %s", bitcodeSize,
27040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet              bcFileName.string());
271b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
272b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
273b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
274b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    pid_t pid = fork();
275005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines
276b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    switch (pid) {
277b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case -1: {  // Error occurred (we attempt no recovery)
278b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Couldn't fork for bcc compiler execution");
279b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
280b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
281b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case 0: {  // Child process
28240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        ALOGV("Invoking BCC with: %s", compileCommandLine.c_str());
28340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        execv(BCC_EXE_PATH, (char* const*)compileArguments);
284005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines
285005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines        ALOGE("execv() failed: %s", strerror(errno));
286b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        abort();
287b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
288b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
289b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    default: {  // Parent process (actual driver)
290b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        // Wait on child process to finish compiling the source.
291b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        int status = 0;
292b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        pid_t w = waitpid(pid, &status, 0);
293b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        if (w == -1) {
294b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            ALOGE("Could not wait for bcc compiler");
295b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            return false;
296b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        }
297b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
298b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
299b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            return true;
300b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        }
301b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
302b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("bcc compiler terminated unexpectedly");
303b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
304b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
305b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
306b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines}
307b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
308ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#endif  // !defined(RS_COMPATIBILITY_LIB)
309c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines}  // namespace
310ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
311709a0978ae141198018ca9769f8d96292a8928e6Jason Samsnamespace android {
312709a0978ae141198018ca9769f8d96292a8928e6Jason Samsnamespace renderscript {
313709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
314110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
315110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define MAXLINE 500
316110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define MAKE_STR_HELPER(S) #S
317110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define MAKE_STR(S) MAKE_STR_HELPER(S)
318110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_VAR_STR "exportVarCount: "
319110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_FUNC_STR "exportFuncCount: "
320110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define EXPORT_FOREACH_STR "exportForEachCount: "
321110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#define OBJECT_SLOT_STR "objectSlotCount: "
322110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
323110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams// Copy up to a newline or size chars from str -> s, updating str
324110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams// Returns s when successful and NULL when '\0' is finally reached.
325110f181b7966212a36ef18016f9b81c7322d0a2fJason Samsstatic char* strgets(char *s, int size, const char **ppstr) {
326110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (!ppstr || !*ppstr || **ppstr == '\0' || size < 1) {
327110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        return NULL;
328110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
329110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
330110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int i;
331110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    for (i = 0; i < (size - 1); i++) {
332110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        s[i] = **ppstr;
333110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        (*ppstr)++;
334110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (s[i] == '\0') {
335110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            return s;
336110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        } else if (s[i] == '\n') {
337110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            s[i+1] = '\0';
338110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            return s;
339110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
340110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
341110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
342110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // size has been exceeded.
343110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    s[i] = '\0';
344110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
345110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    return s;
346110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams}
347110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
348709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
349709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptImpl::RsdCpuScriptImpl(RsdCpuReferenceImpl *ctx, const Script *s) {
350709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx = ctx;
351709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mScript = s;
352709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
353110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
354110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mScriptSO = NULL;
355110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mInvokeFunctions = NULL;
356110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mForEachFunctions = NULL;
357110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mFieldAddress = NULL;
358110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mFieldIsObject = NULL;
359110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mForEachSignatures = NULL;
360110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
361110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCompilerContext = NULL;
362110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCompilerDriver = NULL;
363110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mExecutable = NULL;
364110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
365110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
366e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray
367709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRoot = NULL;
368709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRootExpand = NULL;
369709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mInit = NULL;
370709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mFreeChildren = NULL;
371709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
372709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
373709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mBoundAllocs = NULL;
374709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mIntrinsicData = NULL;
375709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mIsThreadable = true;
376709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
377709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
378709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
379709a0978ae141198018ca9769f8d96292a8928e6Jason Samsbool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir,
380709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                            uint8_t const *bitcode, size_t bitcodeSize,
381005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines                            uint32_t flags, char const *bccPluginName) {
382709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc);
383709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("rsdScriptInit %p %p", rsc, script);
384709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
385709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->lockMutex();
386110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
387005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines    bool useRSDebugContext = false;
388709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
389709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerContext = NULL;
390709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver = NULL;
391709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mExecutable = NULL;
392709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
393709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerContext = new bcc::BCCContext();
394709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerContext == NULL) {
395709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGE("bcc: FAILS to create compiler context (out of memory)");
396709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->unlockMutex();
397709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return false;
398709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
399709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
400709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver = new bcc::RSCompilerDriver();
401709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerDriver == NULL) {
402709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGE("bcc: FAILS to create compiler driver (out of memory)");
403709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->unlockMutex();
404709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return false;
405709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
406709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
40725e3af55a43faddced1a9931574dfdc3cc8ad8fdStephen Hines    // Configure symbol resolvers (via compiler-rt and the RS runtime).
40825e3af55a43faddced1a9931574dfdc3cc8ad8fdStephen Hines    mRSRuntime.setLookupFunction(lookupRuntimeStub);
40925e3af55a43faddced1a9931574dfdc3cc8ad8fdStephen Hines    mRSRuntime.setContext(this);
41025e3af55a43faddced1a9931574dfdc3cc8ad8fdStephen Hines    mResolver.chainResolver(mCompilerRuntime);
41125e3af55a43faddced1a9931574dfdc3cc8ad8fdStephen Hines    mResolver.chainResolver(mRSRuntime);
412709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
413b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    // Run any compiler setup functions we have been provided with.
414b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    RSSetupCompilerCallback setupCompilerCallback =
415b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines            mCtx->getSetupCompilerCallback();
416b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    if (setupCompilerCallback != NULL) {
417b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines        setupCompilerCallback(mCompilerDriver);
418b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    }
419b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines
42040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcinfo::MetadataExtractor bitcodeMetadata((const char *) bitcode, bitcodeSize);
42140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    if (!bitcodeMetadata.extract()) {
422b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not extract metadata from bitcode");
423f94e8db4232979b2fc93e8a77c42bfa57d3da56aStephen Hines        mCtx->unlockMutex();
424b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
425b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
426b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
42740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    const char* core_lib = findCoreLib(bitcodeMetadata, (const char*)bitcode, bitcodeSize);
428cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines
429cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines    if (mCtx->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
430f47e8b4b86bf194e65398032f3f5f47a6da89f3fStephen Hines        mCompilerDriver->setDebugContext(true);
431005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines        useRSDebugContext = true;
432ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    }
433ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
43440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    android::String8 bcFileName(cacheDir);
43540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcFileName.append("/");
43640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcFileName.append(resName);
43740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcFileName.append(".bc");
43840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
43940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    std::vector<const char*> compileArguments;
44040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    setCompileArguments(&compileArguments, bcFileName, cacheDir, resName, core_lib,
44140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                        useRSDebugContext, bccPluginName);
44240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    // The last argument of compileArguments ia a NULL, so remove 1 from the size.
44340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    std::string compileCommandLine =
44440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                bcc::getCommandLine(compileArguments.size() - 1, compileArguments.data());
44540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
44640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    if (!is_force_recompile()) {
44740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        // Load the compiled script that's in the cache, if any.
44840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        mExecutable = bcc::RSCompilerDriver::loadScript(cacheDir, resName, (const char*)bitcode,
44940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                                                        bitcodeSize, compileCommandLine.c_str(),
45040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                                                        mResolver);
451cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines    }
452709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
45340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    // If we can't, it's either not there or out of date.  We compile the bit code and try loading
45440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    // again.
45540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    if (mExecutable == NULL) {
45640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        if (!compileBitcode(bcFileName, (const char*)bitcode, bitcodeSize, compileArguments.data(),
45740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                            compileCommandLine)) {
45840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            ALOGE("bcc: FAILS to compile '%s'", resName);
45940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            mCtx->unlockMutex();
46040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            return false;
46140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        }
46240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        mExecutable = bcc::RSCompilerDriver::loadScript(cacheDir, resName, (const char*)bitcode,
46340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                                                        bitcodeSize, compileCommandLine.c_str(),
46440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                                                        mResolver);
46540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        if (mExecutable == NULL) {
46640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            ALOGE("bcc: FAILS to load freshly compiled executable for '%s'", resName);
46740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            mCtx->unlockMutex();
46840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            return false;
46940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        }
470709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
471709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
47240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    mExecutable->setThreadable(mIsThreadable);
47340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    if (!mExecutable->syncInfo()) {
474709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGW("bcc: FAILS to synchronize the RS info file to the disk");
475709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
476709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
47740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    mRoot = reinterpret_cast<int (*)()>(mExecutable->getSymbolAddress("root"));
478709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mRootExpand =
47940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        reinterpret_cast<int (*)()>(mExecutable->getSymbolAddress("root.expand"));
48040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    mInit = reinterpret_cast<void (*)()>(mExecutable->getSymbolAddress("init"));
481709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mFreeChildren =
48240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        reinterpret_cast<void (*)()>(mExecutable->getSymbolAddress(".rs.dtor"));
483709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
484709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
48540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    if (bitcodeMetadata.getExportVarCount()) {
48640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        mBoundAllocs = new Allocation *[bitcodeMetadata.getExportVarCount()];
48740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        memset(mBoundAllocs, 0, sizeof(void *) * bitcodeMetadata.getExportVarCount());
48829809d1f95d4cd4cbc6b2f9384b3321759691e13Tim Murray    }
48929809d1f95d4cd4cbc6b2f9384b3321759691e13Tim Murray
49040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    for (size_t i = 0; i < bitcodeMetadata.getExportForEachSignatureCount(); i++) {
49140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        char* name = new char[strlen(bitcodeMetadata.getExportForEachNameList()[i]) + 1];
49240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        mExportedForEachFuncList.push_back(
49340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                    std::make_pair(name, bitcodeMetadata.getExportForEachSignatureList()[i]));
494709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
495709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
496f4d216ee0f0ef18edbde208a61dc4e2fe4c8f050Jean-Luc Brouillet#else  // RS_COMPATIBILITY_LIB is defined
497110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
498c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    mScriptSO = loadSharedLibrary(cacheDir, resName);
499110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
500110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
501110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        char line[MAXLINE];
502110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mRoot = (RootFunc_t) dlsym(mScriptSO, "root");
503110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mRoot) {
504110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found root(): %p", mRoot);
505110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
506110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mRootExpand = (RootFunc_t) dlsym(mScriptSO, "root.expand");
507110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mRootExpand) {
508110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found root.expand(): %p", mRootExpand);
509110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
510110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mInit = (InvokeFunc_t) dlsym(mScriptSO, "init");
511110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mInit) {
512110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found init(): %p", mInit);
513110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
514110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mFreeChildren = (InvokeFunc_t) dlsym(mScriptSO, ".rs.dtor");
515110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mFreeChildren) {
516110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found .rs.dtor(): %p", mFreeChildren);
517110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
518110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
519110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        const char *rsInfo = (const char *) dlsym(mScriptSO, ".rs.info");
520110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (rsInfo) {
521110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //ALOGE("Found .rs.info(): %p - %s", rsInfo, rsInfo);
522110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
523110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
524110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t varCount = 0;
525110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
526110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
527110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
528110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, EXPORT_VAR_STR "%zu", &varCount) != 1) {
529110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid export var count!: %s", line);
530110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
531110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
532110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
533110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mExportedVariableCount = varCount;
534110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        //ALOGE("varCount: %zu", varCount);
535110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (varCount > 0) {
536110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            // Start by creating/zeroing this member, since we don't want to
537110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            // accidentally clean up invalid pointers later (if we error out).
538110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mFieldIsObject = new bool[varCount];
539110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mFieldIsObject == NULL) {
540110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
541110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
542110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            memset(mFieldIsObject, 0, varCount * sizeof(*mFieldIsObject));
543110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mFieldAddress = new void*[varCount];
544110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mFieldAddress == NULL) {
545110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
546110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
547110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < varCount; ++i) {
548110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
549110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
550110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
551110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                char *c = strrchr(line, '\n');
552110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (c) {
553110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    *c = '\0';
554110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
555110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mFieldAddress[i] = dlsym(mScriptSO, line);
556110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (mFieldAddress[i] == NULL) {
557110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Failed to find variable address for %s: %s",
558110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                          line, dlerror());
559110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    // Not a critical error if we don't find a global variable.
560110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
561110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                else {
562110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //ALOGE("Found variable %s at %p", line,
563110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //mFieldAddress[i]);
564110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
565110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
566110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
567110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
568110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t funcCount = 0;
569110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
570110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
571110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
572110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, EXPORT_FUNC_STR "%zu", &funcCount) != 1) {
573110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid export func count!: %s", line);
574110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
575110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
576110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
577110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mExportedFunctionCount = funcCount;
578110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        //ALOGE("funcCount: %zu", funcCount);
579110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
580110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (funcCount > 0) {
581110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mInvokeFunctions = new InvokeFunc_t[funcCount];
582110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mInvokeFunctions == NULL) {
583110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
584110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
585110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < funcCount; ++i) {
586110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
587110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
588110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
589110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                char *c = strrchr(line, '\n');
590110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (c) {
591110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    *c = '\0';
592110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
593110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
594110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mInvokeFunctions[i] = (InvokeFunc_t) dlsym(mScriptSO, line);
595110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (mInvokeFunctions[i] == NULL) {
596110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Failed to get function address for %s(): %s",
597110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                          line, dlerror());
598110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
599110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
600110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                else {
601110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //ALOGE("Found InvokeFunc_t %s at %p", line, mInvokeFunctions[i]);
602110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
603110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
604110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
605110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
606110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t forEachCount = 0;
607110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
608110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
609110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
610110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, EXPORT_FOREACH_STR "%zu", &forEachCount) != 1) {
611110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid export forEach count!: %s", line);
612110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
613110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
614110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
615110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (forEachCount > 0) {
616110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
617110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mForEachSignatures = new uint32_t[forEachCount];
618110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mForEachSignatures == NULL) {
619110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
620110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
621110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mForEachFunctions = new ForEachFunc_t[forEachCount];
622110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mForEachFunctions == NULL) {
623110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                goto error;
624110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
625110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < forEachCount; ++i) {
626110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                unsigned int tmpSig = 0;
627110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                char tmpName[MAXLINE];
628110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
629110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
630110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
631110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
632110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (sscanf(line, "%u - %" MAKE_STR(MAXLINE) "s",
633110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                           &tmpSig, tmpName) != 2) {
634110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Invalid export forEach!: %s", line);
635110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
636110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
637110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
638110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                // Lookup the expanded ForEach kernel.
639110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                strncat(tmpName, ".expand", MAXLINE-1-strlen(tmpName));
640110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mForEachSignatures[i] = tmpSig;
641110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                mForEachFunctions[i] =
642110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                        (ForEachFunc_t) dlsym(mScriptSO, tmpName);
643ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                if (i != 0 && mForEachFunctions[i] == NULL) {
644110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    // Ignore missing root.expand functions.
645110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    // root() is always specified at location 0.
646ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                    ALOGE("Failed to find forEach function address for %s: %s",
647ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                          tmpName, dlerror());
648ef7481e2f0a4ad7b32bb626245e4207cabe171dcStephen Hines                    goto error;
649110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
650110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                else {
651110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    //ALOGE("Found forEach %s at %p", tmpName, mForEachFunctions[i]);
652110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
653110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
654110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
655110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
656110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        size_t objectSlotCount = 0;
657110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (strgets(line, MAXLINE, &rsInfo) == NULL) {
658110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
659110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
660110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (sscanf(line, OBJECT_SLOT_STR "%zu", &objectSlotCount) != 1) {
661110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            ALOGE("Invalid object slot count!: %s", line);
662110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            goto error;
663110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
664110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
665110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (objectSlotCount > 0) {
666110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            rsAssert(varCount > 0);
667110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            for (size_t i = 0; i < objectSlotCount; ++i) {
668110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                uint32_t varNum = 0;
669110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (strgets(line, MAXLINE, &rsInfo) == NULL) {
670110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
671110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
672110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (sscanf(line, "%u", &varNum) != 1) {
673110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    ALOGE("Invalid object slot!: %s", line);
674110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    goto error;
675110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
676110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
677110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (varNum < varCount) {
678110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    mFieldIsObject[varNum] = true;
679110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
680110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
681110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
682110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
683110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (varCount > 0) {
684110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            mBoundAllocs = new Allocation *[varCount];
685110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            memset(mBoundAllocs, 0, varCount * sizeof(*mBoundAllocs));
686110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
687110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
688110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        if (mScriptSO == (void*)1) {
689110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            //rsdLookupRuntimeStub(script, "acos");
690110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
691c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    } else {
692c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        goto error;
693110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
694110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
695709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->unlockMutex();
696709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return true;
697110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
698110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
699110f181b7966212a36ef18016f9b81c7322d0a2fJason Samserror:
700110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
701110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCtx->unlockMutex();
702110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mInvokeFunctions;
703110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mForEachFunctions;
704110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mFieldAddress;
705110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mFieldIsObject;
706110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mForEachSignatures;
707110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    delete[] mBoundAllocs;
708110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
709110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        dlclose(mScriptSO);
710110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
711110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    return false;
712110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
713709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
714709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
7159ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#ifndef RS_COMPATIBILITY_LIB
7169ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
7179ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#ifdef __LP64__
7189ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#define SYSLIBPATH "/system/lib64"
7199ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#else
7209ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#define SYSLIBPATH "/system/lib"
7219ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#endif
7229ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
7239ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouilletconst char* RsdCpuScriptImpl::findCoreLib(const bcinfo::MetadataExtractor& ME, const char* bitcode,
7249ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet                                          size_t bitcodeSize) {
7259ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    const char* defaultLib = SYSLIBPATH"/libclcore.bc";
7269ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
7279ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // If we're debugging, use the debug library.
7289ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    if (mCtx->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
7299ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return SYSLIBPATH"/libclcore_debug.bc";
7309ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    }
7319ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
7329ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // If a callback has been registered to specify a library, use that.
7339ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    RSSelectRTCallback selectRTCallback = mCtx->getSelectRTCallback();
7349ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    if (selectRTCallback != NULL) {
7359ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return selectRTCallback((const char*)bitcode, bitcodeSize);
7369ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    }
7379ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
7389ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // Check for a platform specific library
7399ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#if defined(ARCH_ARM_HAVE_NEON) && !defined(DISABLE_CLCORE_NEON)
7409ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    enum bcinfo::RSFloatPrecision prec = ME.getRSFloatPrecision();
7417ebb02bf54cc3e6b6424c8da642ed75b460cc40dJean-Luc Brouillet    if (prec == bcinfo::RS_FP_Relaxed) {
7429ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // NEON-capable ARMv7a devices can use an accelerated math library
7439ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // for all reduced precision scripts.
7449ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // ARMv8 does not use NEON, as ASIMD can be used with all precision
7459ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // levels.
7469ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return SYSLIBPATH"/libclcore_neon.bc";
7479ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    } else {
7489ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return defaultLib;
7499ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    }
7509ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#elif defined(__i386__) || defined(__x86_64__)
7519ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // x86 devices will use an optimized library.
7529ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    return SYSLIBPATH"/libclcore_x86.bc";
7539ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#else
7549ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    return defaultLib;
7559ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#endif
7569ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet}
7579ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
7589ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#endif
7599ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
760709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::populateScript(Script *script) {
761110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
762709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // Copy info over to runtime
76329809d1f95d4cd4cbc6b2f9384b3321759691e13Tim Murray    script->mHal.info.exportedFunctionCount = mExecutable->getExportFuncAddrs().size();
76429809d1f95d4cd4cbc6b2f9384b3321759691e13Tim Murray    script->mHal.info.exportedVariableCount = mExecutable->getExportVarAddrs().size();
76529809d1f95d4cd4cbc6b2f9384b3321759691e13Tim Murray    script->mHal.info.exportedForeachFuncList = &mExportedForEachFuncList[0];
76629809d1f95d4cd4cbc6b2f9384b3321759691e13Tim Murray    script->mHal.info.exportedPragmaCount = mExecutable->getPragmaKeys().size();
767709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedPragmaKeyList =
768709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const_cast<const char**>(mExecutable->getPragmaKeys().array());
769709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    script->mHal.info.exportedPragmaValueList =
770709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const_cast<const char**>(mExecutable->getPragmaValues().array());
771709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
772709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mRootExpand) {
773709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        script->mHal.info.root = mRootExpand;
774709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
775709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        script->mHal.info.root = mRoot;
776709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
777110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
778110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // Copy info over to runtime
779110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedFunctionCount = mExportedFunctionCount;
780110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedVariableCount = mExportedVariableCount;
781110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedPragmaCount = 0;
782110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedPragmaKeyList = 0;
783110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    script->mHal.info.exportedPragmaValueList = 0;
784110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
785110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // Bug, need to stash in metadata
786110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mRootExpand) {
787110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        script->mHal.info.root = mRootExpand;
788110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    } else {
789110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        script->mHal.info.root = mRoot;
790110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
791110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
792709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
793709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
794709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
795709a0978ae141198018ca9769f8d96292a8928e6Jason Samstypedef void (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
796709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
797709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::forEachMtlsSetup(const Allocation * ain, Allocation * aout,
798709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        const void * usr, uint32_t usrLen,
799709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        const RsScriptCall *sc,
800709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        MTLaunchStruct *mtls) {
801709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
802709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memset(mtls, 0, sizeof(MTLaunchStruct));
803709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
8043a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    // possible for this to occur if IO_OUTPUT/IO_INPUT with no bound surface
8053a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    if (ain && (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr == NULL) {
806ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null in allocations");
8073a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray        return;
8083a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    }
8093a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    if (aout && (const uint8_t *)aout->mHal.drvState.lod[0].mallocPtr == NULL) {
810ddceab9a001f07a3395226c5e06e3b420720af0fJason Sams        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null out allocations");
8113a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray        return;
8123a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray    }
8133a25fdd3786c1a08b783d8a83ef94b756347ff5cTim Murray
8144b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (ain != NULL) {
8154b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Type *inType = ain->getType();
8164b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
8174b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimX = inType->getDimX();
8184b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimY = inType->getDimY();
8194b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimZ = inType->getDimZ();
8204b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
8214b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else if (aout != NULL) {
8224b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Type *outType = aout->getType();
8234b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
8244b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimX = outType->getDimX();
8254b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimY = outType->getDimY();
8264b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimZ = outType->getDimZ();
8274b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
828709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
829709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
830709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
831709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
832709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
8334b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (ain != NULL && aout != NULL) {
8344b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        if (!ain->hasSameDims(aout)) {
8354b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
8364b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes              "Failed to launch kernel; dimensions of input and output allocations do not match.");
8374b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
8384b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            return;
8394b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
8404b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
8414b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
842709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!sc || (sc->xEnd == 0)) {
843709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->xEnd = mtls->fep.dimX;
844709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
845709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->xStart < mtls->fep.dimX);
846709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->xEnd <= mtls->fep.dimX);
847709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->xStart < sc->xEnd);
848709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->xStart = rsMin(mtls->fep.dimX, sc->xStart);
849709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->xEnd = rsMin(mtls->fep.dimX, sc->xEnd);
850709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (mtls->xStart >= mtls->xEnd) return;
851709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
852709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
853709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!sc || (sc->yEnd == 0)) {
854709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->yEnd = mtls->fep.dimY;
855709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    } else {
856709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->yStart < mtls->fep.dimY);
857709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->yEnd <= mtls->fep.dimY);
858709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        rsAssert(sc->yStart < sc->yEnd);
859709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->yStart = rsMin(mtls->fep.dimY, sc->yStart);
860709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->yEnd = rsMin(mtls->fep.dimY, sc->yEnd);
861709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (mtls->yStart >= mtls->yEnd) return;
862709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
863709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
864d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray    if (!sc || (sc->zEnd == 0)) {
865d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        mtls->zEnd = mtls->fep.dimZ;
866d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray    } else {
867d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        rsAssert(sc->zStart < mtls->fep.dimZ);
868d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        rsAssert(sc->zEnd <= mtls->fep.dimZ);
869d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        rsAssert(sc->zStart < sc->zEnd);
870d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        mtls->zStart = rsMin(mtls->fep.dimZ, sc->zStart);
871d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        mtls->zEnd = rsMin(mtls->fep.dimZ, sc->zEnd);
872d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray        if (mtls->zStart >= mtls->zEnd) return;
873d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray    }
874d4ecb17adc9b099351f2ca1779a74f5283f20a3dTim Murray
875709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->xEnd = rsMax((uint32_t)1, mtls->xEnd);
876709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->yEnd = rsMax((uint32_t)1, mtls->yEnd);
877709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->zEnd = rsMax((uint32_t)1, mtls->zEnd);
878709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->arrayEnd = rsMax((uint32_t)1, mtls->arrayEnd);
879709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
880709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(!ain || (ain->getType()->getDimZ() == 0));
881709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
882709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->rsc = mCtx;
883709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->ain = ain;
884709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->aout = aout;
885709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.usr = usr;
886709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.usrLen = usrLen;
887709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->mSliceSize = 1;
888709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->mSliceNum = 0;
889709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
890709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.ptrIn = NULL;
891709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.eStrideIn = 0;
892709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->isThreadable = mIsThreadable;
893709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
894709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (ain) {
895709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.ptrIn = (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr;
896709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.eStrideIn = ain->getType()->getElementSizeBytes();
897709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.yStrideIn = ain->mHal.drvState.lod[0].stride;
898709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
899709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
900709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.ptrOut = NULL;
901709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.eStrideOut = 0;
902709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (aout) {
903709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.ptrOut = (uint8_t *)aout->mHal.drvState.lod[0].mallocPtr;
904709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.eStrideOut = aout->getType()->getElementSizeBytes();
905709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mtls->fep.yStrideOut = aout->mHal.drvState.lod[0].stride;
906709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
907709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
908709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
9094b3c34e6833e39bc89c2128002806b654b8e623dChris Wailesvoid RsdCpuScriptImpl::forEachMtlsSetup(const Allocation ** ains, uint32_t inLen,
9104b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                                        Allocation * aout,
9114b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                                        const void * usr, uint32_t usrLen,
9124b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                                        const RsScriptCall *sc,
9134b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                                        MTLaunchStruct *mtls) {
9144b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9154b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    memset(mtls, 0, sizeof(MTLaunchStruct));
9164b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9174b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    // possible for this to occur if IO_OUTPUT/IO_INPUT with no bound surface
9184b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (ains != NULL) {
9194b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        for (int index = inLen; --index >= 0;) {
9204b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            const Allocation* ain = ains[index];
9214b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9224b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            if (ain != NULL && (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr == NULL) {
9234b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null in allocations");
9244b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                return;
9254b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            }
9264b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
9274b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
9284b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9294b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (aout && (const uint8_t *)aout->mHal.drvState.lod[0].mallocPtr == NULL) {
9304b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null out allocations");
9314b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        return;
9324b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
9334b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9344b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (ains != NULL) {
9354b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Allocation *ain0   = ains[0];
9364b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Type       *inType = ain0->getType();
9374b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9384b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimX = inType->getDimX();
9394b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimY = inType->getDimY();
9404b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimZ = inType->getDimZ();
9414b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9424b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        for (int Index = inLen; --Index >= 1;) {
9434b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            if (!ain0->hasSameDims(ains[Index])) {
9444b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
9454b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                  "Failed to launch kernel; dimensions of input and output allocations do not match.");
9464b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9474b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                return;
9484b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            }
9494b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
9504b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9514b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else if (aout != NULL) {
9524b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Type *outType = aout->getType();
9534b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9544b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimX = outType->getDimX();
9554b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimY = outType->getDimY();
9564b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.dimZ = outType->getDimZ();
9574b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9584b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
9594b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
9604b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        return;
9614b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
9624b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9634b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (ains != NULL && aout != NULL) {
9644b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        if (!ains[0]->hasSameDims(aout)) {
9654b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
9664b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes              "Failed to launch kernel; dimensions of input and output allocations do not match.");
9674b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9684b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            return;
9694b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
9704b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
9714b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9724b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (!sc || (sc->xEnd == 0)) {
9734b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->xEnd = mtls->fep.dimX;
9744b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
9754b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        rsAssert(sc->xStart < mtls->fep.dimX);
9764b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        rsAssert(sc->xEnd <= mtls->fep.dimX);
9774b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        rsAssert(sc->xStart < sc->xEnd);
9784b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->xStart = rsMin(mtls->fep.dimX, sc->xStart);
9794b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->xEnd = rsMin(mtls->fep.dimX, sc->xEnd);
9804b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        if (mtls->xStart >= mtls->xEnd) return;
9814b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
9824b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9834b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (!sc || (sc->yEnd == 0)) {
9844b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->yEnd = mtls->fep.dimY;
9854b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
9864b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        rsAssert(sc->yStart < mtls->fep.dimY);
9874b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        rsAssert(sc->yEnd <= mtls->fep.dimY);
9884b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        rsAssert(sc->yStart < sc->yEnd);
9894b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->yStart = rsMin(mtls->fep.dimY, sc->yStart);
9904b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->yEnd = rsMin(mtls->fep.dimY, sc->yEnd);
9914b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        if (mtls->yStart >= mtls->yEnd) return;
9924b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
9934b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
9944b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (!sc || (sc->zEnd == 0)) {
9954b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->zEnd = mtls->fep.dimZ;
9964b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
9974b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        rsAssert(sc->zStart < mtls->fep.dimZ);
9984b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        rsAssert(sc->zEnd <= mtls->fep.dimZ);
9994b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        rsAssert(sc->zStart < sc->zEnd);
10004b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->zStart = rsMin(mtls->fep.dimZ, sc->zStart);
10014b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->zEnd = rsMin(mtls->fep.dimZ, sc->zEnd);
10024b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        if (mtls->zStart >= mtls->zEnd) return;
10034b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
10044b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10054b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->xEnd     = rsMax((uint32_t)1, mtls->xEnd);
10064b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->yEnd     = rsMax((uint32_t)1, mtls->yEnd);
10074b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->zEnd     = rsMax((uint32_t)1, mtls->zEnd);
10084b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->arrayEnd = rsMax((uint32_t)1, mtls->arrayEnd);
10094b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10104b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    rsAssert(!ains || (ains[0]->getType()->getDimZ() == 0));
10114b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10124b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->rsc        = mCtx;
10134b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->ains       = ains;
10144b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->aout       = aout;
10154b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->fep.usr    = usr;
10164b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->fep.usrLen = usrLen;
10174b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->mSliceSize = 1;
10184b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->mSliceNum  = 0;
10194b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10204b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->fep.ptrIns    = NULL;
10214b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->fep.eStrideIn = 0;
10224b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->isThreadable  = mIsThreadable;
10234b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10244b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (ains) {
10254b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.ptrIns    = new const uint8_t*[inLen];
10264b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.inStrides = new StridePair[inLen];
10274b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10284b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        for (int index = inLen; --index >= 0;) {
10294b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            const Allocation *ain = ains[index];
10304b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10314b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            mtls->fep.ptrIns[index] =
10324b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes              (const uint8_t*)ain->mHal.drvState.lod[0].mallocPtr;
10334b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10344b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            mtls->fep.inStrides[index].eStride =
10354b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes              ain->getType()->getElementSizeBytes();
10364b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            mtls->fep.inStrides[index].yStride =
10374b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes              ain->mHal.drvState.lod[0].stride;
10384b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
10394b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
10404b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10414b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->fep.ptrOut = NULL;
10424b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->fep.eStrideOut = 0;
10434b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (aout) {
10444b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.ptrOut     = (uint8_t *)aout->mHal.drvState.lod[0].mallocPtr;
10454b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.eStrideOut = aout->getType()->getElementSizeBytes();
10464b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        mtls->fep.yStrideOut = aout->mHal.drvState.lod[0].stride;
10474b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
10484b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes}
10494b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
1050709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1051709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeForEach(uint32_t slot,
1052709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const Allocation * ain,
1053709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     Allocation * aout,
1054709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const void * usr,
1055709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     uint32_t usrLen,
1056709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const RsScriptCall *sc) {
1057709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1058709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    MTLaunchStruct mtls;
1059709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    forEachMtlsSetup(ain, aout, usr, usrLen, sc, &mtls);
1060709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    forEachKernelSetup(slot, &mtls);
1061709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1062709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
1063709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->launchThreads(ain, aout, sc, &mtls);
1064709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
1065709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1066709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
10674b3c34e6833e39bc89c2128002806b654b8e623dChris Wailesvoid RsdCpuScriptImpl::invokeForEachMulti(uint32_t slot,
10684b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                                          const Allocation ** ains,
10694b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                                          uint32_t inLen,
10704b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                                          Allocation * aout,
10714b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                                          const void * usr,
10724b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                                          uint32_t usrLen,
10734b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                                          const RsScriptCall *sc) {
10744b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10754b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    MTLaunchStruct mtls;
10764b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10774b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    forEachMtlsSetup(ains, inLen, aout, usr, usrLen, sc, &mtls);
10784b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    forEachKernelSetup(slot, &mtls);
10794b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
10804b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
10814b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mCtx->launchThreads(ains, inLen, aout, sc, &mtls);
10824b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mCtx->setTLS(oldTLS);
10834b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes}
10844b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
1085709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::forEachKernelSetup(uint32_t slot, MTLaunchStruct *mtls) {
1086709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->script = this;
1087709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.slot = slot;
1088110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
1089709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(slot < mExecutable->getExportForeachFuncAddrs().size());
1090709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->kernel = reinterpret_cast<ForEachFunc_t>(
1091709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                      mExecutable->getExportForeachFuncAddrs()[slot]);
1092709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(mtls->kernel != NULL);
1093709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->sig = mExecutable->getInfo().getExportForeachFuncs()[slot].second;
1094110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
1095110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mtls->kernel = reinterpret_cast<ForEachFunc_t>(mForEachFunctions[slot]);
1096110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    rsAssert(mtls->kernel != NULL);
1097110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mtls->sig = mForEachSignatures[slot];
1098110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
1099709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1100709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1101709a0978ae141198018ca9769f8d96292a8928e6Jason Samsint RsdCpuScriptImpl::invokeRoot() {
1102709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
1103709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int ret = mRoot();
1104709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
1105709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return ret;
1106709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1107709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1108709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeInit() {
1109709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mInit) {
1110709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mInit();
1111709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1112709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1113709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1114709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeFreeChildren() {
1115709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mFreeChildren) {
1116709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mFreeChildren();
1117709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1118709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1119709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1120709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeFunction(uint32_t slot, const void *params,
1121709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                      size_t paramLength) {
1122709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("invoke %p %p %i %p %i", dc, script, slot, params, paramLength);
1123709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1124709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
1125709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    reinterpret_cast<void (*)(const void *, uint32_t)>(
1126110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
1127709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mExecutable->getExportFuncAddrs()[slot])(params, paramLength);
1128110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
1129110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        mInvokeFunctions[slot])(params, paramLength);
1130110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
1131709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
1132709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1133709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1134709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalVar(uint32_t slot, const void *data, size_t dataLength) {
1135709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(!script->mFieldIsObject[slot]);
1136709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("setGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength);
1137709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1138709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //if (mIntrinsicID) {
1139709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mIntrinsicFuncs.setVar(dc, script, drv->mIntrinsicData, slot, data, dataLength);
1140709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //return;
1141709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //}
1142709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1143110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
1144709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
1145709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                          mExecutable->getExportVarAddrs()[slot]);
1146110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
1147110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
1148110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
1149709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
1150709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
1151709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
1152709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1153709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1154709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, data, dataLength);
1155709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1156709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
11579c64239ebbfa4170190ede812e69150035e008e0Tim Murrayvoid RsdCpuScriptImpl::getGlobalVar(uint32_t slot, void *data, size_t dataLength) {
11589c64239ebbfa4170190ede812e69150035e008e0Tim Murray    //rsAssert(!script->mFieldIsObject[slot]);
11599c64239ebbfa4170190ede812e69150035e008e0Tim Murray    //ALOGE("getGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength);
11609c64239ebbfa4170190ede812e69150035e008e0Tim Murray
11619c64239ebbfa4170190ede812e69150035e008e0Tim Murray#ifndef RS_COMPATIBILITY_LIB
11629c64239ebbfa4170190ede812e69150035e008e0Tim Murray    int32_t *srcPtr = reinterpret_cast<int32_t *>(
11639c64239ebbfa4170190ede812e69150035e008e0Tim Murray                          mExecutable->getExportVarAddrs()[slot]);
11649c64239ebbfa4170190ede812e69150035e008e0Tim Murray#else
11659c64239ebbfa4170190ede812e69150035e008e0Tim Murray    int32_t *srcPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
11669c64239ebbfa4170190ede812e69150035e008e0Tim Murray#endif
11679c64239ebbfa4170190ede812e69150035e008e0Tim Murray    if (!srcPtr) {
11689c64239ebbfa4170190ede812e69150035e008e0Tim Murray        //ALOGV("Calling setVar on slot = %i which is null", slot);
11699c64239ebbfa4170190ede812e69150035e008e0Tim Murray        return;
11709c64239ebbfa4170190ede812e69150035e008e0Tim Murray    }
11719c64239ebbfa4170190ede812e69150035e008e0Tim Murray    memcpy(data, srcPtr, dataLength);
11729c64239ebbfa4170190ede812e69150035e008e0Tim Murray}
11739c64239ebbfa4170190ede812e69150035e008e0Tim Murray
11749c64239ebbfa4170190ede812e69150035e008e0Tim Murray
1175709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalVarWithElemDims(uint32_t slot, const void *data, size_t dataLength,
1176709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                                const Element *elem,
1177ac8d146a41f18afad5314ac8af440d6aedbe20bfStephen Hines                                                const uint32_t *dims, size_t dimLength) {
1178709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1179110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
1180709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
1181709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mExecutable->getExportVarAddrs()[slot]);
1182110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
1183110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
1184110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
1185709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
1186709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
1187709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
1188709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1189709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1190709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // We want to look at dimension in terms of integer components,
1191709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // but dimLength is given in terms of bytes.
1192709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    dimLength /= sizeof(int);
1193709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1194709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // Only a single dimension is currently supported.
1195709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(dimLength == 1);
1196709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (dimLength == 1) {
1197709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        // First do the increment loop.
1198709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        size_t stride = elem->getSizeBytes();
1199709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const char *cVal = reinterpret_cast<const char *>(data);
1200ac8d146a41f18afad5314ac8af440d6aedbe20bfStephen Hines        for (uint32_t i = 0; i < dims[0]; i++) {
1201709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            elem->incRefs(cVal);
1202709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            cVal += stride;
1203709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
1204709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1205709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        // Decrement loop comes after (to prevent race conditions).
1206709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        char *oldVal = reinterpret_cast<char *>(destPtr);
1207ac8d146a41f18afad5314ac8af440d6aedbe20bfStephen Hines        for (uint32_t i = 0; i < dims[0]; i++) {
1208709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            elem->decRefs(oldVal);
1209709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            oldVal += stride;
1210709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
1211709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1212709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1213709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, data, dataLength);
1214709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1215709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1216709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalBind(uint32_t slot, Allocation *data) {
1217709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1218709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(!script->mFieldIsObject[slot]);
1219709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("setGlobalBind %p %p %i %p", dc, script, slot, data);
1220709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1221110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
1222709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
1223709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                          mExecutable->getExportVarAddrs()[slot]);
1224110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
1225110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
1226110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
1227709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
1228709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
1229709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
1230709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1231709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1232709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    void *ptr = NULL;
1233709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mBoundAllocs[slot] = data;
1234709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if(data) {
1235709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ptr = data->mHal.drvState.lod[0].mallocPtr;
1236709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1237709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, &ptr, sizeof(void *));
1238709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1239709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1240709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalObj(uint32_t slot, ObjectBase *data) {
1241709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1242709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(script->mFieldIsObject[slot]);
1243709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("setGlobalObj %p %p %i %p", dc, script, slot, data);
1244709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1245110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
1246709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(
1247709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                          mExecutable->getExportVarAddrs()[slot]);
1248110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
1249110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]);
1250110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
1251e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray
1252709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
1253709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
1254709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
1255709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1256709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1257f29edf80510d483b8663e9d8b859959e37361aeeJason Sams    rsrSetObject(mCtx->getContext(), (rs_object_base *)destPtr, data);
1258709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1259709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1260709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptImpl::~RsdCpuScriptImpl() {
1261110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
1262709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mExecutable) {
1263709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Vector<void *>::const_iterator var_addr_iter =
1264709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getExportVarAddrs().begin();
1265709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Vector<void *>::const_iterator var_addr_end =
1266709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getExportVarAddrs().end();
1267709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1268709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_iter =
1269709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getInfo().getObjectSlots().begin();
1270709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_end =
1271709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            mExecutable->getInfo().getObjectSlots().end();
1272709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1273709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        while ((var_addr_iter != var_addr_end) &&
1274709a0978ae141198018ca9769f8d96292a8928e6Jason Sams               (is_object_iter != is_object_end)) {
1275709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            // The field address can be NULL if the script-side has optimized
1276709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            // the corresponding global variable away.
1277f29edf80510d483b8663e9d8b859959e37361aeeJason Sams            rs_object_base *obj_addr =
1278f29edf80510d483b8663e9d8b859959e37361aeeJason Sams                reinterpret_cast<rs_object_base *>(*var_addr_iter);
1279709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            if (*is_object_iter) {
1280a36c50a6ab87f4c9049318d4c6c8ec7b0a1e6e12Jason Sams                if (*var_addr_iter != NULL && mCtx->getContext() != NULL) {
1281709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                    rsrClearObject(mCtx->getContext(), obj_addr);
1282709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                }
1283709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            }
1284709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            var_addr_iter++;
1285709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            is_object_iter++;
1286709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
1287709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1288709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1289709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerContext) {
1290709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mCompilerContext;
1291709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1292709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerDriver) {
1293709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mCompilerDriver;
1294709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1295709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mExecutable) {
1296709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mExecutable;
1297709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1298709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mBoundAllocs) {
1299709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete[] mBoundAllocs;
1300709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1301bee48d79ba974e3dfbb782f9cce5c8d554f488e7Tim Murray
130229809d1f95d4cd4cbc6b2f9384b3321759691e13Tim Murray    for (size_t i = 0; i < mExportedForEachFuncList.size(); i++) {
130329809d1f95d4cd4cbc6b2f9384b3321759691e13Tim Murray        delete[] mExportedForEachFuncList[i].first;
130429809d1f95d4cd4cbc6b2f9384b3321759691e13Tim Murray    }
1305110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
1306110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mFieldIsObject) {
1307110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        for (size_t i = 0; i < mExportedVariableCount; ++i) {
1308110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            if (mFieldIsObject[i]) {
1309110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                if (mFieldAddress[i] != NULL) {
1310f29edf80510d483b8663e9d8b859959e37361aeeJason Sams                    rs_object_base *obj_addr =
1311f29edf80510d483b8663e9d8b859959e37361aeeJason Sams                        reinterpret_cast<rs_object_base *>(mFieldAddress[i]);
1312110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                    rsrClearObject(mCtx->getContext(), obj_addr);
1313110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams                }
1314110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams            }
1315110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        }
1316110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
1317110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
1318110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mInvokeFunctions) delete[] mInvokeFunctions;
1319110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mForEachFunctions) delete[] mForEachFunctions;
1320110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mFieldAddress) delete[] mFieldAddress;
1321110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mFieldIsObject) delete[] mFieldIsObject;
1322110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mForEachSignatures) delete[] mForEachSignatures;
1323110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mBoundAllocs) delete[] mBoundAllocs;
1324110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
1325110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        dlclose(mScriptSO);
1326110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
1327110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
1328709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1329709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1330709a0978ae141198018ca9769f8d96292a8928e6Jason SamsAllocation * RsdCpuScriptImpl::getAllocationForPointer(const void *ptr) const {
1331709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!ptr) {
1332709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return NULL;
1333709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1334709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1335709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    for (uint32_t ct=0; ct < mScript->mHal.info.exportedVariableCount; ct++) {
1336709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Allocation *a = mBoundAllocs[ct];
1337709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (!a) continue;
1338709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (a->mHal.drvState.lod[0].mallocPtr == ptr) {
1339709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            return a;
1340709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
1341709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
1342709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    ALOGE("rsGetAllocation, failed to find %p", ptr);
1343709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return NULL;
1344709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1345709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
134617e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Samsvoid RsdCpuScriptImpl::preLaunch(uint32_t slot, const Allocation * ain,
134717e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams                       Allocation * aout, const void * usr,
134817e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams                       uint32_t usrLen, const RsScriptCall *sc)
134917e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams{
135017e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams}
135117e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams
135217e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Samsvoid RsdCpuScriptImpl::postLaunch(uint32_t slot, const Allocation * ain,
135317e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams                        Allocation * aout, const void * usr,
135417e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams                        uint32_t usrLen, const RsScriptCall *sc)
135517e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams{
135617e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams}
135717e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams
1358709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
1359709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1360709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
1361