11e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang/*
21e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Copyright 2012, The Android Open Source Project
31e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *
41e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
51e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * you may not use this file except in compliance with the License.
61e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * You may obtain a copy of the License at
71e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *
81e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
91e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *
101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Unless required by applicable law or agreed to in writing, software
111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * See the License for the specific language governing permissions and
141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * limitations under the License.
151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang */
161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
17f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet// #define LOG_NDEBUG 0
18e198abec6c5e3eab380ccf6897b0a0b9c2dd92ddStephen Hines#include "bcc/Renderscript/RSInfo.h"
191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2048cd745480738c026312931877ecb8ebecb1c64eStephen Hines#if !defined(_WIN32)  /* TODO create a HAVE_DLFCN_H */
21f290793bc65b8483332ac8b568962395c4a63927Zonr Chang#include <dlfcn.h>
2248cd745480738c026312931877ecb8ebecb1c64eStephen Hines#endif
23f290793bc65b8483332ac8b568962395c4a63927Zonr Chang
241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#include <cstring>
251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#include <new>
26688e4c0dd73c273551f517fa85a08b40dd63eaccStephen Hines#include <string>
271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
28c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/FileBase.h"
29ef73a242762bcd8113b9b65ceccbe7d909b5acbcZonr Chang#include "bcc/Support/Log.h"
301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
31b81d697ec617be24494b622a3532f1c465264415Nick Kralevich#ifdef HAVE_ANDROID_OS
32ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao#include <cutils/properties.h>
33b81d697ec617be24494b622a3532f1c465264415Nick Kralevich#endif
34ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao
351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changusing namespace bcc;
361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
3701f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hinesandroid::String8 RSInfo::GetPath(const char *pFilename) {
3801f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines  android::String8 result(pFilename);
391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  result.append(".info");
401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return result;
411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
43f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouilletstatic std::string stringFromSourceHash(const RSInfo::DependencyHashTy& hash) {
44f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    std::string s;
45f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    s.reserve(SHA1_DIGEST_LENGTH + 1);
46f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    for (int i = 0; i < SHA1_DIGEST_LENGTH; i++) {
47f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        char buf[4];
48f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        snprintf(buf, sizeof(buf), "%02x", hash[i]);
49f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        s.append(buf);
50f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    }
51f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    return s;
52f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet}
53f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet
54f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouilletstd::string bcc::getCommandLine(int argc, const char* const* argv) {
55f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    std::string s;
56f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    for (int i = 0; i < argc; i++) {
57f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        if (i > 0) {
58f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet            s += ' ';
59f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        }
60f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        s += argv[i];
61f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    }
62f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    return s;
63f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet}
64f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet
65f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouilletbool RSInfo::IsConsistent(const char* pInputFilename, const DependencyHashTy& expectedSourceHash,
66f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                          const char* expectedCompileCommandLine,
67f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                          const char* expectedBuildFingerprint) {
68f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    if (::memcmp(mSourceHash, expectedSourceHash, SHA1_DIGEST_LENGTH) != 0) {
69c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet        ALOGD("Cache %s is dirty due to the source it depends on has been changed:",
70c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet              pInputFilename);
71f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        ALOGD("expected: %s", stringFromSourceHash(expectedSourceHash).c_str());
72f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        ALOGD("cached  : %s", stringFromSourceHash(mSourceHash).c_str());
73f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        return false;
74f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    }
75f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    if (strcmp(expectedCompileCommandLine, mCompileCommandLine) != 0) {
76f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        ALOGD("Cache %s is dirty because the command line used to compile it has changed:",
77f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet              pInputFilename);
78f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        ALOGD("expected: %s", expectedCompileCommandLine);
79f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        ALOGD("cached  : %s", mCompileCommandLine);
80f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        return false;
81f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    }
82f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    if (strcmp(expectedBuildFingerprint, mBuildFingerprint) != 0) {
83f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        ALOGD("Cache %s is dirty because the build fingerprint has changed:", pInputFilename);
84f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        ALOGD("expected: %s", expectedBuildFingerprint);
85f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet        ALOGD("cached  : %s", mBuildFingerprint);
86f7401ab4b42dcbd782f20ba5c279694edbd28516Shih-wei Liao        return false;
87f7401ab4b42dcbd782f20ba5c279694edbd28516Shih-wei Liao    }
88c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet    return true;
891e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
901e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
911e2adce6df4414d827149ec563c9c89f21ea7426Zonr ChangRSInfo::RSInfo(size_t pStringPoolSize) : mStringPool(NULL) {
921e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ::memset(&mHeader, 0, sizeof(mHeader));
931e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ::memcpy(mHeader.magic, RSINFO_MAGIC, sizeof(mHeader.magic));
951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ::memcpy(mHeader.version, RSINFO_VERSION, sizeof(mHeader.version));
961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.headerSize = sizeof(mHeader);
981e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
991e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.pragmaList.itemSize = sizeof(rsinfo::PragmaItem);
1001e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.objectSlotList.itemSize = sizeof(rsinfo::ObjectSlotItem);
1011e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.exportVarNameList.itemSize = sizeof(rsinfo::ExportVarNameItem);
1021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.exportFuncNameList.itemSize = sizeof(rsinfo::ExportFuncNameItem);
1031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.exportForeachFuncList.itemSize = sizeof(rsinfo::ExportForeachFuncItem);
1041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pStringPoolSize > 0) {
1061e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    mHeader.strPoolSize = pStringPoolSize;
1071e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    mStringPool = new (std::nothrow) char [ mHeader.strPoolSize ];
1081e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    if (mStringPool == NULL) {
1091e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      ALOGE("Out of memory when allocate memory for string pool in RSInfo "
1101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang            "constructor (size: %u)!", mHeader.strPoolSize);
1111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    }
1121ae3fd6e2290fe1635bafe91a65e0e88e641b6fcStephen Hines    ::memset(mStringPool, 0, mHeader.strPoolSize);
1131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
114c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet  mSourceHash = NULL;
115f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  mCompileCommandLine = NULL;
116f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  mBuildFingerprint = NULL;
1171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
1181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1191e2adce6df4414d827149ec563c9c89f21ea7426Zonr ChangRSInfo::~RSInfo() {
1201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  delete [] mStringPool;
1211e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
1221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changbool RSInfo::layout(off_t initial_offset) {
124c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet  mHeader.pragmaList.offset = initial_offset +
125c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet                              mHeader.headerSize +
126c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet                              mHeader.strPoolSize;
1271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.pragmaList.count = mPragmas.size();
1281e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
129c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet#define AFTER(_list) ((_list).offset + (_list).itemSize * (_list).count)
1301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.objectSlotList.offset = AFTER(mHeader.pragmaList);
1311e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.objectSlotList.count = mObjectSlots.size();
1321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1331e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.exportVarNameList.offset = AFTER(mHeader.objectSlotList);
1341e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.exportVarNameList.count = mExportVarNames.size();
1351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.exportFuncNameList.offset = AFTER(mHeader.exportVarNameList);
1371e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.exportFuncNameList.count = mExportFuncNames.size();
1381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.exportForeachFuncList.offset = AFTER(mHeader.exportFuncNameList);
1401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  mHeader.exportForeachFuncList.count = mExportForeachFuncs.size();
1411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#undef AFTER
1421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1431e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
1441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
1451e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1461e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changvoid RSInfo::dump() const {
1471e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Hide the codes to save the code size when debugging is disabled.
1481e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#if !LOG_NDEBUG
1491e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Dump header
1511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ALOGV("RSInfo Header:");
1521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ALOGV("\tIs threadable: %s", ((mHeader.isThreadable) ? "true" : "false"));
1531e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ALOGV("\tHeader size: %u", mHeader.headerSize);
1541e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ALOGV("\tString pool size: %u", mHeader.strPoolSize);
1551e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
156c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet  if (mSourceHash == NULL) {
157f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet      ALOGV("Source hash: NULL!");
158c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet  } else {
159f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet      ALOGV("Source hash: %s", stringFromSourceHash(mSourceHash).c_str());
160c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet  }
161c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet
162f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  ALOGV("Compile Command Line: ", mCompileCommandLine ? mCompileCommandLine : "(NULL)");
163f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  ALOGV("mBuildFingerprint: ", mBuildFingerprint ? mBuildFingerprint : "(NULL)");
164f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet
1651e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#define DUMP_LIST_HEADER(_name, _header) do { \
1661e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ALOGV(_name ":"); \
1671e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ALOGV("\toffset: %u", (_header).offset);  \
1681e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ALOGV("\t# of item: %u", (_header).count);  \
1691e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ALOGV("\tsize of each item: %u", (_header).itemSize); \
1701e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang} while (false)
1711e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1721e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  DUMP_LIST_HEADER("Pragma list", mHeader.pragmaList);
1731e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  for (PragmaListTy::const_iterator pragma_iter = mPragmas.begin(),
1741e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        pragma_end = mPragmas.end(); pragma_iter != pragma_end; pragma_iter++) {
1751e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGV("\tkey: %s, value: %s", pragma_iter->first, pragma_iter->second);
1761e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1771e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1781e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  DUMP_LIST_HEADER("RS object slots", mHeader.objectSlotList);
1791e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  for (ObjectSlotListTy::const_iterator slot_iter = mObjectSlots.begin(),
1801e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          slot_end = mObjectSlots.end(); slot_iter != slot_end; slot_iter++) {
1811e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGV("slot: %u", *slot_iter);
1821e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1831e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1841e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  DUMP_LIST_HEADER("RS export variables", mHeader.exportVarNameList);
1851e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  for (ExportVarNameListTy::const_iterator var_iter = mExportVarNames.begin(),
1861e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          var_end = mExportVarNames.end(); var_iter != var_end; var_iter++) {
1871e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGV("name: %s", *var_iter);
1881e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1891e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1901e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  DUMP_LIST_HEADER("RS export functions", mHeader.exportFuncNameList);
1911e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  for (ExportFuncNameListTy::const_iterator func_iter = mExportFuncNames.begin(),
1921e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        func_end = mExportFuncNames.end(); func_iter != func_end; func_iter++) {
1931e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGV("name: %s", *func_iter);
1941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  DUMP_LIST_HEADER("RS foreach list", mHeader.exportForeachFuncList);
1971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  for (ExportForeachFuncListTy::const_iterator
1981e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          foreach_iter = mExportForeachFuncs.begin(),
1991e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          foreach_end = mExportForeachFuncs.end(); foreach_iter != foreach_end;
2001e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          foreach_iter++) {
2011e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGV("name: %s, signature: %05x", foreach_iter->first,
2021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                                       foreach_iter->second);
2031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#undef DUMP_LIST_HEADER
2051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2061e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#endif // LOG_NDEBUG
2071e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return;
2081e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
2091e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changconst char *RSInfo::getStringFromPool(rsinfo::StringIndexTy pStrIdx) const {
2111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // String pool uses direct indexing. Ensure that the pStrIdx is within the
2121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // range.
2131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pStrIdx >= mHeader.strPoolSize) {
2141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("String index #%u is out of range in string pool (size: %u)!",
2151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          pStrIdx, mHeader.strPoolSize);
2161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return NULL;
2171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return &mStringPool[ pStrIdx ];
2191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
2201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2211e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changrsinfo::StringIndexTy RSInfo::getStringIdxInPool(const char *pStr) const {
2221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Assume we are on the flat memory architecture (i.e., the memory space is
2231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // continuous.)
2241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if ((mStringPool + mHeader.strPoolSize) < pStr) {
2251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("String %s does not in the string pool!", pStr);
2261e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return rsinfo::gInvalidStringIndex;
2271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2281e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return (pStr - mStringPool);
2291e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
2301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
231ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei LiaoRSInfo::FloatPrecision RSInfo::getFloatPrecisionRequirement() const {
2321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Check to see if we have any FP precision-related pragmas.
233688e4c0dd73c273551f517fa85a08b40dd63eaccStephen Hines  std::string relaxed_pragma("rs_fp_relaxed");
234688e4c0dd73c273551f517fa85a08b40dd63eaccStephen Hines  std::string imprecise_pragma("rs_fp_imprecise");
235688e4c0dd73c273551f517fa85a08b40dd63eaccStephen Hines  std::string full_pragma("rs_fp_full");
2361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  bool relaxed_pragma_seen = false;
237ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet  bool full_pragma_seen = false;
2381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  for (PragmaListTy::const_iterator pragma_iter = mPragmas.begin(),
2401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang           pragma_end = mPragmas.end(); pragma_iter != pragma_end;
2411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang       pragma_iter++) {
2421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const char *pragma_key = pragma_iter->first;
243688e4c0dd73c273551f517fa85a08b40dd63eaccStephen Hines    if (!relaxed_pragma.compare(pragma_key)) {
2441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      relaxed_pragma_seen = true;
245688e4c0dd73c273551f517fa85a08b40dd63eaccStephen Hines    } else if (!imprecise_pragma.compare(pragma_key)) {
246ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet      ALOGW("rs_fp_imprecise is deprecated.  Assuming rs_fp_relaxed instead.");
247ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet      relaxed_pragma_seen = true;
248ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet    } else if (!full_pragma.compare(pragma_key)) {
249ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet      full_pragma_seen = true;
2501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    }
2511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
253ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet  if (relaxed_pragma_seen && full_pragma_seen) {
254ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet    ALOGE("Full and relaxed precision specified at the same time!");
255ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao  }
256ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet  RSInfo::FloatPrecision result = relaxed_pragma_seen ? FP_Relaxed : FP_Full;
257ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao
258b81d697ec617be24494b622a3532f1c465264415Nick Kralevich#ifdef HAVE_ANDROID_OS
259ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao  // Provide an override for precsion via adb shell setprop
260ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao  // adb shell setprop debug.rs.precision rs_fp_full
261ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao  // adb shell setprop debug.rs.precision rs_fp_relaxed
262ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao  // adb shell setprop debug.rs.precision rs_fp_imprecise
263ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao  char precision_prop_buf[PROPERTY_VALUE_MAX];
264ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao  property_get("debug.rs.precision", precision_prop_buf, "");
265ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao
266ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao  if (precision_prop_buf[0]) {
267688e4c0dd73c273551f517fa85a08b40dd63eaccStephen Hines    if (!relaxed_pragma.compare(precision_prop_buf)) {
268ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao      ALOGI("Switching to RS FP relaxed mode via setprop");
269ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao      result = FP_Relaxed;
270688e4c0dd73c273551f517fa85a08b40dd63eaccStephen Hines    } else if (!imprecise_pragma.compare(precision_prop_buf)) {
271ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet      ALOGW("Switching to RS FP relaxed mode via setprop. rs_fp_imprecise was specified but is "
272ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet              "deprecated ");
273ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet      result = FP_Relaxed;
274688e4c0dd73c273551f517fa85a08b40dd63eaccStephen Hines    } else if (!full_pragma.compare(precision_prop_buf)) {
275ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao      ALOGI("Switching to RS FP full mode via setprop");
276ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao      result = FP_Full;
277ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet    } else {
278ef406964e2ba7e45d3a044d2fb459dce92569560Jean-Luc Brouillet      ALOGE("Unrecognized debug.rs.precision %s", precision_prop_buf);
279ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao    }
2801e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
281b81d697ec617be24494b622a3532f1c465264415Nick Kralevich#endif
282ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao
283ed7fffbc0e3fe3c5dced1248f6be52b6c95b513bShih-wei Liao  return result;
2841e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
285