blob: c79d008cb3f5f03aabbd57f9f0c585a93e1551fe [file] [log] [blame]
Jason Samsa5597fc2009-07-08 18:01:53 -07001
2/*
3 * Copyright (C) 2009 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include "rsContext.h"
Jason Samsa5597fc2009-07-08 18:01:53 -070019#include "rsFileA3D.h"
20
21#include "rsMesh.h"
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070022#include "rsAnimation.h"
Alex Sakhartchouke23d2392012-03-09 09:24:39 -080023#include "rs.h"
Alex Sakhartchoukd3e0ad42010-06-24 17:15:34 -070024
Jason Samsa6ab26a2012-03-28 17:44:21 -070025#if !defined(__RS_PDK__)
26 #include <androidfw/Asset.h>
27#endif
28
Jason Samsa5597fc2009-07-08 18:01:53 -070029using namespace android;
30using namespace android::renderscript;
31
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080032FileA3D::FileA3D(Context *rsc) : ObjectBase(rsc) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070033 mAlloc = NULL;
34 mData = NULL;
35 mWriteStream = NULL;
36 mReadStream = NULL;
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080037 mAsset = NULL;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070038
39 mMajorVersion = 0;
40 mMinorVersion = 1;
41 mDataSize = 0;
Jason Samsa5597fc2009-07-08 18:01:53 -070042}
43
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080044FileA3D::~FileA3D() {
45 for (size_t i = 0; i < mIndex.size(); i ++) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070046 delete mIndex[i];
47 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080048 for (size_t i = 0; i < mWriteIndex.size(); i ++) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070049 delete mWriteIndex[i];
50 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080051 if (mWriteStream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070052 delete mWriteStream;
53 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080054 if (mReadStream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070055 delete mWriteStream;
56 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080057 if (mAlloc) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070058 free(mAlloc);
59 }
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080060 if (mAsset) {
Jason Samsa6ab26a2012-03-28 17:44:21 -070061#if !defined(__RS_PDK__)
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080062 delete mAsset;
Jason Samsa6ab26a2012-03-28 17:44:21 -070063#endif
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080064 }
Jason Samsa5597fc2009-07-08 18:01:53 -070065}
66
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080067void FileA3D::parseHeader(IStream *headerStream) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070068 mMajorVersion = headerStream->loadU32();
69 mMinorVersion = headerStream->loadU32();
70 uint32_t flags = headerStream->loadU32();
71 mUse64BitOffsets = (flags & 1) != 0;
72
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070073 uint32_t numIndexEntries = headerStream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080074 for (uint32_t i = 0; i < numIndexEntries; i ++) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070075 A3DIndexEntry *entry = new A3DIndexEntry();
76 headerStream->loadString(&entry->mObjectName);
Steve Block65982012011-10-20 11:56:00 +010077 //ALOGV("Header data, entry name = %s", entry->mObjectName.string());
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070078 entry->mType = (RsA3DClassID)headerStream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080079 if (mUse64BitOffsets){
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070080 entry->mOffset = headerStream->loadOffset();
81 entry->mLength = headerStream->loadOffset();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080082 } else {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070083 entry->mOffset = headerStream->loadU32();
84 entry->mLength = headerStream->loadU32();
85 }
86 entry->mRsObj = NULL;
87 mIndex.push(entry);
88 }
89}
90
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080091bool FileA3D::load(Asset *asset) {
Jason Samsa6ab26a2012-03-28 17:44:21 -070092#if !defined(__RS_PDK__)
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080093 mAsset = asset;
94 return load(asset->getBuffer(false), asset->getLength());
Jason Samsa6ab26a2012-03-28 17:44:21 -070095#else
96 return false;
97#endif
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080098}
99
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800100bool FileA3D::load(const void *data, size_t length) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700101 const uint8_t *localData = (const uint8_t *)data;
102
103 size_t lengthRemaining = length;
104 size_t magicStrLen = 12;
105 if ((length < magicStrLen) ||
106 memcmp(data, "Android3D_ff", magicStrLen)) {
107 return false;
108 }
109
110 localData += magicStrLen;
111 lengthRemaining -= magicStrLen;
112
113 // Next we get our header size
114 uint64_t headerSize = 0;
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800115 if (lengthRemaining < sizeof(headerSize)) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700116 return false;
117 }
118
119 memcpy(&headerSize, localData, sizeof(headerSize));
120 localData += sizeof(headerSize);
121 lengthRemaining -= sizeof(headerSize);
122
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800123 if (lengthRemaining < headerSize) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700124 return false;
125 }
126
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700127 // Now open the stream to parse the header
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700128 IStream headerStream(localData, false);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700129 parseHeader(&headerStream);
130
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700131 localData += headerSize;
132 lengthRemaining -= headerSize;
133
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800134 if (lengthRemaining < sizeof(mDataSize)) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700135 return false;
136 }
137
138 // Read the size of the data
139 memcpy(&mDataSize, localData, sizeof(mDataSize));
140 localData += sizeof(mDataSize);
141 lengthRemaining -= sizeof(mDataSize);
142
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800143 if (lengthRemaining < mDataSize) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700144 return false;
145 }
146
147 // We should know enough to read the file in at this point.
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700148 mData = (uint8_t *)localData;
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700149 mReadStream = new IStream(mData, mUse64BitOffsets);
150
151 return true;
152}
153
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800154bool FileA3D::load(FILE *f) {
Jason Samsa5597fc2009-07-08 18:01:53 -0700155 char magicString[12];
156 size_t len;
157
Steve Block65982012011-10-20 11:56:00 +0100158 ALOGV("file open 1");
Jason Samsa5597fc2009-07-08 18:01:53 -0700159 len = fread(magicString, 1, 12, f);
160 if ((len != 12) ||
161 memcmp(magicString, "Android3D_ff", 12)) {
162 return false;
163 }
164
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700165 // Next thing is the size of the header
166 uint64_t headerSize = 0;
167 len = fread(&headerSize, 1, sizeof(headerSize), f);
168 if (len != sizeof(headerSize) || headerSize == 0) {
Jason Samsa5597fc2009-07-08 18:01:53 -0700169 return false;
170 }
171
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700172 uint8_t *headerData = (uint8_t *)malloc(headerSize);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800173 if (!headerData) {
Jason Samsa5597fc2009-07-08 18:01:53 -0700174 return false;
175 }
176
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700177 len = fread(headerData, 1, headerSize, f);
178 if (len != headerSize) {
Jason Samsa5597fc2009-07-08 18:01:53 -0700179 return false;
180 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700181
182 // Now open the stream to parse the header
183 IStream headerStream(headerData, false);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700184 parseHeader(&headerStream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700185
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700186 free(headerData);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700187
188 // Next thing is the size of the header
189 len = fread(&mDataSize, 1, sizeof(mDataSize), f);
190 if (len != sizeof(mDataSize) || mDataSize == 0) {
191 return false;
Jason Samsa5597fc2009-07-08 18:01:53 -0700192 }
193
Steve Block65982012011-10-20 11:56:00 +0100194 ALOGV("file open size = %lli", mDataSize);
Jason Samsa5597fc2009-07-08 18:01:53 -0700195
196 // We should know enough to read the file in at this point.
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700197 mAlloc = malloc(mDataSize);
Jason Samsa5597fc2009-07-08 18:01:53 -0700198 if (!mAlloc) {
199 return false;
200 }
201 mData = (uint8_t *)mAlloc;
202 len = fread(mAlloc, 1, mDataSize, f);
203 if (len != mDataSize) {
204 return false;
205 }
206
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700207 mReadStream = new IStream(mData, mUse64BitOffsets);
208
Steve Block65982012011-10-20 11:56:00 +0100209 ALOGV("Header is read an stream initialized");
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700210 return true;
Jason Samsa5597fc2009-07-08 18:01:53 -0700211}
212
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700213size_t FileA3D::getNumIndexEntries() const {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700214 return mIndex.size();
215}
Jason Samsa5597fc2009-07-08 18:01:53 -0700216
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700217const FileA3D::A3DIndexEntry *FileA3D::getIndexEntry(size_t index) const {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800218 if (index < mIndex.size()) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700219 return mIndex[index];
Jason Samsa5597fc2009-07-08 18:01:53 -0700220 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700221 return NULL;
Jason Samsa5597fc2009-07-08 18:01:53 -0700222}
223
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700224ObjectBase *FileA3D::initializeFromEntry(size_t index) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800225 if (index >= mIndex.size()) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700226 return NULL;
227 }
228
229 FileA3D::A3DIndexEntry *entry = mIndex[index];
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800230 if (!entry) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700231 return NULL;
232 }
233
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800234 if (entry->mRsObj) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700235 entry->mRsObj->incUserRef();
236 return entry->mRsObj;
237 }
238
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700239 // Seek to the beginning of object
240 mReadStream->reset(entry->mOffset);
241 switch (entry->mType) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700242 case RS_A3D_CLASS_ID_UNKNOWN:
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700243 return NULL;
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700244 case RS_A3D_CLASS_ID_MESH:
245 entry->mRsObj = Mesh::createFromStream(mRSC, mReadStream);
246 break;
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700247 case RS_A3D_CLASS_ID_TYPE:
248 entry->mRsObj = Type::createFromStream(mRSC, mReadStream);
249 break;
250 case RS_A3D_CLASS_ID_ELEMENT:
251 entry->mRsObj = Element::createFromStream(mRSC, mReadStream);
252 break;
253 case RS_A3D_CLASS_ID_ALLOCATION:
254 entry->mRsObj = Allocation::createFromStream(mRSC, mReadStream);
255 break;
256 case RS_A3D_CLASS_ID_PROGRAM_VERTEX:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800257 //entry->mRsObj = ProgramVertex::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700258 break;
259 case RS_A3D_CLASS_ID_PROGRAM_RASTER:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800260 //entry->mRsObj = ProgramRaster::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700261 break;
262 case RS_A3D_CLASS_ID_PROGRAM_FRAGMENT:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800263 //entry->mRsObj = ProgramFragment::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700264 break;
265 case RS_A3D_CLASS_ID_PROGRAM_STORE:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800266 //entry->mRsObj = ProgramStore::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700267 break;
268 case RS_A3D_CLASS_ID_SAMPLER:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800269 //entry->mRsObj = Sampler::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700270 break;
271 case RS_A3D_CLASS_ID_ANIMATION:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800272 //entry->mRsObj = Animation::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700273 break;
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700274 case RS_A3D_CLASS_ID_ADAPTER_1D:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800275 //entry->mRsObj = Adapter1D::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700276 break;
277 case RS_A3D_CLASS_ID_ADAPTER_2D:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800278 //entry->mRsObj = Adapter2D::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700279 break;
280 case RS_A3D_CLASS_ID_SCRIPT_C:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800281 break;
Jason Samsdbe66d62012-09-17 13:54:41 -0700282 case RS_A3D_CLASS_ID_SCRIPT_KERNEL_ID:
283 break;
284 case RS_A3D_CLASS_ID_SCRIPT_FIELD_ID:
285 break;
286 case RS_A3D_CLASS_ID_SCRIPT_METHOD_ID:
287 break;
288 case RS_A3D_CLASS_ID_SCRIPT_GROUP:
289 break;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700290 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800291 if (entry->mRsObj) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700292 entry->mRsObj->incUserRef();
293 }
294 return entry->mRsObj;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700295}
296
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800297bool FileA3D::writeFile(const char *filename) {
298 if (!mWriteStream) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000299 ALOGE("No objects to write\n");
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700300 return false;
301 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800302 if (mWriteStream->getPos() == 0) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000303 ALOGE("No objects to write\n");
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700304 return false;
305 }
Jason Samsa5597fc2009-07-08 18:01:53 -0700306
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700307 FILE *writeHandle = fopen(filename, "wb");
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800308 if (!writeHandle) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000309 ALOGE("Couldn't open the file for writing\n");
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700310 return false;
311 }
Jason Samsa5597fc2009-07-08 18:01:53 -0700312
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700313 // Open a new stream to make writing the header easier
314 OStream headerStream(5*1024, false);
315 headerStream.addU32(mMajorVersion);
316 headerStream.addU32(mMinorVersion);
317 uint32_t is64Bit = 0;
318 headerStream.addU32(is64Bit);
Jason Samsa5597fc2009-07-08 18:01:53 -0700319
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700320 uint32_t writeIndexSize = mWriteIndex.size();
321 headerStream.addU32(writeIndexSize);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800322 for (uint32_t i = 0; i < writeIndexSize; i ++) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700323 headerStream.addString(&mWriteIndex[i]->mObjectName);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700324 headerStream.addU32((uint32_t)mWriteIndex[i]->mType);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800325 if (mUse64BitOffsets){
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700326 headerStream.addOffset(mWriteIndex[i]->mOffset);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700327 headerStream.addOffset(mWriteIndex[i]->mLength);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800328 } else {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700329 uint32_t offset = (uint32_t)mWriteIndex[i]->mOffset;
330 headerStream.addU32(offset);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700331 offset = (uint32_t)mWriteIndex[i]->mLength;
332 headerStream.addU32(offset);
Jason Samsa5597fc2009-07-08 18:01:53 -0700333 }
334 }
335
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700336 // Write our magic string so we know we are reading the right file
337 String8 magicString(A3D_MAGIC_KEY);
338 fwrite(magicString.string(), sizeof(char), magicString.size(), writeHandle);
Jason Samsa5597fc2009-07-08 18:01:53 -0700339
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700340 // Store the size of the header to make it easier to parse when we read it
341 uint64_t headerSize = headerStream.getPos();
342 fwrite(&headerSize, sizeof(headerSize), 1, writeHandle);
Jason Samsa5597fc2009-07-08 18:01:53 -0700343
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700344 // Now write our header
345 fwrite(headerStream.getPtr(), sizeof(uint8_t), headerStream.getPos(), writeHandle);
Jason Samsa5597fc2009-07-08 18:01:53 -0700346
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700347 // Now write the size of the data part of the file for easier parsing later
348 uint64_t fileDataSize = mWriteStream->getPos();
349 fwrite(&fileDataSize, sizeof(fileDataSize), 1, writeHandle);
350
351 fwrite(mWriteStream->getPtr(), sizeof(uint8_t), mWriteStream->getPos(), writeHandle);
352
353 int status = fclose(writeHandle);
354
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800355 if (status != 0) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000356 ALOGE("Couldn't close file\n");
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700357 return false;
Jason Samsa5597fc2009-07-08 18:01:53 -0700358 }
359
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700360 return true;
Jason Samsa5597fc2009-07-08 18:01:53 -0700361}
362
Jason Samse3150cf2012-07-24 18:10:20 -0700363void FileA3D::appendToFile(Context *con, ObjectBase *obj) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800364 if (!obj) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700365 return;
Jason Samsa5597fc2009-07-08 18:01:53 -0700366 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800367 if (!mWriteStream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700368 const uint64_t initialStreamSize = 256*1024;
369 mWriteStream = new OStream(initialStreamSize, false);
Jason Samsa5597fc2009-07-08 18:01:53 -0700370 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700371 A3DIndexEntry *indexEntry = new A3DIndexEntry();
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700372 indexEntry->mObjectName.setTo(obj->getName());
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700373 indexEntry->mType = obj->getClassId();
374 indexEntry->mOffset = mWriteStream->getPos();
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700375 indexEntry->mRsObj = obj;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700376 mWriteIndex.push(indexEntry);
Jason Samse3150cf2012-07-24 18:10:20 -0700377 obj->serialize(con, mWriteStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700378 indexEntry->mLength = mWriteStream->getPos() - indexEntry->mOffset;
379 mWriteStream->align(4);
Jason Samsa5597fc2009-07-08 18:01:53 -0700380}
381
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800382RsObjectBase rsaFileA3DGetEntryByIndex(RsContext con, uint32_t index, RsFile file) {
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700383 FileA3D *fa3d = static_cast<FileA3D *>(file);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800384 if (!fa3d) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000385 ALOGE("Can't load entry. No valid file");
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700386 return NULL;
387 }
388
389 ObjectBase *obj = fa3d->initializeFromEntry(index);
Steve Block65982012011-10-20 11:56:00 +0100390 //ALOGV("Returning object with name %s", obj->getName());
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700391
392 return obj;
393}
394
395
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800396void rsaFileA3DGetNumIndexEntries(RsContext con, int32_t *numEntries, RsFile file) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700397 FileA3D *fa3d = static_cast<FileA3D *>(file);
398
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800399 if (fa3d) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700400 *numEntries = fa3d->getNumIndexEntries();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800401 } else {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700402 *numEntries = 0;
403 }
404}
405
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800406void rsaFileA3DGetIndexEntries(RsContext con, RsFileIndexEntry *fileEntries, uint32_t numEntries, RsFile file) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700407 FileA3D *fa3d = static_cast<FileA3D *>(file);
408
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800409 if (!fa3d) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000410 ALOGE("Can't load index entries. No valid file");
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700411 return;
412 }
413
414 uint32_t numFileEntries = fa3d->getNumIndexEntries();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800415 if (numFileEntries != numEntries || numEntries == 0 || fileEntries == NULL) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000416 ALOGE("Can't load index entries. Invalid number requested");
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700417 return;
418 }
419
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800420 for (uint32_t i = 0; i < numFileEntries; i ++) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700421 const FileA3D::A3DIndexEntry *entry = fa3d->getIndexEntry(i);
422 fileEntries[i].classID = entry->getType();
423 fileEntries[i].objectName = entry->getObjectName().string();
424 }
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700425}
426
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800427RsFile rsaFileA3DCreateFromMemory(RsContext con, const void *data, uint32_t len) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700428 if (data == NULL) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000429 ALOGE("File load failed. Asset stream is NULL");
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700430 return NULL;
431 }
432
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700433 Context *rsc = static_cast<Context *>(con);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700434 FileA3D *fa3d = new FileA3D(rsc);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700435 fa3d->incUserRef();
436
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700437 fa3d->load(data, len);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700438 return fa3d;
439}
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800440
441RsFile rsaFileA3DCreateFromAsset(RsContext con, void *_asset) {
Jason Samsa6ab26a2012-03-28 17:44:21 -0700442#if !defined(__RS_PDK__)
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800443 Context *rsc = static_cast<Context *>(con);
444 Asset *asset = static_cast<Asset *>(_asset);
445 FileA3D *fa3d = new FileA3D(rsc);
446 fa3d->incUserRef();
447
448 fa3d->load(asset);
449 return fa3d;
Jason Samsa6ab26a2012-03-28 17:44:21 -0700450#else
451 return NULL;
452#endif
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800453}
454
455RsFile rsaFileA3DCreateFromFile(RsContext con, const char *path) {
456 if (path == NULL) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000457 ALOGE("File load failed. Path is NULL");
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800458 return NULL;
459 }
460
461 Context *rsc = static_cast<Context *>(con);
462 FileA3D *fa3d = NULL;
463
464 FILE *f = fopen(path, "rb");
465 if (f) {
466 fa3d = new FileA3D(rsc);
467 fa3d->incUserRef();
468 fa3d->load(f);
469 fclose(f);
470 } else {
Steve Blockaf12ac62012-01-06 19:20:56 +0000471 ALOGE("Could not open file %s", path);
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800472 }
473
474 return fa3d;
475}