slang_rs_reflection_cpp.cpp revision 192392fc5ffedc06eb8ae2b89d703b3c658fddd6
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#include <sys/stat.h> 18#include <stdio.h> 19#include <stdlib.h> 20 21#include <cstdarg> 22#include <cctype> 23 24#include <algorithm> 25#include <sstream> 26#include <string> 27#include <utility> 28 29#include "os_sep.h" 30#include "slang_rs_context.h" 31#include "slang_rs_export_var.h" 32#include "slang_rs_export_foreach.h" 33#include "slang_rs_export_func.h" 34#include "slang_rs_reflect_utils.h" 35#include "slang_version.h" 36#include "slang_utils.h" 37 38#include "slang_rs_reflection_cpp.h" 39 40using namespace std; 41 42namespace slang { 43 44RSReflectionCpp::RSReflectionCpp(const RSContext *con) : 45 RSReflectionBase(con) { 46 47} 48 49RSReflectionCpp::~RSReflectionCpp() { 50 51} 52 53bool RSReflectionCpp::reflect(const string &OutputPathBase, 54 const string &InputFileName, 55 const string &OutputBCFileName) { 56 mInputFileName = InputFileName; 57 mOutputPath = OutputPathBase; 58 mOutputBCFileName = OutputBCFileName; 59 mClassName = string("ScriptC_") + stripRS(InputFileName); 60 61 makeHeader("ScriptC"); 62 std::vector< std::string > header(mText); 63 mText.clear(); 64 65 makeImpl("ScriptC"); 66 std::vector< std::string > cpp(mText); 67 mText.clear(); 68 69 70 RSReflectionBase::writeFile(mClassName + ".h", header); 71 RSReflectionBase::writeFile(mClassName + ".cpp", cpp); 72 73 74 return false; 75} 76 77typedef std::vector<std::pair<std::string, std::string> > ArgTy; 78 79 80#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_" 81 82 83 84bool RSReflectionCpp::makeHeader(const std::string &baseClass) { 85 startFile(mClassName + ".h"); 86 87 write(""); 88 write("#include \"ScriptC.h\""); 89 write(""); 90 91 // Imports 92 //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++) 93 //out() << "import " << Import[i] << ";" << std::endl; 94 //out() << std::endl; 95 96 if(!baseClass.empty()) { 97 write("class " + mClassName + " : protected " + baseClass + " {"); 98 } else { 99 write("class " + mClassName + " {"); 100 } 101 102 write("private:"); 103 uint32_t slot = 0; 104 incIndent(); 105 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 106 E = mRSContext->export_vars_end(); I != E; I++, slot++) { 107 108 const RSExportVar *ev = *I; 109 RSReflectionTypeData rtd; 110 ev->getType()->convertToRTD(&rtd); 111 if(!ev->isConst()) { 112 write(string(rtd.type->c_name) + " __" + ev->getName() + ";"); 113 } 114 } 115 decIndent(); 116 117 write("public:"); 118 incIndent(); 119 write(mClassName + "(RenderScript *rs, const char *cacheDir, size_t cacheDirLength);"); 120 write("virtual ~" + mClassName + "();"); 121 write(""); 122 123 124 // Reflect export variable 125 slot = 0; 126 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 127 E = mRSContext->export_vars_end(); I != E; I++, slot++) { 128 129 const RSExportVar *ev = *I; 130 RSReflectionTypeData rtd; 131 ev->getType()->convertToRTD(&rtd); 132 133 if(!ev->isConst()) { 134 write(string("void set_") + ev->getName() + "(" + rtd.type->c_name + " v) {"); 135 stringstream tmp; 136 tmp << slot; 137 write(string(" setVar(") + tmp.str() + ", v);"); 138 write(string(" __") + ev->getName() + " = v;"); 139 write("}"); 140 } 141 write(string(rtd.type->c_name) + " get_" + ev->getName() + "() const {"); 142 if(ev->isConst()) { 143 const clang::APValue &val = ev->getInit(); 144 bool isBool = !strcmp(rtd.type->c_name, "bool"); 145 write(string(" return ") + genInitValue(val, isBool) + ";"); 146 } else { 147 write(string(" return __") + ev->getName() + ";"); 148 } 149 write("}"); 150 write(""); 151 } 152 153 // Reflect export for each functions 154 for (RSContext::const_export_foreach_iterator I = mRSContext->export_foreach_begin(), 155 E = mRSContext->export_foreach_end(); I != E; I++) { 156 157 const RSExportForEach *ef = *I; 158 if (ef->isDummyRoot()) { 159 write("// No forEach_root(...)"); 160 continue; 161 } 162 163 stringstream tmp; 164 tmp << "void forEach_" << ef->getName() << "("; 165 if(ef->hasIn() && ef->hasOut()) { 166 tmp << "const Allocation *ain, const Allocation *aout"; 167 } else if(ef->hasIn()) { 168 tmp << "const Allocation *ain"; 169 } else { 170 tmp << "const Allocation *aout"; 171 } 172 173 if(ef->getParamPacketType()) { 174 for(RSExportForEach::const_param_iterator i = ef->params_begin(), 175 e = ef->params_end(); i != e; i++) { 176 177 RSReflectionTypeData rtd; 178 (*i)->getType()->convertToRTD(&rtd); 179 tmp << rtd.type->c_name << " " << (*i)->getName(); 180 } 181 } 182 tmp << ") const;"; 183 write(tmp); 184 } 185 186 187 // Reflect export function 188 for (RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(), 189 E = mRSContext->export_funcs_end(); I != E; I++) { 190 191 //genExportFunction(C, *I); 192 } 193 194 decIndent(); 195 write("};"); 196 return true; 197} 198 199bool RSReflectionCpp::writeBC() { 200 FILE *pfin = fopen(mOutputBCFileName.c_str(), "rb"); 201 if (pfin == NULL) { 202 fprintf(stderr, "Error: could not read file %s\n", mOutputBCFileName.c_str()); 203 return false; 204 } 205 206 unsigned char buf[16]; 207 int read_length; 208 write("static const unsigned char __txt[] = {"); 209 incIndent(); 210 while ((read_length = fread(buf, 1, sizeof(buf), pfin)) > 0) { 211 string s; 212 for(int i = 0; i < read_length; i++) { 213 char buf2[16]; 214 sprintf(buf2, "0x%02x,", buf[i]); 215 s += buf2; 216 } 217 write(s); 218 } 219 decIndent(); 220 write("};"); 221 write(""); 222 return true; 223} 224 225bool RSReflectionCpp::makeImpl(const std::string &baseClass) { 226 startFile(mClassName + ".h"); 227 228 write(""); 229 write("#include \"" + mClassName + ".h\""); 230 write(""); 231 232 writeBC(); 233 234 // Imports 235 //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++) 236 //out() << "import " << Import[i] << ";" << std::endl; 237 //out() << std::endl; 238 239 write(mClassName + "::" + mClassName + 240 "(RenderScript *rs, const char *cacheDir, size_t cacheDirLength) :"); 241 write(" ScriptC(rs, __txt, sizeof(__txt), \"" + mInputFileName + 242 "\", 4, cacheDir, cacheDirLength) {"); 243 incIndent(); 244 //... 245 decIndent(); 246 write("}"); 247 write(""); 248 249 write(mClassName + "::~" + mClassName + "() {"); 250 write("}"); 251 write(""); 252 253 // Reflect export for each functions 254 uint32_t slot = 0; 255 for (RSContext::const_export_foreach_iterator I = mRSContext->export_foreach_begin(), 256 E = mRSContext->export_foreach_end(); I != E; I++, slot++) { 257 258 const RSExportForEach *ef = *I; 259 if (ef->isDummyRoot()) { 260 write("// No forEach_root(...)"); 261 continue; 262 } 263 264 stringstream tmp; 265 tmp << "void " << mClassName << "::forEach_" << ef->getName() << "("; 266 if(ef->hasIn() && ef->hasOut()) { 267 tmp << "const Allocation *ain, const Allocation *aout"; 268 } else if(ef->hasIn()) { 269 tmp << "const Allocation *ain"; 270 } else { 271 tmp << "const Allocation *aout"; 272 } 273 tmp << ") const {"; 274 write(tmp); 275 tmp.str(""); 276 277 tmp << " forEach(" << slot << ", "; 278 if(ef->hasIn() && ef->hasOut()) { 279 tmp << "ain, aout, NULL, 0);"; 280 } else if(ef->hasIn()) { 281 tmp << "ain, NULL, 0);"; 282 } else { 283 tmp << "aout, NULL, 0);"; 284 } 285 write(tmp); 286 287 write("}"); 288 write(""); 289 } 290 291 292 // Reflect export function 293 slot = 0; 294 for (RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(), 295 E = mRSContext->export_funcs_end(); I != E; I++) { 296 297 //genExportFunction(C, *I); 298 } 299 300 decIndent(); 301 return true; 302} 303 304 305 306} 307