RSInfo.h revision 8ee82d4c1dded958f27f0dc51ddeceda0c895d99
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
31namespace bcc {
32
33// Forward declarations
34class FileBase;
35class InputFile;
36class OutputFile;
37class Source;
38
39namespace 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
47struct __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 */
57struct __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
77typedef 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.
80const StringIndexTy gInvalidStringIndex = static_cast<StringIndexTy>(-1);
81
82struct __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
89struct __attribute__((packed)) PragmaItem {
90  // Pragma is a key-value pair.
91  StringIndexTy key;
92  StringIndexTy value;
93};
94
95struct __attribute__((packed)) ObjectSlotItem {
96  uint32_t slot;
97};
98
99struct __attribute__((packed)) ExportVarNameItem {
100  StringIndexTy name;
101};
102
103struct __attribute__((packed)) ExportFuncNameItem {
104  StringIndexTy name;
105};
106
107struct __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.
114template<typename Item>
115inline const char *GetItemTypeName();
116
117template<>
118inline const char *GetItemTypeName<DependencyTableItem>()
119{ return "rs dependency info"; }
120
121template<>
122inline const char *GetItemTypeName<PragmaItem>()
123{  return "rs pragma"; }
124
125template<>
126inline const char *GetItemTypeName<ObjectSlotItem>()
127{  return "rs object slot"; }
128
129template<>
130inline const char *GetItemTypeName<ExportVarNameItem>()
131{ return "rs export var"; }
132
133template<>
134inline const char *GetItemTypeName<ExportFuncNameItem>()
135{  return "rs export func"; }
136
137template<>
138inline const char *GetItemTypeName<ExportForeachFuncItem>()
139{ return "rs export foreach"; }
140
141} // end namespace rsinfo
142
143class RSInfo {
144public:
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
154public:
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
174private:
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
212public:
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
253public:
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