blob: 6f146370208b71a2effbc860b5de0ac3d76e7ccd [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
Ian Rogersf8852d02014-01-29 15:35:17 -080029#include <inttypes.h>
30
Jason Samsa5597fc2009-07-08 18:01:53 -070031using namespace android;
32using namespace android::renderscript;
33
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080034FileA3D::FileA3D(Context *rsc) : ObjectBase(rsc) {
Chris Wailes44bef6f2014-08-12 13:51:10 -070035 mAlloc = nullptr;
36 mData = nullptr;
37 mWriteStream = nullptr;
38 mReadStream = nullptr;
39 mAsset = nullptr;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070040
41 mMajorVersion = 0;
42 mMinorVersion = 1;
43 mDataSize = 0;
Jason Samsa5597fc2009-07-08 18:01:53 -070044}
45
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080046FileA3D::~FileA3D() {
47 for (size_t i = 0; i < mIndex.size(); i ++) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070048 delete mIndex[i];
49 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080050 for (size_t i = 0; i < mWriteIndex.size(); i ++) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070051 delete mWriteIndex[i];
52 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080053 if (mWriteStream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070054 delete mWriteStream;
55 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080056 if (mReadStream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070057 delete mWriteStream;
58 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080059 if (mAlloc) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070060 free(mAlloc);
61 }
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080062 if (mAsset) {
Jason Samsa6ab26a2012-03-28 17:44:21 -070063#if !defined(__RS_PDK__)
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080064 delete mAsset;
Jason Samsa6ab26a2012-03-28 17:44:21 -070065#endif
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080066 }
Jason Samsa5597fc2009-07-08 18:01:53 -070067}
68
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080069void FileA3D::parseHeader(IStream *headerStream) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070070 mMajorVersion = headerStream->loadU32();
71 mMinorVersion = headerStream->loadU32();
72 uint32_t flags = headerStream->loadU32();
73 mUse64BitOffsets = (flags & 1) != 0;
74
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070075 uint32_t numIndexEntries = headerStream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080076 for (uint32_t i = 0; i < numIndexEntries; i ++) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070077 A3DIndexEntry *entry = new A3DIndexEntry();
Jason Sams48ecf6a2013-07-09 15:35:29 -070078 entry->mObjectName = headerStream->loadString();
79
Steve Block65982012011-10-20 11:56:00 +010080 //ALOGV("Header data, entry name = %s", entry->mObjectName.string());
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070081 entry->mType = (RsA3DClassID)headerStream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080082 if (mUse64BitOffsets){
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070083 entry->mOffset = headerStream->loadOffset();
84 entry->mLength = headerStream->loadOffset();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080085 } else {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070086 entry->mOffset = headerStream->loadU32();
87 entry->mLength = headerStream->loadU32();
88 }
Chris Wailes44bef6f2014-08-12 13:51:10 -070089 entry->mRsObj = nullptr;
Chris Wailes93d6bc82014-07-28 16:54:38 -070090 mIndex.push_back(entry);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -070091 }
92}
93
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080094bool FileA3D::load(Asset *asset) {
Jason Samsa6ab26a2012-03-28 17:44:21 -070095#if !defined(__RS_PDK__)
Alex Sakhartchouk5224a272011-01-07 11:12:08 -080096 mAsset = asset;
97 return load(asset->getBuffer(false), asset->getLength());
Jason Samsa6ab26a2012-03-28 17:44:21 -070098#else
99 return false;
100#endif
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800101}
102
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800103bool FileA3D::load(const void *data, size_t length) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700104 const uint8_t *localData = (const uint8_t *)data;
105
106 size_t lengthRemaining = length;
107 size_t magicStrLen = 12;
108 if ((length < magicStrLen) ||
109 memcmp(data, "Android3D_ff", magicStrLen)) {
110 return false;
111 }
112
113 localData += magicStrLen;
114 lengthRemaining -= magicStrLen;
115
116 // Next we get our header size
117 uint64_t headerSize = 0;
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800118 if (lengthRemaining < sizeof(headerSize)) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700119 return false;
120 }
121
122 memcpy(&headerSize, localData, sizeof(headerSize));
123 localData += sizeof(headerSize);
124 lengthRemaining -= sizeof(headerSize);
125
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800126 if (lengthRemaining < headerSize) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700127 return false;
128 }
129
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700130 // Now open the stream to parse the header
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700131 IStream headerStream(localData, false);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700132 parseHeader(&headerStream);
133
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700134 localData += headerSize;
135 lengthRemaining -= headerSize;
136
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800137 if (lengthRemaining < sizeof(mDataSize)) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700138 return false;
139 }
140
141 // Read the size of the data
142 memcpy(&mDataSize, localData, sizeof(mDataSize));
143 localData += sizeof(mDataSize);
144 lengthRemaining -= sizeof(mDataSize);
145
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800146 if (lengthRemaining < mDataSize) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700147 return false;
148 }
149
150 // We should know enough to read the file in at this point.
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700151 mData = (uint8_t *)localData;
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700152 mReadStream = new IStream(mData, mUse64BitOffsets);
153
154 return true;
155}
156
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800157bool FileA3D::load(FILE *f) {
Jason Samsa5597fc2009-07-08 18:01:53 -0700158 char magicString[12];
159 size_t len;
160
Steve Block65982012011-10-20 11:56:00 +0100161 ALOGV("file open 1");
Jason Samsa5597fc2009-07-08 18:01:53 -0700162 len = fread(magicString, 1, 12, f);
163 if ((len != 12) ||
164 memcmp(magicString, "Android3D_ff", 12)) {
165 return false;
166 }
167
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700168 // Next thing is the size of the header
169 uint64_t headerSize = 0;
170 len = fread(&headerSize, 1, sizeof(headerSize), f);
171 if (len != sizeof(headerSize) || headerSize == 0) {
Jason Samsa5597fc2009-07-08 18:01:53 -0700172 return false;
173 }
174
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700175 uint8_t *headerData = (uint8_t *)malloc(headerSize);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800176 if (!headerData) {
Jason Samsa5597fc2009-07-08 18:01:53 -0700177 return false;
178 }
179
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700180 len = fread(headerData, 1, headerSize, f);
181 if (len != headerSize) {
Jason Samsa5597fc2009-07-08 18:01:53 -0700182 return false;
183 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700184
185 // Now open the stream to parse the header
186 IStream headerStream(headerData, false);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700187 parseHeader(&headerStream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700188
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700189 free(headerData);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700190
191 // Next thing is the size of the header
192 len = fread(&mDataSize, 1, sizeof(mDataSize), f);
193 if (len != sizeof(mDataSize) || mDataSize == 0) {
194 return false;
Jason Samsa5597fc2009-07-08 18:01:53 -0700195 }
196
Ian Rogersf8852d02014-01-29 15:35:17 -0800197 ALOGV("file open size = %" PRIi64, mDataSize);
Jason Samsa5597fc2009-07-08 18:01:53 -0700198
199 // We should know enough to read the file in at this point.
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700200 mAlloc = malloc(mDataSize);
Jason Samsa5597fc2009-07-08 18:01:53 -0700201 if (!mAlloc) {
202 return false;
203 }
204 mData = (uint8_t *)mAlloc;
205 len = fread(mAlloc, 1, mDataSize, f);
206 if (len != mDataSize) {
207 return false;
208 }
209
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700210 mReadStream = new IStream(mData, mUse64BitOffsets);
211
Steve Block65982012011-10-20 11:56:00 +0100212 ALOGV("Header is read an stream initialized");
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700213 return true;
Jason Samsa5597fc2009-07-08 18:01:53 -0700214}
215
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700216size_t FileA3D::getNumIndexEntries() const {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700217 return mIndex.size();
218}
Jason Samsa5597fc2009-07-08 18:01:53 -0700219
Jason Sams48ecf6a2013-07-09 15:35:29 -0700220FileA3D::A3DIndexEntry::~A3DIndexEntry() {
221 delete[] mObjectName;
222}
223
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700224const FileA3D::A3DIndexEntry *FileA3D::getIndexEntry(size_t index) const {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800225 if (index < mIndex.size()) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700226 return mIndex[index];
Jason Samsa5597fc2009-07-08 18:01:53 -0700227 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700228 return nullptr;
Jason Samsa5597fc2009-07-08 18:01:53 -0700229}
230
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700231ObjectBase *FileA3D::initializeFromEntry(size_t index) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800232 if (index >= mIndex.size()) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700233 return nullptr;
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700234 }
235
236 FileA3D::A3DIndexEntry *entry = mIndex[index];
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800237 if (!entry) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700238 return nullptr;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700239 }
240
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800241 if (entry->mRsObj) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700242 entry->mRsObj->incUserRef();
243 return entry->mRsObj;
244 }
245
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700246 // Seek to the beginning of object
247 mReadStream->reset(entry->mOffset);
248 switch (entry->mType) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700249 case RS_A3D_CLASS_ID_UNKNOWN:
Chris Wailes44bef6f2014-08-12 13:51:10 -0700250 return nullptr;
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700251 case RS_A3D_CLASS_ID_MESH:
252 entry->mRsObj = Mesh::createFromStream(mRSC, mReadStream);
253 break;
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700254 case RS_A3D_CLASS_ID_TYPE:
255 entry->mRsObj = Type::createFromStream(mRSC, mReadStream);
256 break;
257 case RS_A3D_CLASS_ID_ELEMENT:
258 entry->mRsObj = Element::createFromStream(mRSC, mReadStream);
259 break;
260 case RS_A3D_CLASS_ID_ALLOCATION:
261 entry->mRsObj = Allocation::createFromStream(mRSC, mReadStream);
262 break;
263 case RS_A3D_CLASS_ID_PROGRAM_VERTEX:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800264 //entry->mRsObj = ProgramVertex::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700265 break;
266 case RS_A3D_CLASS_ID_PROGRAM_RASTER:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800267 //entry->mRsObj = ProgramRaster::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700268 break;
269 case RS_A3D_CLASS_ID_PROGRAM_FRAGMENT:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800270 //entry->mRsObj = ProgramFragment::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700271 break;
272 case RS_A3D_CLASS_ID_PROGRAM_STORE:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800273 //entry->mRsObj = ProgramStore::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700274 break;
275 case RS_A3D_CLASS_ID_SAMPLER:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800276 //entry->mRsObj = Sampler::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700277 break;
278 case RS_A3D_CLASS_ID_ANIMATION:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800279 //entry->mRsObj = Animation::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700280 break;
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700281 case RS_A3D_CLASS_ID_ADAPTER_1D:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800282 //entry->mRsObj = Adapter1D::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700283 break;
284 case RS_A3D_CLASS_ID_ADAPTER_2D:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800285 //entry->mRsObj = Adapter2D::createFromStream(mRSC, mReadStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700286 break;
287 case RS_A3D_CLASS_ID_SCRIPT_C:
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800288 break;
Jason Samsdbe66d62012-09-17 13:54:41 -0700289 case RS_A3D_CLASS_ID_SCRIPT_KERNEL_ID:
290 break;
291 case RS_A3D_CLASS_ID_SCRIPT_FIELD_ID:
292 break;
293 case RS_A3D_CLASS_ID_SCRIPT_METHOD_ID:
294 break;
295 case RS_A3D_CLASS_ID_SCRIPT_GROUP:
296 break;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700297 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800298 if (entry->mRsObj) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700299 entry->mRsObj->incUserRef();
300 }
301 return entry->mRsObj;
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700302}
303
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800304bool FileA3D::writeFile(const char *filename) {
305 if (!mWriteStream) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000306 ALOGE("No objects to write\n");
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700307 return false;
308 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800309 if (mWriteStream->getPos() == 0) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000310 ALOGE("No objects to write\n");
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700311 return false;
312 }
Jason Samsa5597fc2009-07-08 18:01:53 -0700313
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700314 FILE *writeHandle = fopen(filename, "wb");
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800315 if (!writeHandle) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000316 ALOGE("Couldn't open the file for writing\n");
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700317 return false;
318 }
Jason Samsa5597fc2009-07-08 18:01:53 -0700319
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700320 // Open a new stream to make writing the header easier
321 OStream headerStream(5*1024, false);
322 headerStream.addU32(mMajorVersion);
323 headerStream.addU32(mMinorVersion);
324 uint32_t is64Bit = 0;
325 headerStream.addU32(is64Bit);
Jason Samsa5597fc2009-07-08 18:01:53 -0700326
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700327 uint32_t writeIndexSize = mWriteIndex.size();
328 headerStream.addU32(writeIndexSize);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800329 for (uint32_t i = 0; i < writeIndexSize; i ++) {
Jason Sams48ecf6a2013-07-09 15:35:29 -0700330 headerStream.addString(mWriteIndex[i]->mObjectName);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700331 headerStream.addU32((uint32_t)mWriteIndex[i]->mType);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800332 if (mUse64BitOffsets){
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700333 headerStream.addOffset(mWriteIndex[i]->mOffset);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700334 headerStream.addOffset(mWriteIndex[i]->mLength);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800335 } else {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700336 uint32_t offset = (uint32_t)mWriteIndex[i]->mOffset;
337 headerStream.addU32(offset);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700338 offset = (uint32_t)mWriteIndex[i]->mLength;
339 headerStream.addU32(offset);
Jason Samsa5597fc2009-07-08 18:01:53 -0700340 }
341 }
342
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700343 // Write our magic string so we know we are reading the right file
Jason Sams48ecf6a2013-07-09 15:35:29 -0700344 fwrite(A3D_MAGIC_KEY, sizeof(char), strlen(A3D_MAGIC_KEY), writeHandle);
Jason Samsa5597fc2009-07-08 18:01:53 -0700345
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700346 // Store the size of the header to make it easier to parse when we read it
347 uint64_t headerSize = headerStream.getPos();
348 fwrite(&headerSize, sizeof(headerSize), 1, writeHandle);
Jason Samsa5597fc2009-07-08 18:01:53 -0700349
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700350 // Now write our header
351 fwrite(headerStream.getPtr(), sizeof(uint8_t), headerStream.getPos(), writeHandle);
Jason Samsa5597fc2009-07-08 18:01:53 -0700352
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700353 // Now write the size of the data part of the file for easier parsing later
354 uint64_t fileDataSize = mWriteStream->getPos();
355 fwrite(&fileDataSize, sizeof(fileDataSize), 1, writeHandle);
356
357 fwrite(mWriteStream->getPtr(), sizeof(uint8_t), mWriteStream->getPos(), writeHandle);
358
359 int status = fclose(writeHandle);
360
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800361 if (status != 0) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000362 ALOGE("Couldn't close file\n");
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700363 return false;
Jason Samsa5597fc2009-07-08 18:01:53 -0700364 }
365
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700366 return true;
Jason Samsa5597fc2009-07-08 18:01:53 -0700367}
368
Jason Samse3150cf2012-07-24 18:10:20 -0700369void FileA3D::appendToFile(Context *con, ObjectBase *obj) {
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800370 if (!obj) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700371 return;
Jason Samsa5597fc2009-07-08 18:01:53 -0700372 }
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800373 if (!mWriteStream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700374 const uint64_t initialStreamSize = 256*1024;
375 mWriteStream = new OStream(initialStreamSize, false);
Jason Samsa5597fc2009-07-08 18:01:53 -0700376 }
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700377 A3DIndexEntry *indexEntry = new A3DIndexEntry();
Jason Sams48ecf6a2013-07-09 15:35:29 -0700378 indexEntry->mObjectName = rsuCopyString(obj->getName());
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700379 indexEntry->mType = obj->getClassId();
380 indexEntry->mOffset = mWriteStream->getPos();
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700381 indexEntry->mRsObj = obj;
Chris Wailes93d6bc82014-07-28 16:54:38 -0700382 mWriteIndex.push_back(indexEntry);
Jason Samse3150cf2012-07-24 18:10:20 -0700383 obj->serialize(con, mWriteStream);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700384 indexEntry->mLength = mWriteStream->getPos() - indexEntry->mOffset;
385 mWriteStream->align(4);
Jason Samsa5597fc2009-07-08 18:01:53 -0700386}
387
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800388RsObjectBase rsaFileA3DGetEntryByIndex(RsContext con, uint32_t index, RsFile file) {
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700389 FileA3D *fa3d = static_cast<FileA3D *>(file);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800390 if (!fa3d) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000391 ALOGE("Can't load entry. No valid file");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700392 return nullptr;
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700393 }
394
395 ObjectBase *obj = fa3d->initializeFromEntry(index);
Steve Block65982012011-10-20 11:56:00 +0100396 //ALOGV("Returning object with name %s", obj->getName());
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700397
398 return obj;
399}
400
401
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800402void rsaFileA3DGetNumIndexEntries(RsContext con, int32_t *numEntries, RsFile file) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700403 FileA3D *fa3d = static_cast<FileA3D *>(file);
404
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800405 if (fa3d) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700406 *numEntries = fa3d->getNumIndexEntries();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800407 } else {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700408 *numEntries = 0;
409 }
410}
411
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800412void rsaFileA3DGetIndexEntries(RsContext con, RsFileIndexEntry *fileEntries, uint32_t numEntries, RsFile file) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700413 FileA3D *fa3d = static_cast<FileA3D *>(file);
414
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800415 if (!fa3d) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000416 ALOGE("Can't load index entries. No valid file");
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700417 return;
418 }
419
420 uint32_t numFileEntries = fa3d->getNumIndexEntries();
Chris Wailes44bef6f2014-08-12 13:51:10 -0700421 if (numFileEntries != numEntries || numEntries == 0 || fileEntries == nullptr) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000422 ALOGE("Can't load index entries. Invalid number requested");
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700423 return;
424 }
425
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800426 for (uint32_t i = 0; i < numFileEntries; i ++) {
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700427 const FileA3D::A3DIndexEntry *entry = fa3d->getIndexEntry(i);
428 fileEntries[i].classID = entry->getType();
Jason Sams48ecf6a2013-07-09 15:35:29 -0700429 fileEntries[i].objectName = rsuCopyString(entry->getObjectName());
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700430 }
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700431}
432
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800433RsFile rsaFileA3DCreateFromMemory(RsContext con, const void *data, uint32_t len) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700434 if (data == nullptr) {
435 ALOGE("File load failed. Asset stream is nullptr");
436 return nullptr;
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700437 }
438
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700439 Context *rsc = static_cast<Context *>(con);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700440 FileA3D *fa3d = new FileA3D(rsc);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700441 fa3d->incUserRef();
442
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700443 fa3d->load(data, len);
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700444 return fa3d;
445}
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800446
447RsFile rsaFileA3DCreateFromAsset(RsContext con, void *_asset) {
Jason Samsa6ab26a2012-03-28 17:44:21 -0700448#if !defined(__RS_PDK__)
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800449 Context *rsc = static_cast<Context *>(con);
450 Asset *asset = static_cast<Asset *>(_asset);
451 FileA3D *fa3d = new FileA3D(rsc);
452 fa3d->incUserRef();
453
454 fa3d->load(asset);
455 return fa3d;
Jason Samsa6ab26a2012-03-28 17:44:21 -0700456#else
Chris Wailes44bef6f2014-08-12 13:51:10 -0700457 return nullptr;
Jason Samsa6ab26a2012-03-28 17:44:21 -0700458#endif
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800459}
460
461RsFile rsaFileA3DCreateFromFile(RsContext con, const char *path) {
Chris Wailes44bef6f2014-08-12 13:51:10 -0700462 if (path == nullptr) {
463 ALOGE("File load failed. Path is nullptr");
464 return nullptr;
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800465 }
466
467 Context *rsc = static_cast<Context *>(con);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700468 FileA3D *fa3d = nullptr;
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800469
470 FILE *f = fopen(path, "rb");
471 if (f) {
472 fa3d = new FileA3D(rsc);
473 fa3d->incUserRef();
474 fa3d->load(f);
475 fclose(f);
476 } else {
Steve Blockaf12ac62012-01-06 19:20:56 +0000477 ALOGE("Could not open file %s", path);
Alex Sakhartchouk5224a272011-01-07 11:12:08 -0800478 }
479
480 return fa3d;
481}