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