Home | History | Annotate | Download | only in Renderscript
      1 /*
      2  * Copyright 2012, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef BCC_RS_INFO_H
     18 #define BCC_RS_INFO_H
     19 
     20 #include <stdint.h>
     21 
     22 #include <utility>
     23 
     24 #include "bcc/Renderscript/RSScript.h"
     25 #include "bcc/Support/Log.h"
     26 #include "bcc/Support/Sha1Util.h"
     27 
     28 #include <utils/String8.h>
     29 #include <utils/Vector.h>
     30 
     31 namespace bcc {
     32 
     33 // Forward declarations
     34 class FileBase;
     35 class InputFile;
     36 class OutputFile;
     37 class Source;
     38 
     39 namespace rsinfo {
     40 
     41 /* RS info file magic */
     42 #define RSINFO_MAGIC      "\0rsinfo\n"
     43 
     44 /* RS info file version, encoded in 4 bytes of ASCII */
     45 #define RSINFO_VERSION    "004\0"
     46 
     47 struct __attribute__((packed)) ListHeader {
     48   // The offset from the beginning of the file of data
     49   uint32_t offset;
     50   // Number of item in the list
     51   uint32_t count;
     52   // Size of each item
     53   uint8_t itemSize;
     54 };
     55 
     56 /* RS info file header */
     57 struct __attribute__((packed)) Header {
     58   // Magic versus version
     59   uint8_t magic[8];
     60   uint8_t version[4];
     61 
     62   uint8_t isThreadable;
     63   uint8_t hasDebugInformation;
     64 
     65   uint16_t headerSize;
     66 
     67   uint32_t strPoolSize;
     68 
     69   struct ListHeader dependencyTable;
     70   struct ListHeader pragmaList;
     71   struct ListHeader objectSlotList;
     72   struct ListHeader exportVarNameList;
     73   struct ListHeader exportFuncNameList;
     74   struct ListHeader exportForeachFuncList;
     75 };
     76 
     77 typedef uint32_t StringIndexTy;
     78 // Use value -1 as an invalid string index marker. No need to declare with
     79 // 'static' modifier since 'const' variable has internal linkage by default.
     80 const StringIndexTy gInvalidStringIndex = static_cast<StringIndexTy>(-1);
     81 
     82 struct __attribute__((packed)) DependencyTableItem {
     83   StringIndexTy id;
     84   // SHA-1 checksum is stored as a string in string pool (and has fixed-length
     85   // SHA1_DIGEST_LENGTH (=20) bytes)
     86   StringIndexTy sha1;
     87 };
     88 
     89 struct __attribute__((packed)) PragmaItem {
     90   // Pragma is a key-value pair.
     91   StringIndexTy key;
     92   StringIndexTy value;
     93 };
     94 
     95 struct __attribute__((packed)) ObjectSlotItem {
     96   uint32_t slot;
     97 };
     98 
     99 struct __attribute__((packed)) ExportVarNameItem {
    100   StringIndexTy name;
    101 };
    102 
    103 struct __attribute__((packed)) ExportFuncNameItem {
    104   StringIndexTy name;
    105 };
    106 
    107 struct __attribute__((packed)) ExportForeachFuncItem {
    108   StringIndexTy name;
    109   uint32_t signature;
    110 };
    111 
    112 // Return the human-readable name of the given rsinfo::*Item in the template
    113 // parameter. This is for debugging and error message.
    114 template<typename Item>
    115 inline const char *GetItemTypeName();
    116 
    117 template<>
    118 inline const char *GetItemTypeName<DependencyTableItem>()
    119 { return "rs dependency info"; }
    120 
    121 template<>
    122 inline const char *GetItemTypeName<PragmaItem>()
    123 {  return "rs pragma"; }
    124 
    125 template<>
    126 inline const char *GetItemTypeName<ObjectSlotItem>()
    127 {  return "rs object slot"; }
    128 
    129 template<>
    130 inline const char *GetItemTypeName<ExportVarNameItem>()
    131 { return "rs export var"; }
    132 
    133 template<>
    134 inline const char *GetItemTypeName<ExportFuncNameItem>()
    135 {  return "rs export func"; }
    136 
    137 template<>
    138 inline const char *GetItemTypeName<ExportForeachFuncItem>()
    139 { return "rs export foreach"; }
    140 
    141 } // end namespace rsinfo
    142 
    143 class RSInfo {
    144 public:
    145   typedef android::Vector<std::pair<const char *,
    146                                     const uint8_t *> > DependencyTableTy;
    147   typedef android::Vector<std::pair<const char*, const char*> > PragmaListTy;
    148   typedef android::Vector<uint32_t> ObjectSlotListTy;
    149   typedef android::Vector<const char *> ExportVarNameListTy;
    150   typedef android::Vector<const char *> ExportFuncNameListTy;
    151   typedef android::Vector<std::pair<const char *,
    152                                     uint32_t> > ExportForeachFuncListTy;
    153 
    154 public:
    155   // Calculate or load the SHA-1 information of the built-in dependencies.
    156   static bool LoadBuiltInSHA1Information();
    157 
    158   // Return the path of the RS info file corresponded to the given output
    159   // executable file.
    160   static android::String8 GetPath(const FileBase &pFile);
    161 
    162   static const char LibBCCPath[];
    163   static const char LibCompilerRTPath[];
    164   static const char LibRSPath[];
    165   static const char LibCLCorePath[];
    166   static const char LibCLCoreDebugPath[];
    167 #if defined(ARCH_X86_HAVE_SSE2)
    168   static const char LibCLCoreX86Path[];
    169 #endif
    170 #if defined(ARCH_ARM_HAVE_NEON)
    171   static const char LibCLCoreNEONPath[];
    172 #endif
    173 
    174 private:
    175   // SHA-1 of the built-in dependencies. Will be initialized in
    176   // LoadBuiltInSHA1Information().
    177   static const uint8_t *LibBCCSHA1;
    178   static const uint8_t *LibCompilerRTSHA1;
    179   static const uint8_t *LibRSSHA1;
    180   static const uint8_t *LibCLCoreSHA1;
    181   static const uint8_t *LibCLCoreDebugSHA1;
    182 #if defined(ARCH_ARM_HAVE_NEON)
    183   static const uint8_t *LibCLCoreNEONSHA1;
    184 #endif
    185 
    186   static bool CheckDependency(const RSInfo &pInfo,
    187                               const char *pInputFilename,
    188                               const DependencyTableTy &pDeps);
    189   static bool AddBuiltInDependencies(RSInfo &pInfo);
    190 
    191   rsinfo::Header mHeader;
    192 
    193   char *mStringPool;
    194 
    195   // In most of the time, there're 4 source dependencies stored (libbcc.so,
    196   // libRS.so, libclcore and the input bitcode itself.)
    197   DependencyTableTy mDependencyTable;
    198   PragmaListTy mPragmas;
    199   ObjectSlotListTy mObjectSlots;
    200   ExportVarNameListTy mExportVarNames;
    201   ExportFuncNameListTy mExportFuncNames;
    202   ExportForeachFuncListTy mExportForeachFuncs;
    203 
    204   // Initialize an empty RSInfo with its size of string pool is pStringPoolSize.
    205   RSInfo(size_t pStringPoolSize);
    206 
    207   // layout() assigns value of offset in each ListHeader (i.e., it decides where
    208   // data should go in the file.) It also updates fields other than offset to
    209   // reflect the current RSInfo object states to mHeader.
    210   bool layout(off_t initial_offset);
    211 
    212 public:
    213   ~RSInfo();
    214 
    215   // Implemented in RSInfoExtractor.cpp.
    216   static RSInfo *ExtractFromSource(const Source &pSource,
    217                                    const DependencyTableTy &pDeps);
    218 
    219   // Implemented in RSInfoReader.cpp.
    220   static RSInfo *ReadFromFile(InputFile &pInput,
    221                               const DependencyTableTy &pDeps);
    222 
    223   // Implemneted in RSInfoWriter.cpp
    224   bool write(OutputFile &pOutput);
    225 
    226   void dump() const;
    227 
    228   // const getter
    229   inline bool isThreadable() const
    230   { return mHeader.isThreadable; }
    231   inline bool hasDebugInformation() const
    232   { return mHeader.hasDebugInformation; }
    233   inline const DependencyTableTy &getDependencyTable() const
    234   { return mDependencyTable; }
    235   inline const PragmaListTy &getPragmas() const
    236   { return mPragmas; }
    237   inline const ObjectSlotListTy &getObjectSlots() const
    238   { return mObjectSlots; }
    239   inline const ExportVarNameListTy &getExportVarNames() const
    240   { return mExportVarNames; }
    241   inline const ExportFuncNameListTy &getExportFuncNames() const
    242   { return mExportFuncNames; }
    243   inline const ExportForeachFuncListTy &getExportForeachFuncs() const
    244   { return mExportForeachFuncs; }
    245 
    246   const char *getStringFromPool(rsinfo::StringIndexTy pStrIdx) const;
    247   rsinfo::StringIndexTy getStringIdxInPool(const char *pStr) const;
    248 
    249   // setter
    250   inline void setThreadable(bool pThreadable = true)
    251   { mHeader.isThreadable = pThreadable; }
    252 
    253 public:
    254   enum FloatPrecision {
    255     FP_Full,
    256     FP_Relaxed,
    257     FP_Imprecise,
    258   };
    259 
    260   // Return the minimal floating point precision required for the associated
    261   // script.
    262   FloatPrecision getFloatPrecisionRequirement() const;
    263 };
    264 
    265 } // end namespace bcc
    266 
    267 #endif  // BCC_RS_INFO_H
    268