rsCpuScript.cpp revision 5aa018cc36e589b07674957714d27ae3d1fa1c4e
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
262fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    #include "rsCppUtils.h"
272fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar
28110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/BCCContext.h>
2982e0a6779cb1006921153081fb33374197e7c9deStephen Hines    #include <bcc/Config/Config.h>
30110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    #include <bcc/Renderscript/RSCompilerDriver.h>
31b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <bcinfo/MetadataExtractor.h>
32ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    #include <cutils/properties.h>
33b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
34aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    #include <zlib.h>
35aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    #include <sys/file.h>
36b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <sys/types.h>
37b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    #include <unistd.h>
38005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines
39005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines    #include <string>
40005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines    #include <vector>
41110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
42709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
43dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <set>
44dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <string>
45dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <dlfcn.h>
46dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <stdlib.h>
47dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <string.h>
48dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#include <iostream>
49cb17015fed6b11a5028f31cc804a3847e379945dYang Ni#include <sstream>
50dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
51dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#ifdef __LP64__
52dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#define SYSLIBPATH "/system/lib64"
53dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#else
54dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#define SYSLIBPATH "/system/lib"
55dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#endif
56dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
57ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hinesnamespace {
588409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines
598409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hinesstatic const bool kDebugGlobalVariables = false;
608409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines
61dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#ifndef RS_COMPATIBILITY_LIB
62dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
63ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hinesstatic bool is_force_recompile() {
64ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#ifdef RS_SERVER
65ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  return false;
66ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#else
67ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  char buf[PROPERTY_VALUE_MAX];
68ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
69ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  // Re-compile if floating point precision has been overridden.
70ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  property_get("debug.rs.precision", buf, "");
71ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  if (buf[0] != '\0') {
72ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return true;
73ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  }
74ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
75ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  // Re-compile if debug.rs.forcerecompile is set.
76ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  property_get("debug.rs.forcerecompile", buf, "0");
77ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  if ((::strcmp(buf, "1") == 0) || (::strcmp(buf, "true") == 0)) {
78ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return true;
79ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  } else {
80ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    return false;
81ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines  }
82ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines#endif  // RS_SERVER
83ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines}
84b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
856847e73314e13aa02231268cca245a81eb0539caChris Wailesstatic void setCompileArguments(std::vector<const char*>* args,
866847e73314e13aa02231268cca245a81eb0539caChris Wailes                                const std::string& bcFileName,
876847e73314e13aa02231268cca245a81eb0539caChris Wailes                                const char* cacheDir, const char* resName,
886847e73314e13aa02231268cca245a81eb0539caChris Wailes                                const char* core_lib, bool useRSDebugContext,
898409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines                                const char* bccPluginName, bool emitGlobalInfo,
908409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines                                bool emitGlobalInfoSkipConstant) {
9140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    rsAssert(cacheDir && resName && core_lib);
92da0f069871343119251d6b0586be356dc2146a62Yang Ni    args->push_back(android::renderscript::RsdCpuScriptImpl::BCC_EXE_PATH);
93687cfe85c3cffb244a7e5daeb1231f441a1ed54dTim Murray    args->push_back("-unroll-runtime");
94687cfe85c3cffb244a7e5daeb1231f441a1ed54dTim Murray    args->push_back("-scalarize-load-store");
958409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    if (emitGlobalInfo) {
968409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        args->push_back("-rs-global-info");
978409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        if (emitGlobalInfoSkipConstant) {
988409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines            args->push_back("-rs-global-info-skip-constant");
998409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        }
1008409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    }
10140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-o");
10240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(resName);
10340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-output_path");
10440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(cacheDir);
10540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-bclib");
10640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(core_lib);
10740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back("-mtriple");
10840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    args->push_back(DEFAULT_TARGET_TRIPLE_STRING);
10940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
110358ffb84f56929cd2d61f6429a790a1606eaf865Tim Murray    // Enable workaround for A53 codegen by default.
111358ffb84f56929cd2d61f6429a790a1606eaf865Tim Murray#if defined(__aarch64__) && !defined(DISABLE_A53_WORKAROUND)
112358ffb84f56929cd2d61f6429a790a1606eaf865Tim Murray    args->push_back("-aarch64-fix-cortex-a53-835769");
113358ffb84f56929cd2d61f6429a790a1606eaf865Tim Murray#endif
114358ffb84f56929cd2d61f6429a790a1606eaf865Tim Murray
11540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    // Execute the bcc compiler.
11640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    if (useRSDebugContext) {
11740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        args->push_back("-rs-debug-ctx");
11840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    } else {
11940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        // Only load additional libraries for compiles that don't use
12040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        // the debug context.
12140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        if (bccPluginName && strlen(bccPluginName) > 0) {
12240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            args->push_back("-load");
12340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            args->push_back(bccPluginName);
12440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        }
12540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    }
12640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
12745e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines    args->push_back("-fPIC");
12845e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines    args->push_back("-embedRSInfo");
129dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
1306847e73314e13aa02231268cca245a81eb0539caChris Wailes    args->push_back(bcFileName.c_str());
13144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    args->push_back(nullptr);
13240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet}
13340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
1346847e73314e13aa02231268cca245a81eb0539caChris Wailesstatic bool compileBitcode(const std::string &bcFileName,
135b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           const char *bitcode,
136b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines                           size_t bitcodeSize,
1372fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar                           std::vector<const char *> &compileArguments) {
13840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    rsAssert(bitcode && bitcodeSize);
13940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
1406847e73314e13aa02231268cca245a81eb0539caChris Wailes    FILE *bcfile = fopen(bcFileName.c_str(), "w");
141b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (!bcfile) {
1426847e73314e13aa02231268cca245a81eb0539caChris Wailes        ALOGE("Could not write to %s", bcFileName.c_str());
143b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
144b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
145b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    size_t nwritten = fwrite(bitcode, 1, bitcodeSize, bcfile);
146b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    fclose(bcfile);
147b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    if (nwritten != bitcodeSize) {
148b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not write %zu bytes to %s", bitcodeSize,
1496847e73314e13aa02231268cca245a81eb0539caChris Wailes              bcFileName.c_str());
150b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
151b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
152b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
1532fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar    return android::renderscript::rsuExecuteCommand(
1542fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar                   android::renderscript::RsdCpuScriptImpl::BCC_EXE_PATH,
1552fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar                   compileArguments.size()-1, compileArguments.data());
156b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines}
157b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
158aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainarbool isChecksumNeeded() {
159aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    char buf[PROPERTY_VALUE_MAX];
160aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    property_get("ro.debuggable", buf, "");
161aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    return (buf[0] == '1');
162aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar}
163aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
164f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Nibool addFileToChecksum(const char *fileName, uint32_t &checksum) {
165f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni    int FD = open(fileName, O_RDONLY);
166f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni    if (FD == -1) {
167f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni        ALOGE("Cannot open file \'%s\' to compute checksum", fileName);
168f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni        return false;
169f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni    }
170f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni
171f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni    char buf[256];
172f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni    while (true) {
173f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni        ssize_t nread = read(FD, buf, sizeof(buf));
174f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni        if (nread < 0) { // bail out on failed read
175f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni            ALOGE("Error while computing checksum for file \'%s\'", fileName);
176f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni            return false;
177f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni        }
178f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni
179f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni        checksum = adler32(checksum, (const unsigned char *) buf, nread);
180f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni        if (static_cast<size_t>(nread) < sizeof(buf)) // EOF
181f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni            break;
182f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni    }
183f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni
184f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni    if (TEMP_FAILURE_RETRY(close(FD)) != 0) {
185f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni        ALOGE("Cannot close file \'%s\' after computing checksum", fileName);
186f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni        return false;
187f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni    }
188f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni    return true;
189f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni}
190cb17015fed6b11a5028f31cc804a3847e379945dYang Ni
191cb17015fed6b11a5028f31cc804a3847e379945dYang Ni#endif  // !defined(RS_COMPATIBILITY_LIB)
192cb17015fed6b11a5028f31cc804a3847e379945dYang Ni}  // namespace
193cb17015fed6b11a5028f31cc804a3847e379945dYang Ni
194cb17015fed6b11a5028f31cc804a3847e379945dYang Ninamespace android {
195cb17015fed6b11a5028f31cc804a3847e379945dYang Ninamespace renderscript {
196cb17015fed6b11a5028f31cc804a3847e379945dYang Ni
197cb17015fed6b11a5028f31cc804a3847e379945dYang Ni#ifndef RS_COMPATIBILITY_LIB
198cb17015fed6b11a5028f31cc804a3847e379945dYang Ni
199cb17015fed6b11a5028f31cc804a3847e379945dYang Niuint32_t constructBuildChecksum(uint8_t const *bitcode, size_t bitcodeSize,
200cb17015fed6b11a5028f31cc804a3847e379945dYang Ni                                const char *commandLine,
201cb17015fed6b11a5028f31cc804a3847e379945dYang Ni                                const char** bccFiles, size_t numFiles) {
202cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    uint32_t checksum = adler32(0L, Z_NULL, 0);
203cb17015fed6b11a5028f31cc804a3847e379945dYang Ni
204cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    // include checksum of bitcode
205cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    if (bitcode != nullptr && bitcodeSize > 0) {
206cb17015fed6b11a5028f31cc804a3847e379945dYang Ni        checksum = adler32(checksum, bitcode, bitcodeSize);
207cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    }
208cb17015fed6b11a5028f31cc804a3847e379945dYang Ni
209cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    // include checksum of command line arguments
210cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    checksum = adler32(checksum, (const unsigned char *) commandLine,
211cb17015fed6b11a5028f31cc804a3847e379945dYang Ni                       strlen(commandLine));
212cb17015fed6b11a5028f31cc804a3847e379945dYang Ni
213cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    // include checksum of bccFiles
214cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    for (size_t i = 0; i < numFiles; i++) {
215cb17015fed6b11a5028f31cc804a3847e379945dYang Ni        const char* bccFile = bccFiles[i];
216cb17015fed6b11a5028f31cc804a3847e379945dYang Ni        if (bccFile[0] != 0 && !addFileToChecksum(bccFile, checksum)) {
217cb17015fed6b11a5028f31cc804a3847e379945dYang Ni            // return empty checksum instead of something partial/corrupt
218cb17015fed6b11a5028f31cc804a3847e379945dYang Ni            return 0;
219cb17015fed6b11a5028f31cc804a3847e379945dYang Ni        }
220cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    }
221cb17015fed6b11a5028f31cc804a3847e379945dYang Ni
222cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    return checksum;
223cb17015fed6b11a5028f31cc804a3847e379945dYang Ni}
224cb17015fed6b11a5028f31cc804a3847e379945dYang Ni
225f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni#endif  // !RS_COMPATIBILITY_LIB
226f02a2b0a2749d4a4f07edbc23eddff2e51d11b72Yang Ni
227709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptImpl::RsdCpuScriptImpl(RsdCpuReferenceImpl *ctx, const Script *s) {
228709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx = ctx;
229709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mScript = s;
230709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
23144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mScriptSO = nullptr;
232dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
233dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#ifndef RS_COMPATIBILITY_LIB
23444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mCompilerDriver = nullptr;
235110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
236110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
237e195a3f57ace3b66d313a6ee88c6e93d5c9d87f4Tim Murray
23844bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mRoot = nullptr;
23944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mRootExpand = nullptr;
24044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mInit = nullptr;
24144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mFreeChildren = nullptr;
242d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    mScriptExec = nullptr;
243709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
24444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mBoundAllocs = nullptr;
24544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mIntrinsicData = nullptr;
246709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mIsThreadable = true;
247aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
248cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    mBuildChecksum = 0;
249aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    mChecksumNeeded = false;
250709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
251709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
252dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainarbool RsdCpuScriptImpl::storeRSInfoFromSO() {
253aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    // The shared object may have an invalid build checksum.
254aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    // Validate and fail early.
255aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    mScriptExec = ScriptExecutable::createFromSharedObject(
256cb17015fed6b11a5028f31cc804a3847e379945dYang Ni            mCtx->getContext(), mScriptSO,
257cb17015fed6b11a5028f31cc804a3847e379945dYang Ni            mChecksumNeeded ? mBuildChecksum : 0);
258aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
259aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    if (mScriptExec == nullptr) {
260aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        return false;
261aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    }
262aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
263dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    mRoot = (RootFunc_t) dlsym(mScriptSO, "root");
264dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (mRoot) {
265dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar        //ALOGE("Found root(): %p", mRoot);
266dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
267dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    mRootExpand = (RootFunc_t) dlsym(mScriptSO, "root.expand");
268dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (mRootExpand) {
269dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar        //ALOGE("Found root.expand(): %p", mRootExpand);
270dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
271dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    mInit = (InvokeFunc_t) dlsym(mScriptSO, "init");
272dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (mInit) {
273dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar        //ALOGE("Found init(): %p", mInit);
274dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
275dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    mFreeChildren = (InvokeFunc_t) dlsym(mScriptSO, ".rs.dtor");
276dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (mFreeChildren) {
277dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar        //ALOGE("Found .rs.dtor(): %p", mFreeChildren);
278dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
279dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
280d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    size_t varCount = mScriptExec->getExportedVariableCount();
281d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    if (varCount > 0) {
282d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni        mBoundAllocs = new Allocation *[varCount];
283d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni        memset(mBoundAllocs, 0, varCount * sizeof(*mBoundAllocs));
284dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
285dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
28668173de001c5d41c74828a426651e07cfd9e8710Pirama Arumuga Nainar    mIsThreadable = mScriptExec->getThreadable();
28768173de001c5d41c74828a426651e07cfd9e8710Pirama Arumuga Nainar    //ALOGE("Script isThreadable? %d", mIsThreadable);
28868173de001c5d41c74828a426651e07cfd9e8710Pirama Arumuga Nainar
2898409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    if (kDebugGlobalVariables) {
2908409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines        mScriptExec->dumpGlobalInfo();
2918409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    }
2928409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines
293d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    return true;
294d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni}
295d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni
296709a0978ae141198018ca9769f8d96292a8928e6Jason Samsbool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir,
297709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                            uint8_t const *bitcode, size_t bitcodeSize,
298005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines                            uint32_t flags, char const *bccPluginName) {
299e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni    //ALOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir,
300e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni    // bitcode, bitcodeSize, flags, lookupFunc);
301709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //ALOGE("rsdScriptInit %p %p", rsc, script);
302709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
303709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->lockMutex();
304110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
305005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines    bool useRSDebugContext = false;
306709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
30744bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    mCompilerDriver = nullptr;
308709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
309709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCompilerDriver = new bcc::RSCompilerDriver();
31044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (mCompilerDriver == nullptr) {
311709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ALOGE("bcc: FAILS to create compiler driver (out of memory)");
312709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mCtx->unlockMutex();
313709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return false;
314709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
315709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
316b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    // Run any compiler setup functions we have been provided with.
317b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    RSSetupCompilerCallback setupCompilerCallback =
318b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines            mCtx->getSetupCompilerCallback();
31944bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (setupCompilerCallback != nullptr) {
320b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines        setupCompilerCallback(mCompilerDriver);
321b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines    }
322b7d9c80c98fc96aa7c638e3124be24f13a6436b2Stephen Hines
32340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcinfo::MetadataExtractor bitcodeMetadata((const char *) bitcode, bitcodeSize);
32440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    if (!bitcodeMetadata.extract()) {
325b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        ALOGE("Could not extract metadata from bitcode");
326f94e8db4232979b2fc93e8a77c42bfa57d3da56aStephen Hines        mCtx->unlockMutex();
327b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines        return false;
328b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines    }
329b58d9adf52f0216c0281c749023bdd5b52236875Stephen Hines
33040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    const char* core_lib = findCoreLib(bitcodeMetadata, (const char*)bitcode, bitcodeSize);
331cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines
332cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines    if (mCtx->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
333f47e8b4b86bf194e65398032f3f5f47a6da89f3fStephen Hines        mCompilerDriver->setDebugContext(true);
334005113297b19ed256b6db9d6bc293ed9266899fcStephen Hines        useRSDebugContext = true;
335ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines    }
336ba17ae494add84056bbf3275b68e40e62a643db0Stephen Hines
3376847e73314e13aa02231268cca245a81eb0539caChris Wailes    std::string bcFileName(cacheDir);
33840e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcFileName.append("/");
33940e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcFileName.append(resName);
34040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    bcFileName.append(".bc");
34140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet
34240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    std::vector<const char*> compileArguments;
3438409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    bool emitGlobalInfo = mCtx->getEmbedGlobalInfo();
3448409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    bool emitGlobalInfoSkipConstant = mCtx->getEmbedGlobalInfoSkipConstant();
34540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    setCompileArguments(&compileArguments, bcFileName, cacheDir, resName, core_lib,
3468409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines                        useRSDebugContext, bccPluginName, emitGlobalInfo,
3478409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines                        emitGlobalInfoSkipConstant);
348aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
349aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    mChecksumNeeded = isChecksumNeeded();
350aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    if (mChecksumNeeded) {
351aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        std::vector<const char *> bccFiles = { BCC_EXE_PATH,
352aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar                                               core_lib,
353aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar                                             };
3542fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar
3552fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        // The last argument of compileArguments is a nullptr, so remove 1 from
3562fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        // the size.
3572fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar        std::unique_ptr<const char> compileCommandLine(
3582fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar            rsuJoinStrings(compileArguments.size()-1, compileArguments.data()));
3592fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar
360aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        mBuildChecksum = constructBuildChecksum(bitcode, bitcodeSize,
361aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar                                                compileCommandLine.get(),
362cb17015fed6b11a5028f31cc804a3847e379945dYang Ni                                                bccFiles.data(), bccFiles.size());
363aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
364cb17015fed6b11a5028f31cc804a3847e379945dYang Ni        if (mBuildChecksum == 0) {
365aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar            // cannot compute checksum but verification is enabled
366aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar            mCtx->unlockMutex();
367aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar            return false;
368aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        }
369aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    }
370aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    else {
371aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        // add a dummy/constant as a checksum if verification is disabled
372cb17015fed6b11a5028f31cc804a3847e379945dYang Ni        mBuildChecksum = 0xabadcafe;
373aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    }
374aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
375aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    // Append build checksum to commandline
376aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    // Handle the terminal nullptr in compileArguments
377aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    compileArguments.pop_back();
378aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    compileArguments.push_back("-build-checksum");
379cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    std::stringstream ss;
380cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    ss << std::hex << mBuildChecksum;
381cb17015fed6b11a5028f31cc804a3847e379945dYang Ni    compileArguments.push_back(ss.str().c_str());
382aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar    compileArguments.push_back(nullptr);
383aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
384bf96a520e162b503b293f65ca9ca9be66d4a0036Tim Murray    if (!is_force_recompile() && !useRSDebugContext) {
3851c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ni        mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
386aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
387aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        // Read RS info from the shared object to detect checksum mismatch
388aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        if (mScriptSO != nullptr && !storeRSInfoFromSO()) {
389aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar            dlclose(mScriptSO);
390aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar            mScriptSO = nullptr;
391aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        }
392cca3d6ca444bef3b6d75431ec19bd07bfe40a733Stephen Hines    }
393709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
39440e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    // If we can't, it's either not there or out of date.  We compile the bit code and try loading
39540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet    // again.
39645e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines    if (mScriptSO == nullptr) {
39745e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines        if (!compileBitcode(bcFileName, (const char*)bitcode, bitcodeSize,
3982fa8a238dd69afebdeb757adcb1d674043d78e32Pirama Arumuga Nainar                            compileArguments))
39945e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines        {
40040e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            ALOGE("bcc: FAILS to compile '%s'", resName);
40140e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            mCtx->unlockMutex();
40240e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            return false;
40340e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        }
40445e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines
4054c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines        if (!SharedLibraryUtils::createSharedLibrary(mCtx->getContext()->getDriverName(),
4064c368af7e705f0bcb77fa99495b2e33ef20d2699Stephen Hines                                                     cacheDir, resName)) {
40745e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines            ALOGE("Linker: Failed to link object file '%s'", resName);
40845e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines            mCtx->unlockMutex();
40945e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines            return false;
41045e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines        }
41145e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines
4121c44cb6b1133730cd18929d637e71e9326c70bd0Yang Ni        mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
41345e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines        if (mScriptSO == nullptr) {
41445e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines            ALOGE("Unable to load '%s'", resName);
41540e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            mCtx->unlockMutex();
41640e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet            return false;
41740e35cdbe217ec8bf9fc3c69873c7d62fc14158fJean-Luc Brouillet        }
418aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar
419aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        // Read RS symbol information from the .so.
420aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        if (!storeRSInfoFromSO()) {
421aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar            goto error;
422aa6757ffc1b23d771566439c3179fdbc1e5ba569Pirama Arumuga Nainar        }
423709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
424709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
425c31585b8ca865bf2b35abc79c8a8ee42de27bee8Yang Ni    mBitcodeFilePath.setTo(bcFileName.c_str());
426da0f069871343119251d6b0586be356dc2146a62Yang Ni
427dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar#else  // RS_COMPATIBILITY_LIB is defined
428f3213d7fd648da98bb3b03204eaf90f03c31926bMiao Wang    const char *nativeLibDir = mCtx->getContext()->getNativeLibDir();
429f3213d7fd648da98bb3b03204eaf90f03c31926bMiao Wang    mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName, nativeLibDir);
430110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
431dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (!mScriptSO) {
432dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar        goto error;
433dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    }
434110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
435dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (!storeRSInfoFromSO()) {
436c2c11cc9037d5ddd55282c6dab82db542b398d9eStephen Hines        goto error;
437110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
438110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#endif
439709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->unlockMutex();
440709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return true;
441110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
442110f181b7966212a36ef18016f9b81c7322d0a2fJason Samserror:
443110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
444110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    mCtx->unlockMutex();
445110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
446110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        dlclose(mScriptSO);
447eb9aa675754c49f613c6ad71d41472b30f38b007Yang Ni        mScriptSO = nullptr;
448110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
449110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    return false;
450709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
451709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
4529ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#ifndef RS_COMPATIBILITY_LIB
4539ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
4549ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouilletconst char* RsdCpuScriptImpl::findCoreLib(const bcinfo::MetadataExtractor& ME, const char* bitcode,
4559ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet                                          size_t bitcodeSize) {
4569ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    const char* defaultLib = SYSLIBPATH"/libclcore.bc";
4579ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
4589ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // If we're debugging, use the debug library.
4599ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    if (mCtx->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
4609ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return SYSLIBPATH"/libclcore_debug.bc";
4619ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    }
4629ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
4639ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // If a callback has been registered to specify a library, use that.
4649ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    RSSelectRTCallback selectRTCallback = mCtx->getSelectRTCallback();
46544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (selectRTCallback != nullptr) {
4669ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return selectRTCallback((const char*)bitcode, bitcodeSize);
4679ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    }
4689ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
4699ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // Check for a platform specific library
4709ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#if defined(ARCH_ARM_HAVE_NEON) && !defined(DISABLE_CLCORE_NEON)
4719ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    enum bcinfo::RSFloatPrecision prec = ME.getRSFloatPrecision();
472f4d3836c83097f57b62c235910fbf490c56ddf56Jean-Luc Brouillet    if (prec == bcinfo::RS_FP_Relaxed) {
4739ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // NEON-capable ARMv7a devices can use an accelerated math library
4749ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // for all reduced precision scripts.
4759ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // ARMv8 does not use NEON, as ASIMD can be used with all precision
4769ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        // levels.
4779ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return SYSLIBPATH"/libclcore_neon.bc";
4789ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    } else {
4799ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet        return defaultLib;
4809ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    }
4819ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#elif defined(__i386__) || defined(__x86_64__)
4829ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    // x86 devices will use an optimized library.
4839ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    return SYSLIBPATH"/libclcore_x86.bc";
4849ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#else
4859ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet    return defaultLib;
4869ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#endif
4879ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet}
4889ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
4899ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet#endif
4909ab5094dd32352b33e251e540934f6e814c5fa5bJean-Luc Brouillet
491709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::populateScript(Script *script) {
492110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // Copy info over to runtime
493d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    script->mHal.info.exportedFunctionCount = mScriptExec->getExportedFunctionCount();
494d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    script->mHal.info.exportedVariableCount = mScriptExec->getExportedVariableCount();
495577194ac9c2bf10f31e564de91371764b265929aPirama Arumuga Nainar    script->mHal.info.exportedPragmaCount = mScriptExec->getPragmaCount();;
496e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni    script->mHal.info.exportedPragmaKeyList = mScriptExec->getPragmaKeys();
497e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni    script->mHal.info.exportedPragmaValueList = mScriptExec->getPragmaValues();
498110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams
499110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    // Bug, need to stash in metadata
500110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mRootExpand) {
501110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        script->mHal.info.root = mRootExpand;
502110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    } else {
503110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        script->mHal.info.root = mRoot;
504110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
505709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
506709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
507709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
508bf2111d3b3de310932099514f06924e48fa1d7b2Jason Samsbool RsdCpuScriptImpl::forEachMtlsSetup(const Allocation ** ains,
509f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                        uint32_t inLen,
510f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                        Allocation * aout,
511709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        const void * usr, uint32_t usrLen,
512709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        const RsScriptCall *sc,
513709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                        MTLaunchStruct *mtls) {
514709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
515709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memset(mtls, 0, sizeof(MTLaunchStruct));
516709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
517f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes    for (int index = inLen; --index >= 0;) {
518f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes        const Allocation* ain = ains[index];
5194b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
520f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes        // possible for this to occur if IO_OUTPUT/IO_INPUT with no bound surface
52144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        if (ain != nullptr &&
52244bef6fba6244292b751387f3d6c31cca96c28adChris Wailes            (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr == nullptr) {
52344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes
5244b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
525f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                         "rsForEach called with null in allocations");
526bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams            return false;
5274b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
5284b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
5294b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
53044bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (aout &&
53144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        (const uint8_t *)aout->mHal.drvState.lod[0].mallocPtr == nullptr) {
53244bef6fba6244292b751387f3d6c31cca96c28adChris Wailes
533f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
534f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                     "rsForEach called with null out allocations");
535bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        return false;
5364b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
5374b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
538f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes    if (inLen > 0) {
5394b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Allocation *ain0   = ains[0];
5404b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Type       *inType = ain0->getType();
5414b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
542c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.x = inType->getDimX();
543c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.y = inType->getDimY();
544c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.z = inType->getDimZ();
5454b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
5464b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        for (int Index = inLen; --Index >= 1;) {
5474b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            if (!ain0->hasSameDims(ains[Index])) {
5484b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes                mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
549e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni                  "Failed to launch kernel; dimensions of input and output"
550e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni                  "allocations do not match.");
5514b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
552bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams                return false;
5534b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            }
5544b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
5554b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
55644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    } else if (aout != nullptr) {
5574b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        const Type *outType = aout->getType();
5584b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
559c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.x = outType->getDimX();
560c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.y = outType->getDimY();
561c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.dim.z = outType->getDimZ();
5624b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
563a9139c724f8312b3634d213599f2d6b3b2505db2Jason Sams    } else if (sc != nullptr) {
564a9139c724f8312b3634d213599f2d6b3b2505db2Jason Sams        mtls->fep.dim.x = sc->xEnd;
565a9139c724f8312b3634d213599f2d6b3b2505db2Jason Sams        mtls->fep.dim.y = sc->yEnd;
566a9139c724f8312b3634d213599f2d6b3b2505db2Jason Sams        mtls->fep.dim.z = 0;
5674b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
568f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
569f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                     "rsForEach called with null allocations");
570bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        return false;
5714b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
5724b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
57344bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (inLen > 0 && aout != nullptr) {
5744b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        if (!ains[0]->hasSameDims(aout)) {
5754b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
5764b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes              "Failed to launch kernel; dimensions of input and output allocations do not match.");
5774b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
578bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams            return false;
5794b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
5804b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
5814b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
5824b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (!sc || (sc->xEnd == 0)) {
583bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.x = mtls->fep.dim.x;
5844b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
585bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.x = rsMin(mtls->fep.dim.x, sc->xStart);
586bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.x = rsMin(mtls->fep.dim.x, sc->xEnd);
58780afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        if (mtls->start.x >= mtls->end.x) {
58880afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
58980afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar              "Failed to launch kernel; Invalid xStart or xEnd.");
59080afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            return false;
59180afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        }
5924b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
5934b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
5944b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (!sc || (sc->yEnd == 0)) {
595bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.y = mtls->fep.dim.y;
5964b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
597bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.y = rsMin(mtls->fep.dim.y, sc->yStart);
598bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.y = rsMin(mtls->fep.dim.y, sc->yEnd);
59980afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        if (mtls->start.y >= mtls->end.y) {
60080afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
60180afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar              "Failed to launch kernel; Invalid yStart or yEnd.");
60280afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            return false;
60380afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        }
6044b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
6054b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
6064b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    if (!sc || (sc->zEnd == 0)) {
607bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.z = mtls->fep.dim.z;
6084b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    } else {
609bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.z = rsMin(mtls->fep.dim.z, sc->zStart);
610bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.z = rsMin(mtls->fep.dim.z, sc->zEnd);
61180afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        if (mtls->start.z >= mtls->end.z) {
61280afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
61380afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar              "Failed to launch kernel; Invalid zStart or zEnd.");
61480afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            return false;
61580afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        }
6164b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
6174b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
618bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    if (!sc || (sc->arrayEnd == 0)) {
619bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[0] = mtls->fep.dim.array[0];
620bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    } else {
621bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.array[0] = rsMin(mtls->fep.dim.array[0], sc->arrayStart);
622bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[0] = rsMin(mtls->fep.dim.array[0], sc->arrayEnd);
62380afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        if (mtls->start.array[0] >= mtls->end.array[0]) {
62480afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
62580afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar              "Failed to launch kernel; Invalid arrayStart or arrayEnd.");
62680afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            return false;
62780afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        }
628bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    }
6294b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
630bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    if (!sc || (sc->array2End == 0)) {
631bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[1] = mtls->fep.dim.array[1];
632bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    } else {
633bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.array[1] = rsMin(mtls->fep.dim.array[1], sc->array2Start);
634bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[1] = rsMin(mtls->fep.dim.array[1], sc->array2End);
63580afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        if (mtls->start.array[1] >= mtls->end.array[1]) {
63680afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
63780afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar              "Failed to launch kernel; Invalid array2Start or array2End.");
63880afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            return false;
63980afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        }
640bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    }
641bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams
642bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    if (!sc || (sc->array3End == 0)) {
643bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[2] = mtls->fep.dim.array[2];
644bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    } else {
645bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.array[2] = rsMin(mtls->fep.dim.array[2], sc->array3Start);
646bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[2] = rsMin(mtls->fep.dim.array[2], sc->array3End);
64780afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        if (mtls->start.array[2] >= mtls->end.array[2]) {
64880afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
64980afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar              "Failed to launch kernel; Invalid array3Start or array3End.");
65080afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            return false;
65180afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        }
652bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    }
653bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams
654bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    if (!sc || (sc->array4End == 0)) {
655bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[3] = mtls->fep.dim.array[3];
656bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    } else {
657bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->start.array[3] = rsMin(mtls->fep.dim.array[3], sc->array4Start);
658bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mtls->end.array[3] = rsMin(mtls->fep.dim.array[3], sc->array4End);
65980afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        if (mtls->start.array[3] >= mtls->end.array[3]) {
66080afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT,
66180afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar              "Failed to launch kernel; Invalid array4Start or array4End.");
66280afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar            return false;
66380afd424b02291e6f088cab2961537c7ba1ee2a5Pirama Arumuga Nainar        }
664bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    }
665bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams
666bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams
667bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    // The X & Y walkers always want 0-1 min even if dim is not present
668bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    mtls->end.x    = rsMax((uint32_t)1, mtls->end.x);
669bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    mtls->end.y    = rsMax((uint32_t)1, mtls->end.y);
6704b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
6714b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->rsc        = mCtx;
672c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams    if (ains) {
673c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        memcpy(mtls->ains, ains, inLen * sizeof(ains[0]));
674c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams    }
675c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams    mtls->aout[0]    = aout;
6764b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->fep.usr    = usr;
6774b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->fep.usrLen = usrLen;
6784b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->mSliceSize = 1;
6794b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->mSliceNum  = 0;
6804b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
6814b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    mtls->isThreadable  = mIsThreadable;
6824b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
683f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes    if (inLen > 0) {
684f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes        mtls->fep.inLen = inLen;
6854b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        for (int index = inLen; --index >= 0;) {
686c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams            mtls->fep.inPtr[index] = (const uint8_t*)ains[index]->mHal.drvState.lod[0].mallocPtr;
687c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams            mtls->fep.inStride[index] = ains[index]->getType()->getElementSizeBytes();
6884b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes        }
6894b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
6904b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
69144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    if (aout != nullptr) {
692c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.outPtr[0] = (uint8_t *)aout->mHal.drvState.lod[0].mallocPtr;
693c0d68470b978a79ce024fde56f23ea3690603ccdJason Sams        mtls->fep.outStride[0] = aout->getType()->getElementSizeBytes();
6944b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes    }
695bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams
696bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    // All validation passed, ok to launch threads
697bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    return true;
6984b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes}
6994b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
700709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
701709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeForEach(uint32_t slot,
702f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                     const Allocation ** ains,
703f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                     uint32_t inLen,
704709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     Allocation * aout,
705709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const void * usr,
706709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     uint32_t usrLen,
707709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                     const RsScriptCall *sc) {
708709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
709709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    MTLaunchStruct mtls;
7104b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
711bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    if (forEachMtlsSetup(ains, inLen, aout, usr, usrLen, sc, &mtls)) {
712bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        forEachKernelSetup(slot, &mtls);
7134b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
714bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
715bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mCtx->launchThreads(ains, inLen, aout, sc, &mtls);
716bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams        mCtx->setTLS(oldTLS);
717bf2111d3b3de310932099514f06924e48fa1d7b2Jason Sams    }
7184b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes}
7194b3c34e6833e39bc89c2128002806b654b8e623dChris Wailes
720709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::forEachKernelSetup(uint32_t slot, MTLaunchStruct *mtls) {
721709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->script = this;
722709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mtls->fep.slot = slot;
723d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    mtls->kernel = mScriptExec->getForEachFunction(slot);
72444bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    rsAssert(mtls->kernel != nullptr);
725d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    mtls->sig = mScriptExec->getForEachSignature(slot);
726709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
727709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
728709a0978ae141198018ca9769f8d96292a8928e6Jason Samsint RsdCpuScriptImpl::invokeRoot() {
729709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
730709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    int ret = mRoot();
731709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
732709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    return ret;
733709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
734709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
735709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeInit() {
736709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mInit) {
737709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mInit();
738709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
739709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
740709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
741709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeFreeChildren() {
742709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mFreeChildren) {
743709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        mFreeChildren();
744709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
745709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
746709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
747709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::invokeFunction(uint32_t slot, const void *params,
748709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                      size_t paramLength) {
749dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    //ALOGE("invoke %i %p %zu", slot, params, paramLength);
750eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    void * ap = nullptr;
751eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen
752eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen#if defined(__x86_64__)
753eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    // The invoked function could have input parameter of vector type for example float4 which
754eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    // requires void* params to be 16 bytes aligned when using SSE instructions for x86_64 platform.
755eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    // So try to align void* params before passing them into RS exported function.
756eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen
757eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    if ((uint8_t)(uint64_t)params & 0x0F) {
758eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen        if ((ap = (void*)memalign(16, paramLength)) != nullptr) {
759eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen            memcpy(ap, params, paramLength);
760eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen        } else {
761e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni            ALOGE("x86_64: invokeFunction memalign error, still use params which"
762e8f9fba78f0cb79fa8773373a635e30382113a75Yang Ni                  " is not 16 bytes aligned.");
763eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen        }
764eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen    }
765eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen#endif
766709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
767709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this);
768dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    reinterpret_cast<void (*)(const void *, uint32_t)>(
769d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni        mScriptExec->getInvokeFunction(slot))(ap? (const void *) ap: params, paramLength);
770eaba5a3ca215729258dcf9ac6f0bb5f88c78f998Yong Chen
771709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mCtx->setTLS(oldTLS);
772709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
773709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
774709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalVar(uint32_t slot, const void *data, size_t dataLength) {
775709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(!script->mFieldIsObject[slot]);
776dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    //ALOGE("setGlobalVar %i %p %zu", slot, data, dataLength);
777709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
778709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //if (mIntrinsicID) {
779709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //mIntrinsicFuncs.setVar(dc, script, drv->mIntrinsicData, slot, data, dataLength);
780709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //return;
781709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //}
782709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
783d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    int32_t *destPtr = reinterpret_cast<int32_t *>(mScriptExec->getFieldAddress(slot));
784709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
785709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
786709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
787709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
788709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
789709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, data, dataLength);
790709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
791709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
7929c64239ebbfa4170190ede812e69150035e008e0Tim Murrayvoid RsdCpuScriptImpl::getGlobalVar(uint32_t slot, void *data, size_t dataLength) {
7939c64239ebbfa4170190ede812e69150035e008e0Tim Murray    //rsAssert(!script->mFieldIsObject[slot]);
794dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    //ALOGE("getGlobalVar %i %p %zu", slot, data, dataLength);
7959c64239ebbfa4170190ede812e69150035e008e0Tim Murray
796d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    int32_t *srcPtr = reinterpret_cast<int32_t *>(mScriptExec->getFieldAddress(slot));
7979c64239ebbfa4170190ede812e69150035e008e0Tim Murray    if (!srcPtr) {
7989c64239ebbfa4170190ede812e69150035e008e0Tim Murray        //ALOGV("Calling setVar on slot = %i which is null", slot);
7999c64239ebbfa4170190ede812e69150035e008e0Tim Murray        return;
8009c64239ebbfa4170190ede812e69150035e008e0Tim Murray    }
8019c64239ebbfa4170190ede812e69150035e008e0Tim Murray    memcpy(data, srcPtr, dataLength);
8029c64239ebbfa4170190ede812e69150035e008e0Tim Murray}
8039c64239ebbfa4170190ede812e69150035e008e0Tim Murray
8049c64239ebbfa4170190ede812e69150035e008e0Tim Murray
805709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalVarWithElemDims(uint32_t slot, const void *data, size_t dataLength,
806709a0978ae141198018ca9769f8d96292a8928e6Jason Sams                                                const Element *elem,
807ac8d146a41f18afad5314ac8af440d6aedbe20bfStephen Hines                                                const uint32_t *dims, size_t dimLength) {
808d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    int32_t *destPtr = reinterpret_cast<int32_t *>(mScriptExec->getFieldAddress(slot));
809709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
810709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
811709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
812709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
813709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
814709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // We want to look at dimension in terms of integer components,
815709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // but dimLength is given in terms of bytes.
816709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    dimLength /= sizeof(int);
817709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
818709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    // Only a single dimension is currently supported.
819709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    rsAssert(dimLength == 1);
820709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (dimLength == 1) {
821709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        // First do the increment loop.
822709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        size_t stride = elem->getSizeBytes();
823709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        const char *cVal = reinterpret_cast<const char *>(data);
824ac8d146a41f18afad5314ac8af440d6aedbe20bfStephen Hines        for (uint32_t i = 0; i < dims[0]; i++) {
825709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            elem->incRefs(cVal);
826709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            cVal += stride;
827709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
828709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
829709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        // Decrement loop comes after (to prevent race conditions).
830709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        char *oldVal = reinterpret_cast<char *>(destPtr);
831ac8d146a41f18afad5314ac8af440d6aedbe20bfStephen Hines        for (uint32_t i = 0; i < dims[0]; i++) {
832709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            elem->decRefs(oldVal);
833709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            oldVal += stride;
834709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
835709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
836709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
837709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, data, dataLength);
838709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
839709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
840709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalBind(uint32_t slot, Allocation *data) {
841709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
842709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(!script->mFieldIsObject[slot]);
843dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    //ALOGE("setGlobalBind %i %p", slot, data);
844709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
845d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    int32_t *destPtr = reinterpret_cast<int32_t *>(mScriptExec->getFieldAddress(slot));
846709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
847709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
848709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
849709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
850709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
85144bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    void *ptr = nullptr;
852709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    mBoundAllocs[slot] = data;
853dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    if (data) {
854709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        ptr = data->mHal.drvState.lod[0].mallocPtr;
855709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
856709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    memcpy(destPtr, &ptr, sizeof(void *));
857709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
858709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
859709a0978ae141198018ca9769f8d96292a8928e6Jason Samsvoid RsdCpuScriptImpl::setGlobalObj(uint32_t slot, ObjectBase *data) {
860709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
861709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    //rsAssert(script->mFieldIsObject[slot]);
862dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar    //ALOGE("setGlobalObj %i %p", slot, data);
863709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
864d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    int32_t *destPtr = reinterpret_cast<int32_t *>(mScriptExec->getFieldAddress(slot));
865709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!destPtr) {
866709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        //ALOGV("Calling setVar on slot = %i which is null", slot);
867709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        return;
868709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
869709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
87005ef73f2d934f1083cc3b8aeb33fe21de9d6e88fJason Sams    rsrSetObject(mCtx->getContext(), (rs_object_base *)destPtr, data);
871709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
872709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
873062c287f573ecc06c38ee4295e5627e12c52ac3dYang Niconst char* RsdCpuScriptImpl::getFieldName(uint32_t slot) const {
874062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni    return mScriptExec->getFieldName(slot);
875062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni}
876062c287f573ecc06c38ee4295e5627e12c52ac3dYang Ni
877709a0978ae141198018ca9769f8d96292a8928e6Jason SamsRsdCpuScriptImpl::~RsdCpuScriptImpl() {
878110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams#ifndef RS_COMPATIBILITY_LIB
879709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (mCompilerDriver) {
880709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        delete mCompilerDriver;
881709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
88245e753a46e587c69b3b0d0c5138e88715a24a29aStephen Hines#endif
883dc0d8f7c0f1f43f25c34fbc04656ad578f6e953bPirama Arumuga Nainar
884d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni    if (mScriptExec != nullptr) {
885d9bae689c1b8c3f2ed1a5f2b374dc9393584b8ddYang Ni        delete mScriptExec;
886110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
887110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mBoundAllocs) delete[] mBoundAllocs;
888110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    if (mScriptSO) {
889110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams        dlclose(mScriptSO);
890110f181b7966212a36ef18016f9b81c7322d0a2fJason Sams    }
891709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
892709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
893709a0978ae141198018ca9769f8d96292a8928e6Jason SamsAllocation * RsdCpuScriptImpl::getAllocationForPointer(const void *ptr) const {
894709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    if (!ptr) {
89544bef6fba6244292b751387f3d6c31cca96c28adChris Wailes        return nullptr;
896709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
897709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
898709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    for (uint32_t ct=0; ct < mScript->mHal.info.exportedVariableCount; ct++) {
899709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        Allocation *a = mBoundAllocs[ct];
900709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (!a) continue;
901709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        if (a->mHal.drvState.lod[0].mallocPtr == ptr) {
902709a0978ae141198018ca9769f8d96292a8928e6Jason Sams            return a;
903709a0978ae141198018ca9769f8d96292a8928e6Jason Sams        }
904709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    }
905709a0978ae141198018ca9769f8d96292a8928e6Jason Sams    ALOGE("rsGetAllocation, failed to find %p", ptr);
90644bef6fba6244292b751387f3d6c31cca96c28adChris Wailes    return nullptr;
907709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
908709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
9098409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hinesint RsdCpuScriptImpl::getGlobalEntries() const {
9108409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    return mScriptExec->getGlobalEntries();
9118409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines}
9128409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines
9138409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hinesconst char * RsdCpuScriptImpl::getGlobalName(int i) const {
9148409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    return mScriptExec->getGlobalName(i);
9158409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines}
9168409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines
9178409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hinesconst void * RsdCpuScriptImpl::getGlobalAddress(int i) const {
9188409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    return mScriptExec->getGlobalAddress(i);
9198409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines}
9208409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines
9218409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hinessize_t RsdCpuScriptImpl::getGlobalSize(int i) const {
9228409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines    return mScriptExec->getGlobalSize(i);
9238409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines}
9248409d6414dd4a42aa59779fcfe9fce18648cb135Stephen Hines
9255aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hinesuint32_t RsdCpuScriptImpl::getGlobalProperties(int i) const {
9265aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines    return mScriptExec->getGlobalProperties(i);
9275aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines}
9285aa018cc36e589b07674957714d27ae3d1fa1c4eStephen Hines
929f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailesvoid RsdCpuScriptImpl::preLaunch(uint32_t slot, const Allocation ** ains,
930f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                 uint32_t inLen, Allocation * aout,
931f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                 const void * usr, uint32_t usrLen,
932f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                 const RsScriptCall *sc) {}
93317e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams
934f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailesvoid RsdCpuScriptImpl::postLaunch(uint32_t slot, const Allocation ** ains,
935f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                  uint32_t inLen, Allocation * aout,
936f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                  const void * usr, uint32_t usrLen,
937f37121300217d3b39ab66dd9c8881bcbcad932dfChris Wailes                                  const RsScriptCall *sc) {}
93817e3cdc24776d8fdbf1ce16287b9b4dcd516708fJason Sams
939709a0978ae141198018ca9769f8d96292a8928e6Jason Sams
940709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
941709a0978ae141198018ca9769f8d96292a8928e6Jason Sams}
942