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 //===----------------------------------------------------------------------===//
     18 // This file implements RSInfo::write()
     19 //===----------------------------------------------------------------------===//
     20 
     21 #include "bcc/Renderscript/RSInfo.h"
     22 
     23 #include "bcc/Support/Log.h"
     24 #include "bcc/Support/OutputFile.h"
     25 
     26 using namespace bcc;
     27 
     28 namespace {
     29 
     30 template<typename ItemType, typename ItemContainer> inline bool
     31 helper_adapt_list_item(ItemType &pResult, const RSInfo &pInfo,
     32                        const typename ItemContainer::const_iterator &pItem);
     33 
     34 template<> inline bool
     35 helper_adapt_list_item<rsinfo::DependencyTableItem, RSInfo::DependencyTableTy>(
     36     rsinfo::DependencyTableItem &pResult,
     37     const RSInfo &pInfo,
     38     const RSInfo::DependencyTableTy::const_iterator &pItem) {
     39   pResult.id = pInfo.getStringIdxInPool(pItem->first);
     40   pResult.sha1 =
     41       pInfo.getStringIdxInPool(reinterpret_cast<const char *>(pItem->second));
     42 
     43   if (pResult.id == rsinfo::gInvalidStringIndex) {
     44     ALOGE("RS dependency table contains invalid source id string '%s'.",
     45           pItem->first);
     46     return false;
     47   }
     48 
     49   if (pResult.sha1 == rsinfo::gInvalidStringIndex) {
     50     ALOGE("RS dependency table contains invalid SHA-1 checksum string in '%s'.",
     51           pItem->first);
     52     return false;
     53   }
     54 
     55   return true;
     56 }
     57 
     58 template<> inline bool
     59 helper_adapt_list_item<rsinfo::PragmaItem, RSInfo::PragmaListTy>(
     60     rsinfo::PragmaItem &pResult,
     61     const RSInfo &pInfo,
     62     const RSInfo::PragmaListTy::const_iterator &pItem) {
     63   pResult.key = pInfo.getStringIdxInPool(pItem->first);
     64   pResult.value = pInfo.getStringIdxInPool(pItem->second);
     65 
     66   if (pResult.key == rsinfo::gInvalidStringIndex) {
     67     ALOGE("RS pragma list contains invalid string '%s' for key.", pItem->first);
     68     return false;
     69   }
     70 
     71   if (pResult.value == rsinfo::gInvalidStringIndex) {
     72     ALOGE("RS pragma list contains invalid string '%s' for value.",
     73           pItem->second);
     74     return false;
     75   }
     76 
     77   return true;
     78 }
     79 
     80 template<> inline bool
     81 helper_adapt_list_item<rsinfo::ObjectSlotItem, RSInfo::ObjectSlotListTy>(
     82     rsinfo::ObjectSlotItem &pResult,
     83     const RSInfo &pInfo,
     84     const RSInfo::ObjectSlotListTy::const_iterator &pItem) {
     85   pResult.slot = *pItem;
     86   return true;
     87 }
     88 
     89 template<> inline bool
     90 helper_adapt_list_item<rsinfo::ExportVarNameItem, RSInfo::ExportVarNameListTy>(
     91     rsinfo::ExportVarNameItem &pResult,
     92     const RSInfo &pInfo,
     93     const RSInfo::ExportVarNameListTy::const_iterator &pItem) {
     94   pResult.name = pInfo.getStringIdxInPool(*pItem);
     95 
     96   if (pResult.name == rsinfo::gInvalidStringIndex) {
     97     ALOGE("RS export vars contains invalid string '%s' for name.", *pItem);
     98     return false;
     99   }
    100 
    101   return true;
    102 }
    103 
    104 template<> inline bool
    105 helper_adapt_list_item<rsinfo::ExportFuncNameItem,
    106                        RSInfo::ExportFuncNameListTy>(
    107     rsinfo::ExportFuncNameItem &pResult,
    108     const RSInfo &pInfo,
    109     const RSInfo::ExportFuncNameListTy::const_iterator &pItem) {
    110   pResult.name = pInfo.getStringIdxInPool(*pItem);
    111 
    112   if (pResult.name == rsinfo::gInvalidStringIndex) {
    113     ALOGE("RS export funcs contains invalid string '%s' for name.", *pItem);
    114     return false;
    115   }
    116 
    117   return true;
    118 }
    119 
    120 template<> inline bool
    121 helper_adapt_list_item<rsinfo::ExportForeachFuncItem,
    122                        RSInfo::ExportForeachFuncListTy>(
    123     rsinfo::ExportForeachFuncItem &pResult,
    124     const RSInfo &pInfo,
    125     const RSInfo::ExportForeachFuncListTy::const_iterator &pItem) {
    126   pResult.name = pInfo.getStringIdxInPool(pItem->first);
    127   pResult.signature = pItem->second;
    128 
    129   if (pResult.name == rsinfo::gInvalidStringIndex) {
    130     ALOGE("RS export foreach contains invalid string '%s' for name.",
    131           pItem->first);
    132     return false;
    133   }
    134 
    135   return true;
    136 }
    137 
    138 template<typename ItemType, typename ItemContainer>
    139 inline bool helper_write_list(OutputFile &pOutput,
    140                               const RSInfo &pInfo,
    141                               const rsinfo::ListHeader &pHeader,
    142                               ItemContainer &pList) {
    143   ItemType item;
    144 
    145   for (typename ItemContainer::const_iterator item_iter = pList.begin(),
    146           item_end = pList.end(); item_iter != item_end; item_iter++) {
    147     // Convert each entry in the pList to ItemType.
    148     if (!helper_adapt_list_item<ItemType, ItemContainer>(item,
    149                                                          pInfo,
    150                                                          item_iter)) {
    151       return false;
    152     }
    153     // And write out an item.
    154     if (pOutput.write(&item, sizeof(item)) != sizeof(item)) {
    155       ALOGE("Cannot write out item of %s for RSInfo file %s! (%s)",
    156             rsinfo::GetItemTypeName<ItemType>(), pOutput.getName().c_str(),
    157             pOutput.getErrorMessage().c_str());
    158       return false;
    159     }
    160   }
    161 
    162   return true;
    163 }
    164 
    165 } // end anonymous namespace
    166 
    167 bool RSInfo::write(OutputFile &pOutput) {
    168   off_t initial_offset = pOutput.tell();
    169   const char *output_filename = pOutput.getName().c_str();
    170 
    171   if (pOutput.hasError()) {
    172     ALOGE("Invalid RS info file %s for output! (%s)",
    173           output_filename, pOutput.getErrorMessage().c_str());
    174     return false;
    175   }
    176 
    177   // Layout.
    178   if (!layout(initial_offset)) {
    179     return false;
    180   }
    181 
    182   // Write header.
    183   if (pOutput.write(&mHeader, sizeof(mHeader)) != sizeof(mHeader)) {
    184     ALOGE("Cannot write out the header for RSInfo file %s! (%s)",
    185           output_filename, pOutput.getErrorMessage().c_str());
    186     return false;
    187   }
    188 
    189   // Write string pool.
    190   if (static_cast<size_t>(pOutput.write(mStringPool, mHeader.strPoolSize))
    191           != mHeader.strPoolSize) {
    192     ALOGE("Cannot write out the string pool for RSInfo file %s! (%s)",
    193           output_filename, pOutput.getErrorMessage().c_str());
    194     return false;
    195   }
    196 
    197   // Write dependencyTable.
    198   if (!helper_write_list<rsinfo::DependencyTableItem, DependencyTableTy>
    199         (pOutput, *this, mHeader.dependencyTable, mDependencyTable)) {
    200     return false;
    201   }
    202 
    203   // Write pragmaList.
    204   if (!helper_write_list<rsinfo::PragmaItem, PragmaListTy>
    205         (pOutput, *this, mHeader.pragmaList, mPragmas)) {
    206     return false;
    207   }
    208 
    209   // Write objectSlotList.
    210   if (!helper_write_list<rsinfo::ObjectSlotItem, ObjectSlotListTy>
    211         (pOutput, *this, mHeader.objectSlotList, mObjectSlots)) {
    212     return false;
    213   }
    214 
    215   // Write exportVarNameList.
    216   if (!helper_write_list<rsinfo::ExportVarNameItem, ExportVarNameListTy>
    217         (pOutput, *this, mHeader.exportVarNameList, mExportVarNames)) {
    218     return false;
    219   }
    220 
    221   // Write exportFuncNameList.
    222   if (!helper_write_list<rsinfo::ExportFuncNameItem, ExportFuncNameListTy>
    223         (pOutput, *this, mHeader.exportFuncNameList, mExportFuncNames)) {
    224     return false;
    225   }
    226 
    227   // Write exportForeachFuncList.
    228   if (!helper_write_list<rsinfo::ExportForeachFuncItem, ExportForeachFuncListTy>
    229         (pOutput, *this, mHeader.exportForeachFuncList, mExportForeachFuncs)) {
    230     return false;
    231   }
    232 
    233   return true;
    234 }
    235