rsCpuScript.cpp revision 2abfcc6d129fe3defddef4540aa95cc445c03a7a
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"
192abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni#include "rsCpuExecutable.h"
20709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
21110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifdef RS_COMPATIBILITY_LIB
22110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <stdio.h>
23ee48c0bbf290a73e2cd4710b70d62fc203dac0dcStephen Hines    #include <sys/stat.h>
24c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines    #include <unistd.h>
25110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#else
26110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/BCCContext.h>
2782e0a6779cb1006921153081fb33374197e7c9deStephen Hines    #include <bcc/Config/Config.h>
28110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSCompilerDriver.h>
29b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <bcinfo/MetadataExtractor.h>
30ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    #include <cutils/properties.h>
31b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
32b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <sys/types.h>
33b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <sys/wait.h>
34b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <unistd.h>
35005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines
36005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines    #include <string>
37005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines    #include <vector>
38110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
39709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
40dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <set>
41dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <string>
42dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <dlfcn.h>
43dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <stdlib.h>
44dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <string.h>
45dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <iostream>
46dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
47dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#ifdef __LP64__
48dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#define SYSLIBPATH "/system/lib64"
49dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#else
50dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#define SYSLIBPATH "/system/lib"
51dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#endif
52dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
53ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hinesnamespace {
54dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#ifndef RS_COMPATIBILITY_LIB
55dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
56ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hinesstatic bool is_force_recompile() {
57ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#ifdef RS_SERVER
58ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  return false;
59ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#else
60ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  char buf[PROPERTY_VALUE_MAX];
61ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
62ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  // Re-compile if floating point precision has been overridden.
63ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  property_get("debug.rs.precision", buf, "");
64ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  if (buf[0] != '\0') {
65ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return true;
66ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  }
67ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
68ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  // Re-compile if debug.rs.forcerecompile is set.
69ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  property_get("debug.rs.forcerecompile", buf, "0");
70ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  if ((::strcmp(buf, "1") == 0) || (::strcmp(buf, "true") == 0)) {
71ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return true;
72ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  } else {
73ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return false;
74ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  }
75ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#endif  // RS_SERVER
76ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines}
77b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
786847e73314e13aa02231268cca245a81eb0539caChris Wailesstatic void setCompileArguments(std::vector<const char*>* args,
796847e73314e13aa02231268cca245a81eb0539caChris Wailes                                const std::string& bcFileName,
806847e73314e13aa02231268cca245a81eb0539caChris Wailes                                const char* cacheDir, const char* resName,
816847e73314e13aa02231268cca245a81eb0539caChris Wailes                                const char* core_lib, bool useRSDebugContext,
826847e73314e13aa02231268cca245a81eb0539caChris Wailes                                const char* bccPluginName) {
8340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    rsAssert(cacheDir && resName && core_lib);
84da0f069871343119251d6b0586be356dc2146a62Yang Ni    args->push_back(android::renderscript::RsdCpuScriptImpl::BCC_EXE_PATH);
85687cfe85c3cffb244a7e5daeb1231f441a1ed54dTim Murray    args->push_back("-unroll-runtime");
86687cfe85c3cffb244a7e5daeb1231f441a1ed54dTim Murray    args->push_back("-scalarize-load-store");
8740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-o");
8840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(resName);
8940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-output_path");
9040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(cacheDir);
9140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-bclib");
9240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(core_lib);
9340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-mtriple");
9440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(DEFAULT_TARGET_TRIPLE_STRING);
9540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
96358ffb84f56929cd2d61f6429a790a1606eaf865Tim Murray    // Enable workaround for A53 codegen by default.
97358ffb84f56929cd2d61f6429a790a1606eaf865Tim Murray#if defined(__aarch64__) && !defined(DISABLE_A53_WORKAROUND)
98358ffb84f56929cd2d61f6429a790a1606eaf865Tim Murray    args->push_back("-aarch64-fix-cortex-a53-835769");
99358ffb84f56929cd2d61f6429a790a1606eaf865Tim Murray#endif
100358ffb84f56929cd2d61f6429a790a1606eaf865Tim Murray
10140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    // Execute the bcc compiler.
10240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    if (useRSDebugContext) {
10340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        args->push_back("-rs-debug-ctx");
10440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    } else {
10540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        // Only load additional libraries for compiles that don't use
10640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        // the debug context.
10740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        if (bccPluginName && strlen(bccPluginName) > 0) {
10840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            args->push_back("-load");
10940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            args->push_back(bccPluginName);
11040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        }
11140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    }
11240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
11345e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines    args->push_back("-fPIC");
11445e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines    args->push_back("-embedRSInfo");
115dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
1166847e73314e13aa02231268cca245a81eb0539caChris Wailes    args->push_back(bcFileName.c_str());
11744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    args->push_back(nullptr);
11840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet}
11940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
1206847e73314e13aa02231268cca245a81eb0539caChris Wailesstatic bool compileBitcode(const std::string &bcFileName,
121b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           const char *bitcode,
122b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           size_t bitcodeSize,
1236847e73314e13aa02231268cca245a81eb0539caChris Wailes                           const char **compileArguments,
1246847e73314e13aa02231268cca245a81eb0539caChris Wailes                           const std::string &compileCommandLine) {
12540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    rsAssert(bitcode && bitcodeSize);
12640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
1276847e73314e13aa02231268cca245a81eb0539caChris Wailes    FILE *bcfile = fopen(bcFileName.c_str(), "w");
128b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (!bcfile) {
1296847e73314e13aa02231268cca245a81eb0539caChris Wailes        ALOGE("Could not write to %s", bcFileName.c_str());
130b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
131b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
132b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    size_t nwritten = fwrite(bitcode, 1, bitcodeSize, bcfile);
133b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    fclose(bcfile);
134b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (nwritten != bitcodeSize) {
135b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not write %zu bytes to %s", bitcodeSize,
1366847e73314e13aa02231268cca245a81eb0539caChris Wailes              bcFileName.c_str());
137b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
138b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
139b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
140b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    pid_t pid = fork();
141005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines
142b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    switch (pid) {
143b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case -1: {  // Error occurred (we attempt no recovery)
144b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Couldn't fork for bcc compiler execution");
145b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
146b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
147b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    case 0: {  // Child process
14840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        ALOGV("Invoking BCC with: %s", compileCommandLine.c_str());
149da0f069871343119251d6b0586be356dc2146a62Yang Ni        execv(android::renderscript::RsdCpuScriptImpl::BCC_EXE_PATH,
150da0f069871343119251d6b0586be356dc2146a62Yang Ni              (char* const*)compileArguments);
151005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines
152005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines        ALOGE("execv() failed: %s", strerror(errno));
153b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        abort();
154b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
155b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
156b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    default: {  // Parent process (actual driver)
157b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        // Wait on child process to finish compiling the source.
158b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        int status = 0;
159b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        pid_t w = waitpid(pid, &status, 0);
160b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        if (w == -1) {
161b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            ALOGE("Could not wait for bcc compiler");
162b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            return false;
163b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        }
164b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
165b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
166b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines            return true;
167b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        }
168b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
169b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("bcc compiler terminated unexpectedly");
170b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
171b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
172b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
173b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines}
174b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
1751c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ni#endif  // !defined(RS_COMPATIBILITY_LIB)
1761c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ni}  // namespace
1771c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ni
1781c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ninamespace android {
1791c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ninamespace renderscript {
1801c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ni
181709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptImpl::RsdCpuScriptImpl(RsdCpuReferenceImpl *ctx, const Script *s) {
182709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx = ctx;
183709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mScript = s;
184709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
18544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mScriptSO = nullptr;
186dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
187dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#ifndef RS_COMPATIBILITY_LIB
18844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mCompilerDriver = nullptr;
189110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
190110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
191e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray
19244bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mRoot = nullptr;
19344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mRootExpand = nullptr;
19444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mInit = nullptr;
19544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mFreeChildren = nullptr;
196d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    mScriptExec = nullptr;
197709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
19844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mBoundAllocs = nullptr;
19944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mIntrinsicData = nullptr;
200709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mIsThreadable = true;
201709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
202709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
203dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainarbool RsdCpuScriptImpl::storeRSInfoFromSO() {
204dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    mRoot = (RootFunc_t) dlsym(mScriptSO, "root");
205dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (mRoot) {
206dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar        //ALOGE("Found root(): %p", mRoot);
207dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
208dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    mRootExpand = (RootFunc_t) dlsym(mScriptSO, "root.expand");
209dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (mRootExpand) {
210dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar        //ALOGE("Found root.expand(): %p", mRootExpand);
211dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
212dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    mInit = (InvokeFunc_t) dlsym(mScriptSO, "init");
213dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (mInit) {
214dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar        //ALOGE("Found init(): %p", mInit);
215dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
216dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    mFreeChildren = (InvokeFunc_t) dlsym(mScriptSO, ".rs.dtor");
217dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (mFreeChildren) {
218dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar        //ALOGE("Found .rs.dtor(): %p", mFreeChildren);
219dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
220dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
221d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    mScriptExec = ScriptExecutable::createFromSharedObject(
222d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni            mCtx->getContext(), mScriptSO);
223d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni
224d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    if (mScriptExec == nullptr) {
225d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni        return false;
226d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    }
227d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni
228d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    size_t varCount = mScriptExec->getExportedVariableCount();
229d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    if (varCount > 0) {
230d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni        mBoundAllocs = new Allocation *[varCount];
231d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni        memset(mBoundAllocs, 0, varCount * sizeof(*mBoundAllocs));
232dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
233dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
23468173de001c5d41c74828a426651e07cfd9e8710Pirama Arumuga Nainar    mIsThreadable = mScriptExec->getThreadable();
23568173de001c5d41c74828a426651e07cfd9e8710Pirama Arumuga Nainar    //ALOGE("Script isThreadable? %d", mIsThreadable);
23668173de001c5d41c74828a426651e07cfd9e8710Pirama Arumuga Nainar
237d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    return true;
238d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni}
239d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni
240709a0978ae141198018ca9769f8d96292a8928e6Jason Samsbool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir,
241709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                            uint8_t const *bitcode, size_t bitcodeSize,
242005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines                            uint32_t flags, char const *bccPluginName) {
243e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni    //ALOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir,
244e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni    // bitcode, bitcodeSize, flags, lookupFunc);
245709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("rsdScriptInit %p %p", rsc, script);
246709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
247709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->lockMutex();
248110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
249005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines    bool useRSDebugContext = false;
250709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
25144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mCompilerDriver = nullptr;
252709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
253709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver = new bcc::RSCompilerDriver();
25444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (mCompilerDriver == nullptr) {
255709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGE("bcc: FAILS to create compiler driver (out of memory)");
256709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->unlockMutex();
257709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return false;
258709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
259709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
260b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    // Run any compiler setup functions we have been provided with.
261b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    RSSetupCompilerCallback setupCompilerCallback =
262b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines            mCtx->getSetupCompilerCallback();
26344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (setupCompilerCallback != nullptr) {
264b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines        setupCompilerCallback(mCompilerDriver);
265b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    }
266b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines
26740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcinfo::MetadataExtractor bitcodeMetadata((const char *) bitcode, bitcodeSize);
26840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    if (!bitcodeMetadata.extract()) {
269b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not extract metadata from bitcode");
270f94e8db4232979b2fc93e8a77c42bfa57d3da56aStephen Hines        mCtx->unlockMutex();
271b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
272b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
273b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
27440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    const char* core_lib = findCoreLib(bitcodeMetadata, (const char*)bitcode, bitcodeSize);
275cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines
276cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines    if (mCtx->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
277f47e8b4b86bf194e65398032f3f5f47a6da89f3fStephen Hines        mCompilerDriver->setDebugContext(true);
278005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines        useRSDebugContext = true;
279ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    }
280ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
2816847e73314e13aa02231268cca245a81eb0539caChris Wailes    std::string bcFileName(cacheDir);
28240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcFileName.append("/");
28340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcFileName.append(resName);
28440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcFileName.append(".bc");
28540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
28640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    std::vector<const char*> compileArguments;
28740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    setCompileArguments(&compileArguments, bcFileName, cacheDir, resName, core_lib,
28840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet                        useRSDebugContext, bccPluginName);
28944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    // The last argument of compileArguments ia a nullptr, so remove 1 from the size.
2902abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    std::unique_ptr<const char> joined(
2912abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni        rsuJoinStrings(compileArguments.size() - 1, compileArguments.data()));
2922abfcc6d129fe3defddef4540aa95cc445c03a7aYang Ni    std::string compileCommandLine (joined.get());
29340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
294bf96a520e162b503b293f65ca9ca9be66d4a0036Tim Murray    if (!is_force_recompile() && !useRSDebugContext) {
2951c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ni        mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
296cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines    }
297709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
29840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    // If we can't, it's either not there or out of date.  We compile the bit code and try loading
29940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    // again.
30045e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines    if (mScriptSO == nullptr) {
30145e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines        if (!compileBitcode(bcFileName, (const char*)bitcode, bitcodeSize,
30245e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines                            compileArguments.data(), compileCommandLine))
30345e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines        {
30440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            ALOGE("bcc: FAILS to compile '%s'", resName);
30540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            mCtx->unlockMutex();
30640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            return false;
30740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        }
30845e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines
3091c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ni        if (!SharedLibraryUtils::createSharedLibrary(cacheDir, resName)) {
31045e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines            ALOGE("Linker: Failed to link object file '%s'", resName);
31145e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines            mCtx->unlockMutex();
31245e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines            return false;
31345e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines        }
31445e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines
3151c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ni        mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
31645e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines        if (mScriptSO == nullptr) {
31745e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines            ALOGE("Unable to load '%s'", resName);
31840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            mCtx->unlockMutex();
31940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            return false;
32040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        }
321709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
322709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
323c31585b8ca865bf2b35abc79c8a8ee42de27bee8Yang Ni    mBitcodeFilePath.setTo(bcFileName.c_str());
324da0f069871343119251d6b0586be356dc2146a62Yang Ni
32545e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines    // Read RS symbol information from the .so.
32645e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines    if ( !mScriptSO) {
32745e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines        goto error;
32829809d1f95d4cd4cbc6b2f9384b3321759691e13Tim Murray    }
329110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
33045e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines    if ( !storeRSInfoFromSO()) {
33145e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines      goto error;
332dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
333dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#else  // RS_COMPATIBILITY_LIB is defined
334f3213d7fd648da98bb3b03204eaf90f03c31926bMiao Wang    const char *nativeLibDir = mCtx->getContext()->getNativeLibDir();
335f3213d7fd648da98bb3b03204eaf90f03c31926bMiao Wang    mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName, nativeLibDir);
336110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
337dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (!mScriptSO) {
338dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar        goto error;
339dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
340110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
341dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (!storeRSInfoFromSO()) {
342c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        goto error;
343110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
344110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
345709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->unlockMutex();
346709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return true;
347110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
348110f181b7966212a36ef18016f9b81c7322d0a2fJason Samserror:
349110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
350110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCtx->unlockMutex();
351110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
352110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        dlclose(mScriptSO);
353eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni        mScriptSO = nullptr;
354110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
355110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    return false;
356709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
357709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
3589ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#ifndef RS_COMPATIBILITY_LIB
3599ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
3609ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouilletconst char* RsdCpuScriptImpl::findCoreLib(const bcinfo::MetadataExtractor& ME, const char* bitcode,
3619ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet                                          size_t bitcodeSize) {
3629ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    const char* defaultLib = SYSLIBPATH"/libclcore.bc";
3639ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
3649ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // If we're debugging, use the debug library.
3659ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    if (mCtx->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
3669ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return SYSLIBPATH"/libclcore_debug.bc";
3679ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    }
3689ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
3699ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // If a callback has been registered to specify a library, use that.
3709ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    RSSelectRTCallback selectRTCallback = mCtx->getSelectRTCallback();
37144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (selectRTCallback != nullptr) {
3729ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return selectRTCallback((const char*)bitcode, bitcodeSize);
3739ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    }
3749ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
3759ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // Check for a platform specific library
3769ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#if defined(ARCH_ARM_HAVE_NEON) && !defined(DISABLE_CLCORE_NEON)
3779ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    enum bcinfo::RSFloatPrecision prec = ME.getRSFloatPrecision();
378f4d3836c83097f57b62c235910fbf490c56ddf56Jean-Luc Brouillet    if (prec == bcinfo::RS_FP_Relaxed) {
3799ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // NEON-capable ARMv7a devices can use an accelerated math library
3809ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // for all reduced precision scripts.
3819ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // ARMv8 does not use NEON, as ASIMD can be used with all precision
3829ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // levels.
3839ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return SYSLIBPATH"/libclcore_neon.bc";
3849ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    } else {
3859ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return defaultLib;
3869ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    }
3879ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#elif defined(__i386__) || defined(__x86_64__)
3889ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // x86 devices will use an optimized library.
3899ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    return SYSLIBPATH"/libclcore_x86.bc";
3909ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#else
3919ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    return defaultLib;
3929ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#endif
3939ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet}
3949ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
3959ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#endif
3969ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
397709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::populateScript(Script *script) {
398110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // Copy info over to runtime
399d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    script->mHal.info.exportedFunctionCount = mScriptExec->getExportedFunctionCount();
400d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    script->mHal.info.exportedVariableCount = mScriptExec->getExportedVariableCount();
401577194ac9c2bf10f31e564de91371764b265929aPirama Arumuga Nainar    script->mHal.info.exportedPragmaCount = mScriptExec->getPragmaCount();;
402e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni    script->mHal.info.exportedPragmaKeyList = mScriptExec->getPragmaKeys();
403e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni    script->mHal.info.exportedPragmaValueList = mScriptExec->getPragmaValues();
404110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
405110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // Bug, need to stash in metadata
406110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mRootExpand) {
407110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        script->mHal.info.root = mRootExpand;
408110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    } else {
409110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        script->mHal.info.root = mRoot;
410110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
411709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
412709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
413709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
414709a0978ae141198018ca9769f8d96292a8928e6Jason Samstypedef void (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
415709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
416bf2111d3b3de310932099514f06924e48fa1d7b2Jason Samsbool RsdCpuScriptImpl::forEachMtlsSetup(const Allocation ** ains,
417f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                        uint32_t inLen,
418f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                        Allocation * aout,
419709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        const void * usr, uint32_t usrLen,
420709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        const RsScriptCall *sc,
421709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        MTLaunchStruct *mtls) {
422709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
423709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memset(mtls, 0, sizeof(MTLaunchStruct));
424709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
425f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes    for (int index = inLen; --index >= 0;) {
426f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes        const Allocation* ain = ains[index];
4274b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
428f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes        // possible for this to occur if IO_OUTPUT/IO_INPUT with no bound surface
42944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        if (ain != nullptr &&
43044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes            (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr == nullptr) {
43144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes
4324b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
433f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                         "rsForEach called with null in allocations");
434bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams            return false;
4354b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
4364b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
4374b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
43844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (aout &&
43944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        (const uint8_t *)aout->mHal.drvState.lod[0].mallocPtr == nullptr) {
44044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes
441f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
442f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                     "rsForEach called with null out allocations");
443bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        return false;
4444b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
4454b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
446f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes    if (inLen > 0) {
4474b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Allocation *ain0   = ains[0];
4484b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Type       *inType = ain0->getType();
4494b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
450c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.x = inType->getDimX();
451c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.y = inType->getDimY();
452c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.z = inType->getDimZ();
4534b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
4544b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        for (int Index = inLen; --Index >= 1;) {
4554b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            if (!ain0->hasSameDims(ains[Index])) {
4564b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
457e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni                  "Failed to launch kernel; dimensions of input and output"
458e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni                  "allocations do not match.");
4594b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
460bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams                return false;
4614b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            }
4624b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
4634b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
46444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    } else if (aout != nullptr) {
4654b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Type *outType = aout->getType();
4664b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
467c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.x = outType->getDimX();
468c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.y = outType->getDimY();
469c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.z = outType->getDimZ();
4704b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
4714b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
472f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
473f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                     "rsForEach called with null allocations");
474bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        return false;
4754b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
4764b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
47744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (inLen > 0 && aout != nullptr) {
4784b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        if (!ains[0]->hasSameDims(aout)) {
4794b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
4804b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes              "Failed to launch kernel; dimensions of input and output allocations do not match.");
4814b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
482bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams            return false;
4834b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
4844b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
4854b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
4864b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (!sc || (sc->xEnd == 0)) {
487bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.x = mtls->fep.dim.x;
4884b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
489bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.x = rsMin(mtls->fep.dim.x, sc->xStart);
490bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.x = rsMin(mtls->fep.dim.x, sc->xEnd);
491bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        if (mtls->start.x >= mtls->end.x) return false;
4924b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
4934b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
4944b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (!sc || (sc->yEnd == 0)) {
495bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.y = mtls->fep.dim.y;
4964b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
497bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.y = rsMin(mtls->fep.dim.y, sc->yStart);
498bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.y = rsMin(mtls->fep.dim.y, sc->yEnd);
499bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        if (mtls->start.y >= mtls->end.y) return false;
5004b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
5014b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
5024b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (!sc || (sc->zEnd == 0)) {
503bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.z = mtls->fep.dim.z;
5044b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
505bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.z = rsMin(mtls->fep.dim.z, sc->zStart);
506bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.z = rsMin(mtls->fep.dim.z, sc->zEnd);
507bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        if (mtls->start.z >= mtls->end.z) return false;
5084b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
5094b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
510bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    if (!sc || (sc->arrayEnd == 0)) {
511bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[0] = mtls->fep.dim.array[0];
512bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    } else {
513bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.array[0] = rsMin(mtls->fep.dim.array[0], sc->arrayStart);
514bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[0] = rsMin(mtls->fep.dim.array[0], sc->arrayEnd);
515bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        if (mtls->start.array[0] >= mtls->end.array[0]) return false;
516bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    }
5174b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
518bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    if (!sc || (sc->array2End == 0)) {
519bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[1] = mtls->fep.dim.array[1];
520bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    } else {
521bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.array[1] = rsMin(mtls->fep.dim.array[1], sc->array2Start);
522bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[1] = rsMin(mtls->fep.dim.array[1], sc->array2End);
523bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        if (mtls->start.array[1] >= mtls->end.array[1]) return false;
524bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    }
525bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams
526bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    if (!sc || (sc->array3End == 0)) {
527bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[2] = mtls->fep.dim.array[2];
528bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    } else {
529bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.array[2] = rsMin(mtls->fep.dim.array[2], sc->array3Start);
530bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[2] = rsMin(mtls->fep.dim.array[2], sc->array3End);
531bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        if (mtls->start.array[2] >= mtls->end.array[2]) return false;
532bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    }
533bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams
534bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    if (!sc || (sc->array4End == 0)) {
535bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[3] = mtls->fep.dim.array[3];
536bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    } else {
537bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.array[3] = rsMin(mtls->fep.dim.array[3], sc->array4Start);
538bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[3] = rsMin(mtls->fep.dim.array[3], sc->array4End);
539bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        if (mtls->start.array[3] >= mtls->end.array[3]) return false;
540bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    }
541bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams
542bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams
543bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    // The X & Y walkers always want 0-1 min even if dim is not present
544bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    mtls->end.x    = rsMax((uint32_t)1, mtls->end.x);
545bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    mtls->end.y    = rsMax((uint32_t)1, mtls->end.y);
5464b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
5474b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->rsc        = mCtx;
548c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams    if (ains) {
549c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        memcpy(mtls->ains, ains, inLen * sizeof(ains[0]));
550c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams    }
551c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams    mtls->aout[0]    = aout;
5524b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->fep.usr    = usr;
5534b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->fep.usrLen = usrLen;
5544b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->mSliceSize = 1;
5554b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->mSliceNum  = 0;
5564b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
5574b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->isThreadable  = mIsThreadable;
5584b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
559f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes    if (inLen > 0) {
560f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes        mtls->fep.inLen = inLen;
5614b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        for (int index = inLen; --index >= 0;) {
562c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams            mtls->fep.inPtr[index] = (const uint8_t*)ains[index]->mHal.drvState.lod[0].mallocPtr;
563c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams            mtls->fep.inStride[index] = ains[index]->getType()->getElementSizeBytes();
5644b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
5654b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
5664b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
56744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (aout != nullptr) {
568c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.outPtr[0] = (uint8_t *)aout->mHal.drvState.lod[0].mallocPtr;
569c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.outStride[0] = aout->getType()->getElementSizeBytes();
5704b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
571bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams
572bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    // All validation passed, ok to launch threads
573bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    return true;
5744b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes}
5754b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
576709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
577709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeForEach(uint32_t slot,
578f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                     const Allocation ** ains,
579f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                     uint32_t inLen,
580709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     Allocation * aout,
581709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const void * usr,
582709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     uint32_t usrLen,
583709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const RsScriptCall *sc) {
584709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
585709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    MTLaunchStruct mtls;
5864b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
587bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    if (forEachMtlsSetup(ains, inLen, aout, usr, usrLen, sc, &mtls)) {
588bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        forEachKernelSetup(slot, &mtls);
5894b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
590bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
591bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mCtx->launchThreads(ains, inLen, aout, sc, &mtls);
592bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mCtx->setTLS(oldTLS);
593bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    }
5944b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes}
5954b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
596709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::forEachKernelSetup(uint32_t slot, MTLaunchStruct *mtls) {
597709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->script = this;
598709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.slot = slot;
599d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    mtls->kernel = mScriptExec->getForEachFunction(slot);
60044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    rsAssert(mtls->kernel != nullptr);
601d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    mtls->sig = mScriptExec->getForEachSignature(slot);
602709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
603709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
604709a0978ae141198018ca9769f8d96292a8928e6Jason Samsint RsdCpuScriptImpl::invokeRoot() {
605709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
606709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int ret = mRoot();
607709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
608709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return ret;
609709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
610709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
611709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeInit() {
612709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mInit) {
613709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mInit();
614709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
615709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
616709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
617709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeFreeChildren() {
618709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mFreeChildren) {
619709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mFreeChildren();
620709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
621709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
622709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
623709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeFunction(uint32_t slot, const void *params,
624709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                      size_t paramLength) {
625dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    //ALOGE("invoke %i %p %zu", slot, params, paramLength);
626eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    void * ap = nullptr;
627eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen
628eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen#if defined(__x86_64__)
629eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    // The invoked function could have input parameter of vector type for example float4 which
630eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    // requires void* params to be 16 bytes aligned when using SSE instructions for x86_64 platform.
631eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    // So try to align void* params before passing them into RS exported function.
632eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen
633eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    if ((uint8_t)(uint64_t)params & 0x0F) {
634eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen        if ((ap = (void*)memalign(16, paramLength)) != nullptr) {
635eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen            memcpy(ap, params, paramLength);
636eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen        } else {
637e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni            ALOGE("x86_64: invokeFunction memalign error, still use params which"
638e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni                  " is not 16 bytes aligned.");
639eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen        }
640eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    }
641eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen#endif
642709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
643709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
644dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    reinterpret_cast<void (*)(const void *, uint32_t)>(
645d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni        mScriptExec->getInvokeFunction(slot))(ap? (const void *) ap: params, paramLength);
646eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen
647709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
648709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
649709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
650709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalVar(uint32_t slot, const void *data, size_t dataLength) {
651709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(!script->mFieldIsObject[slot]);
652dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    //ALOGE("setGlobalVar %i %p %zu", slot, data, dataLength);
653709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
654709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //if (mIntrinsicID) {
655709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mIntrinsicFuncs.setVar(dc, script, drv->mIntrinsicData, slot, data, dataLength);
656709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //return;
657709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //}
658709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
659d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    int32_t *destPtr = reinterpret_cast<int32_t *>(mScriptExec->getFieldAddress(slot));
660709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
661709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
662709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
663709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
664709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
665709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, data, dataLength);
666709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
667709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
6689c64239ebbfa4170190ede812e69150035e008e0Tim Murrayvoid RsdCpuScriptImpl::getGlobalVar(uint32_t slot, void *data, size_t dataLength) {
6699c64239ebbfa4170190ede812e69150035e008e0Tim Murray    //rsAssert(!script->mFieldIsObject[slot]);
670dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    //ALOGE("getGlobalVar %i %p %zu", slot, data, dataLength);
6719c64239ebbfa4170190ede812e69150035e008e0Tim Murray
672d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    int32_t *srcPtr = reinterpret_cast<int32_t *>(mScriptExec->getFieldAddress(slot));
6739c64239ebbfa4170190ede812e69150035e008e0Tim Murray    if (!srcPtr) {
6749c64239ebbfa4170190ede812e69150035e008e0Tim Murray        //ALOGV("Calling setVar on slot = %i which is null", slot);
6759c64239ebbfa4170190ede812e69150035e008e0Tim Murray        return;
6769c64239ebbfa4170190ede812e69150035e008e0Tim Murray    }
6779c64239ebbfa4170190ede812e69150035e008e0Tim Murray    memcpy(data, srcPtr, dataLength);
6789c64239ebbfa4170190ede812e69150035e008e0Tim Murray}
6799c64239ebbfa4170190ede812e69150035e008e0Tim Murray
6809c64239ebbfa4170190ede812e69150035e008e0Tim Murray
681709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalVarWithElemDims(uint32_t slot, const void *data, size_t dataLength,
682709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                                const Element *elem,
683ac8d146a41f18afad5314ac8af440d6aedbe20bfStephen Hines                                                const uint32_t *dims, size_t dimLength) {
684d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    int32_t *destPtr = reinterpret_cast<int32_t *>(mScriptExec->getFieldAddress(slot));
685709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
686709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
687709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
688709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
689709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
690709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // We want to look at dimension in terms of integer components,
691709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // but dimLength is given in terms of bytes.
692709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    dimLength /= sizeof(int);
693709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
694709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // Only a single dimension is currently supported.
695709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(dimLength == 1);
696709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (dimLength == 1) {
697709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        // First do the increment loop.
698709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        size_t stride = elem->getSizeBytes();
699709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const char *cVal = reinterpret_cast<const char *>(data);
700ac8d146a41f18afad5314ac8af440d6aedbe20bfStephen Hines        for (uint32_t i = 0; i < dims[0]; i++) {
701709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            elem->incRefs(cVal);
702709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            cVal += stride;
703709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
704709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
705709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        // Decrement loop comes after (to prevent race conditions).
706709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        char *oldVal = reinterpret_cast<char *>(destPtr);
707ac8d146a41f18afad5314ac8af440d6aedbe20bfStephen Hines        for (uint32_t i = 0; i < dims[0]; i++) {
708709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            elem->decRefs(oldVal);
709709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            oldVal += stride;
710709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
711709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
712709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
713709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, data, dataLength);
714709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
715709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
716709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalBind(uint32_t slot, Allocation *data) {
717709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
718709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(!script->mFieldIsObject[slot]);
719dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    //ALOGE("setGlobalBind %i %p", slot, data);
720709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
721d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    int32_t *destPtr = reinterpret_cast<int32_t *>(mScriptExec->getFieldAddress(slot));
722709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
723709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
724709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
725709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
726709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
72744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    void *ptr = nullptr;
728709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mBoundAllocs[slot] = data;
729dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (data) {
730709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ptr = data->mHal.drvState.lod[0].mallocPtr;
731709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
732709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, &ptr, sizeof(void *));
733709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
734709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
735709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalObj(uint32_t slot, ObjectBase *data) {
736709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
737709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(script->mFieldIsObject[slot]);
738dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    //ALOGE("setGlobalObj %i %p", slot, data);
739709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
740d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    int32_t *destPtr = reinterpret_cast<int32_t *>(mScriptExec->getFieldAddress(slot));
741709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
742709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
743709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
744709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
745709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
74605ef73f2d934f1083cc3b8aeb33fe21de9d6e88fJason Sams    rsrSetObject(mCtx->getContext(), (rs_object_base *)destPtr, data);
747709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
748709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
749709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptImpl::~RsdCpuScriptImpl() {
750110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
751709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerDriver) {
752709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mCompilerDriver;
753709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
75445e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines#endif
755dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
756d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    if (mScriptExec != nullptr) {
757d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni        delete mScriptExec;
758110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
759110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mBoundAllocs) delete[] mBoundAllocs;
760110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
761110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        dlclose(mScriptSO);
762110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
763709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
764709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
765709a0978ae141198018ca9769f8d96292a8928e6Jason SamsAllocation * RsdCpuScriptImpl::getAllocationForPointer(const void *ptr) const {
766709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!ptr) {
76744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
768709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
769709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
770709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    for (uint32_t ct=0; ct < mScript->mHal.info.exportedVariableCount; ct++) {
771709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Allocation *a = mBoundAllocs[ct];
772709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (!a) continue;
773709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (a->mHal.drvState.lod[0].mallocPtr == ptr) {
774709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            return a;
775709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
776709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
777709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    ALOGE("rsGetAllocation, failed to find %p", ptr);
77844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    return nullptr;
779709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
780709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
781f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailesvoid RsdCpuScriptImpl::preLaunch(uint32_t slot, const Allocation ** ains,
782f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                 uint32_t inLen, Allocation * aout,
783f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                 const void * usr, uint32_t usrLen,
784f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                 const RsScriptCall *sc) {}
78517e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams
786f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailesvoid RsdCpuScriptImpl::postLaunch(uint32_t slot, const Allocation ** ains,
787f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                  uint32_t inLen, Allocation * aout,
788f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                  const void * usr, uint32_t usrLen,
789f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                  const RsScriptCall *sc) {}
79017e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams
791709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
792709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
793709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
794