/*
* Copyright 2012, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BCC_RS_INFO_H
#define BCC_RS_INFO_H
#include <stdint.h>
#include <utility>
#include "bcc/Renderscript/RSScript.h"
#include "bcc/Support/Log.h"
#include "bcc/Support/Sha1Util.h"
#include <utils/String8.h>
#include <utils/Vector.h>
namespace bcc {
// Forward declarations
class FileBase;
class InputFile;
class OutputFile;
class Source;
namespace rsinfo {
/* RS info file magic */
#define RSINFO_MAGIC "\0rsinfo\n"
/* RS info file version, encoded in 4 bytes of ASCII */
#define RSINFO_VERSION "003\0"
struct __attribute__((packed)) ListHeader {
// The offset from the beginning of the file of data
uint32_t offset;
// Number of item in the list
uint32_t count;
// Size of each item
uint8_t itemSize;
};
/* RS info file header */
struct __attribute__((packed)) Header {
// Magic versus version
uint8_t magic[8];
uint8_t version[4];
uint8_t isThreadable;
uint8_t hasDebugInformation;
uint16_t headerSize;
uint32_t strPoolSize;
struct ListHeader dependencyTable;
struct ListHeader pragmaList;
struct ListHeader objectSlotList;
struct ListHeader exportVarNameList;
struct ListHeader exportFuncNameList;
struct ListHeader exportForeachFuncList;
};
typedef uint32_t StringIndexTy;
// Use value -1 as an invalid string index marker. No need to declare with
// 'static' modifier since 'const' variable has internal linkage by default.
const StringIndexTy gInvalidStringIndex = static_cast<StringIndexTy>(-1);
struct __attribute__((packed)) DependencyTableItem {
StringIndexTy id;
// SHA-1 checksum is stored as a string in string pool (and has fixed-length
// SHA1_DIGEST_LENGTH (=20) bytes)
StringIndexTy sha1;
};
struct __attribute__((packed)) PragmaItem {
// Pragma is a key-value pair.
StringIndexTy key;
StringIndexTy value;
};
struct __attribute__((packed)) ObjectSlotItem {
uint32_t slot;
};
struct __attribute__((packed)) ExportVarNameItem {
StringIndexTy name;
};
struct __attribute__((packed)) ExportFuncNameItem {
StringIndexTy name;
};
struct __attribute__((packed)) ExportForeachFuncItem {
StringIndexTy name;
uint32_t signature;
};
// Return the human-readable name of the given rsinfo::*Item in the template
// parameter. This is for debugging and error message.
template<typename Item>
inline const char *GetItemTypeName();
template<>
inline const char *GetItemTypeName<DependencyTableItem>()
{ return "rs dependency info"; }
template<>
inline const char *GetItemTypeName<PragmaItem>()
{ return "rs pragma"; }
template<>
inline const char *GetItemTypeName<ObjectSlotItem>()
{ return "rs object slot"; }
template<>
inline const char *GetItemTypeName<ExportVarNameItem>()
{ return "rs export var"; }
template<>
inline const char *GetItemTypeName<ExportFuncNameItem>()
{ return "rs export func"; }
template<>
inline const char *GetItemTypeName<ExportForeachFuncItem>()
{ return "rs export foreach"; }
} // end namespace rsinfo
class RSInfo {
public:
typedef android::Vector<std::pair<const char *,
const uint8_t *> > DependencyTableTy;
typedef android::Vector<std::pair<const char*, const char*> > PragmaListTy;
typedef android::Vector<uint32_t> ObjectSlotListTy;
typedef android::Vector<const char *> ExportVarNameListTy;
typedef android::Vector<const char *> ExportFuncNameListTy;
typedef android::Vector<std::pair<const char *,
uint32_t> > ExportForeachFuncListTy;
public:
// Calculate or load the SHA-1 information of the built-in dependencies.
static void LoadBuiltInSHA1Information();
// Return the path of the RS info file corresponded to the given output
// executable file.
static android::String8 GetPath(const FileBase &pFile);
static const char LibBCCPath[];
static const char LibRSPath[];
static const char LibCLCorePath[];
#if defined(ARCH_ARM_HAVE_NEON)
static const char LibCLCoreNEONPath[];
#endif
private:
// SHA-1 of the built-in dependencies. Will be initialized in
// LoadBuiltInSHA1Information().
static const uint8_t *LibBCCSHA1;
static const uint8_t *LibRSSHA1;
static const uint8_t *LibCLCoreSHA1;
#if defined(ARCH_ARM_HAVE_NEON)
static const uint8_t *LibCLCoreNEONSHA1;
#endif
static bool CheckDependency(const RSInfo &pInfo,
const char *pInputFilename,
const DependencyTableTy &pDeps);
static bool AddBuiltInDependencies(RSInfo &pInfo);
rsinfo::Header mHeader;
char *mStringPool;
// In most of the time, there're 4 source dependencies stored (libbcc.so,
// libRS.so, libclcore and the input bitcode itself.)
DependencyTableTy mDependencyTable;
PragmaListTy mPragmas;
ObjectSlotListTy mObjectSlots;
ExportVarNameListTy mExportVarNames;
ExportFuncNameListTy mExportFuncNames;
ExportForeachFuncListTy mExportForeachFuncs;
// Initialize an empty RSInfo with its size of string pool is pStringPoolSize.
RSInfo(size_t pStringPoolSize);
// layout() assigns value of offset in each ListHeader (i.e., it decides where
// data should go in the file.) It also updates fields other than offset to
// reflect the current RSInfo object states to mHeader.
bool layout(off_t initial_offset);
public:
~RSInfo();
// Implemented in RSInfoExtractor.cpp.
static RSInfo *ExtractFromSource(const Source &pSource,
const DependencyTableTy &pDeps);
// Implemented in RSInfoReader.cpp.
static RSInfo *ReadFromFile(InputFile &pInput,
const DependencyTableTy &pDeps);
// Implemneted in RSInfoWriter.cpp
bool write(OutputFile &pOutput);
void dump() const;
// const getter
inline bool isThreadable() const
{ return mHeader.isThreadable; }
inline bool hasDebugInformation() const
{ return mHeader.hasDebugInformation; }
inline const DependencyTableTy &getDependencyTable() const
{ return mDependencyTable; }
inline const PragmaListTy &getPragmas() const
{ return mPragmas; }
inline const ObjectSlotListTy &getObjectSlots() const
{ return mObjectSlots; }
inline const ExportVarNameListTy &getExportVarNames() const
{ return mExportVarNames; }
inline const ExportFuncNameListTy &getExportFuncNames() const
{ return mExportFuncNames; }
inline const ExportForeachFuncListTy &getExportForeachFuncs() const
{ return mExportForeachFuncs; }
const char *getStringFromPool(rsinfo::StringIndexTy pStrIdx) const;
rsinfo::StringIndexTy getStringIdxInPool(const char *pStr) const;
// setter
inline void setThreadable(bool pThreadable = true)
{ mHeader.isThreadable = pThreadable; }
public:
enum FloatPrecision {
FP_Full,
FP_Relaxed,
FP_Imprecise,
};
// Return the minimal floating point precision required for the associated
// script.
FloatPrecision getFloatPrecisionRequirement() const;
};
} // end namespace bcc
#endif // BCC_RS_INFO_H