xref: /aosp_15_r20/frameworks/rs/rsFileA3D.cpp (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker 
2*e1eccf28SAndroid Build Coastguard Worker /*
3*e1eccf28SAndroid Build Coastguard Worker  * Copyright (C) 2009 The Android Open Source Project
4*e1eccf28SAndroid Build Coastguard Worker  *
5*e1eccf28SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*e1eccf28SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*e1eccf28SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
8*e1eccf28SAndroid Build Coastguard Worker  *
9*e1eccf28SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
10*e1eccf28SAndroid Build Coastguard Worker  *
11*e1eccf28SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*e1eccf28SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*e1eccf28SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*e1eccf28SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*e1eccf28SAndroid Build Coastguard Worker  * limitations under the License.
16*e1eccf28SAndroid Build Coastguard Worker  */
17*e1eccf28SAndroid Build Coastguard Worker 
18*e1eccf28SAndroid Build Coastguard Worker #include "rsContext.h"
19*e1eccf28SAndroid Build Coastguard Worker #include "rsFileA3D.h"
20*e1eccf28SAndroid Build Coastguard Worker 
21*e1eccf28SAndroid Build Coastguard Worker #include "rsMesh.h"
22*e1eccf28SAndroid Build Coastguard Worker #include "rsAnimation.h"
23*e1eccf28SAndroid Build Coastguard Worker #include "rs.h"
24*e1eccf28SAndroid Build Coastguard Worker 
25*e1eccf28SAndroid Build Coastguard Worker #include <inttypes.h>
26*e1eccf28SAndroid Build Coastguard Worker 
27*e1eccf28SAndroid Build Coastguard Worker namespace android {
28*e1eccf28SAndroid Build Coastguard Worker namespace renderscript {
29*e1eccf28SAndroid Build Coastguard Worker 
FileA3D(Context * rsc)30*e1eccf28SAndroid Build Coastguard Worker FileA3D::FileA3D(Context *rsc) : ObjectBase(rsc) {
31*e1eccf28SAndroid Build Coastguard Worker     mAlloc = nullptr;
32*e1eccf28SAndroid Build Coastguard Worker     mData = nullptr;
33*e1eccf28SAndroid Build Coastguard Worker     mWriteStream = nullptr;
34*e1eccf28SAndroid Build Coastguard Worker     mReadStream = nullptr;
35*e1eccf28SAndroid Build Coastguard Worker 
36*e1eccf28SAndroid Build Coastguard Worker     mMajorVersion = 0;
37*e1eccf28SAndroid Build Coastguard Worker     mMinorVersion = 1;
38*e1eccf28SAndroid Build Coastguard Worker     mDataSize = 0;
39*e1eccf28SAndroid Build Coastguard Worker }
40*e1eccf28SAndroid Build Coastguard Worker 
~FileA3D()41*e1eccf28SAndroid Build Coastguard Worker FileA3D::~FileA3D() {
42*e1eccf28SAndroid Build Coastguard Worker     for (size_t i = 0; i < mIndex.size(); i ++) {
43*e1eccf28SAndroid Build Coastguard Worker         delete mIndex[i];
44*e1eccf28SAndroid Build Coastguard Worker     }
45*e1eccf28SAndroid Build Coastguard Worker     for (size_t i = 0; i < mWriteIndex.size(); i ++) {
46*e1eccf28SAndroid Build Coastguard Worker         delete mWriteIndex[i];
47*e1eccf28SAndroid Build Coastguard Worker     }
48*e1eccf28SAndroid Build Coastguard Worker     if (mWriteStream) {
49*e1eccf28SAndroid Build Coastguard Worker         delete mWriteStream;
50*e1eccf28SAndroid Build Coastguard Worker     }
51*e1eccf28SAndroid Build Coastguard Worker     if (mReadStream) {
52*e1eccf28SAndroid Build Coastguard Worker         delete mReadStream;
53*e1eccf28SAndroid Build Coastguard Worker     }
54*e1eccf28SAndroid Build Coastguard Worker     if (mAlloc) {
55*e1eccf28SAndroid Build Coastguard Worker         free(mAlloc);
56*e1eccf28SAndroid Build Coastguard Worker     }
57*e1eccf28SAndroid Build Coastguard Worker }
58*e1eccf28SAndroid Build Coastguard Worker 
parseHeader(IStream * headerStream)59*e1eccf28SAndroid Build Coastguard Worker void FileA3D::parseHeader(IStream *headerStream) {
60*e1eccf28SAndroid Build Coastguard Worker     mMajorVersion = headerStream->loadU32();
61*e1eccf28SAndroid Build Coastguard Worker     mMinorVersion = headerStream->loadU32();
62*e1eccf28SAndroid Build Coastguard Worker     uint32_t flags = headerStream->loadU32();
63*e1eccf28SAndroid Build Coastguard Worker     mUse64BitOffsets = (flags & 1) != 0;
64*e1eccf28SAndroid Build Coastguard Worker 
65*e1eccf28SAndroid Build Coastguard Worker     uint32_t numIndexEntries = headerStream->loadU32();
66*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < numIndexEntries; i ++) {
67*e1eccf28SAndroid Build Coastguard Worker         A3DIndexEntry *entry = new A3DIndexEntry();
68*e1eccf28SAndroid Build Coastguard Worker         entry->mObjectName = headerStream->loadString();
69*e1eccf28SAndroid Build Coastguard Worker 
70*e1eccf28SAndroid Build Coastguard Worker         //ALOGV("Header data, entry name = %s", entry->mObjectName.string());
71*e1eccf28SAndroid Build Coastguard Worker         entry->mType = (RsA3DClassID)headerStream->loadU32();
72*e1eccf28SAndroid Build Coastguard Worker         if (mUse64BitOffsets){
73*e1eccf28SAndroid Build Coastguard Worker             entry->mOffset = headerStream->loadOffset();
74*e1eccf28SAndroid Build Coastguard Worker             entry->mLength = headerStream->loadOffset();
75*e1eccf28SAndroid Build Coastguard Worker         } else {
76*e1eccf28SAndroid Build Coastguard Worker             entry->mOffset = headerStream->loadU32();
77*e1eccf28SAndroid Build Coastguard Worker             entry->mLength = headerStream->loadU32();
78*e1eccf28SAndroid Build Coastguard Worker         }
79*e1eccf28SAndroid Build Coastguard Worker         entry->mRsObj = nullptr;
80*e1eccf28SAndroid Build Coastguard Worker         mIndex.push_back(entry);
81*e1eccf28SAndroid Build Coastguard Worker     }
82*e1eccf28SAndroid Build Coastguard Worker }
83*e1eccf28SAndroid Build Coastguard Worker 
load(Asset * asset)84*e1eccf28SAndroid Build Coastguard Worker bool FileA3D::load(Asset *asset) {
85*e1eccf28SAndroid Build Coastguard Worker     return false;
86*e1eccf28SAndroid Build Coastguard Worker }
87*e1eccf28SAndroid Build Coastguard Worker 
load(const void * data,size_t length)88*e1eccf28SAndroid Build Coastguard Worker bool FileA3D::load(const void *data, size_t length) {
89*e1eccf28SAndroid Build Coastguard Worker     const uint8_t *localData = (const uint8_t *)data;
90*e1eccf28SAndroid Build Coastguard Worker 
91*e1eccf28SAndroid Build Coastguard Worker     size_t lengthRemaining = length;
92*e1eccf28SAndroid Build Coastguard Worker     size_t magicStrLen = 12;
93*e1eccf28SAndroid Build Coastguard Worker     if ((length < magicStrLen) ||
94*e1eccf28SAndroid Build Coastguard Worker         memcmp(data, "Android3D_ff", magicStrLen)) {
95*e1eccf28SAndroid Build Coastguard Worker         return false;
96*e1eccf28SAndroid Build Coastguard Worker     }
97*e1eccf28SAndroid Build Coastguard Worker 
98*e1eccf28SAndroid Build Coastguard Worker     localData += magicStrLen;
99*e1eccf28SAndroid Build Coastguard Worker     lengthRemaining -= magicStrLen;
100*e1eccf28SAndroid Build Coastguard Worker 
101*e1eccf28SAndroid Build Coastguard Worker     // Next we get our header size
102*e1eccf28SAndroid Build Coastguard Worker     uint64_t headerSize = 0;
103*e1eccf28SAndroid Build Coastguard Worker     if (lengthRemaining < sizeof(headerSize)) {
104*e1eccf28SAndroid Build Coastguard Worker         return false;
105*e1eccf28SAndroid Build Coastguard Worker     }
106*e1eccf28SAndroid Build Coastguard Worker 
107*e1eccf28SAndroid Build Coastguard Worker     memcpy(&headerSize, localData, sizeof(headerSize));
108*e1eccf28SAndroid Build Coastguard Worker     localData += sizeof(headerSize);
109*e1eccf28SAndroid Build Coastguard Worker     lengthRemaining -= sizeof(headerSize);
110*e1eccf28SAndroid Build Coastguard Worker 
111*e1eccf28SAndroid Build Coastguard Worker     if (lengthRemaining < headerSize) {
112*e1eccf28SAndroid Build Coastguard Worker         return false;
113*e1eccf28SAndroid Build Coastguard Worker     }
114*e1eccf28SAndroid Build Coastguard Worker 
115*e1eccf28SAndroid Build Coastguard Worker     // Now open the stream to parse the header
116*e1eccf28SAndroid Build Coastguard Worker     IStream headerStream(localData, false);
117*e1eccf28SAndroid Build Coastguard Worker     parseHeader(&headerStream);
118*e1eccf28SAndroid Build Coastguard Worker 
119*e1eccf28SAndroid Build Coastguard Worker     localData += headerSize;
120*e1eccf28SAndroid Build Coastguard Worker     lengthRemaining -= headerSize;
121*e1eccf28SAndroid Build Coastguard Worker 
122*e1eccf28SAndroid Build Coastguard Worker     if (lengthRemaining < sizeof(mDataSize)) {
123*e1eccf28SAndroid Build Coastguard Worker         return false;
124*e1eccf28SAndroid Build Coastguard Worker     }
125*e1eccf28SAndroid Build Coastguard Worker 
126*e1eccf28SAndroid Build Coastguard Worker     // Read the size of the data
127*e1eccf28SAndroid Build Coastguard Worker     memcpy(&mDataSize, localData, sizeof(mDataSize));
128*e1eccf28SAndroid Build Coastguard Worker     localData += sizeof(mDataSize);
129*e1eccf28SAndroid Build Coastguard Worker     lengthRemaining -= sizeof(mDataSize);
130*e1eccf28SAndroid Build Coastguard Worker 
131*e1eccf28SAndroid Build Coastguard Worker     if (lengthRemaining < mDataSize) {
132*e1eccf28SAndroid Build Coastguard Worker         return false;
133*e1eccf28SAndroid Build Coastguard Worker     }
134*e1eccf28SAndroid Build Coastguard Worker 
135*e1eccf28SAndroid Build Coastguard Worker     // We should know enough to read the file in at this point.
136*e1eccf28SAndroid Build Coastguard Worker     mData = (uint8_t *)localData;
137*e1eccf28SAndroid Build Coastguard Worker     mReadStream = new IStream(mData, mUse64BitOffsets);
138*e1eccf28SAndroid Build Coastguard Worker 
139*e1eccf28SAndroid Build Coastguard Worker     return true;
140*e1eccf28SAndroid Build Coastguard Worker }
141*e1eccf28SAndroid Build Coastguard Worker 
load(FILE * f)142*e1eccf28SAndroid Build Coastguard Worker bool FileA3D::load(FILE *f) {
143*e1eccf28SAndroid Build Coastguard Worker     char magicString[12];
144*e1eccf28SAndroid Build Coastguard Worker     size_t len;
145*e1eccf28SAndroid Build Coastguard Worker 
146*e1eccf28SAndroid Build Coastguard Worker     ALOGV("file open 1");
147*e1eccf28SAndroid Build Coastguard Worker     len = fread(magicString, 1, 12, f);
148*e1eccf28SAndroid Build Coastguard Worker     if ((len != 12) ||
149*e1eccf28SAndroid Build Coastguard Worker         memcmp(magicString, "Android3D_ff", 12)) {
150*e1eccf28SAndroid Build Coastguard Worker         return false;
151*e1eccf28SAndroid Build Coastguard Worker     }
152*e1eccf28SAndroid Build Coastguard Worker 
153*e1eccf28SAndroid Build Coastguard Worker     // Next thing is the size of the header
154*e1eccf28SAndroid Build Coastguard Worker     uint64_t headerSize = 0;
155*e1eccf28SAndroid Build Coastguard Worker     len = fread(&headerSize, 1, sizeof(headerSize), f);
156*e1eccf28SAndroid Build Coastguard Worker     if (len != sizeof(headerSize) || headerSize == 0) {
157*e1eccf28SAndroid Build Coastguard Worker         return false;
158*e1eccf28SAndroid Build Coastguard Worker     }
159*e1eccf28SAndroid Build Coastguard Worker 
160*e1eccf28SAndroid Build Coastguard Worker     uint8_t *headerData = (uint8_t *)malloc(headerSize);
161*e1eccf28SAndroid Build Coastguard Worker     if (!headerData) {
162*e1eccf28SAndroid Build Coastguard Worker         return false;
163*e1eccf28SAndroid Build Coastguard Worker     }
164*e1eccf28SAndroid Build Coastguard Worker 
165*e1eccf28SAndroid Build Coastguard Worker     len = fread(headerData, 1, headerSize, f);
166*e1eccf28SAndroid Build Coastguard Worker     if (len != headerSize) {
167*e1eccf28SAndroid Build Coastguard Worker         free(headerData);
168*e1eccf28SAndroid Build Coastguard Worker         return false;
169*e1eccf28SAndroid Build Coastguard Worker     }
170*e1eccf28SAndroid Build Coastguard Worker 
171*e1eccf28SAndroid Build Coastguard Worker     // Now open the stream to parse the header
172*e1eccf28SAndroid Build Coastguard Worker     IStream headerStream(headerData, false);
173*e1eccf28SAndroid Build Coastguard Worker     parseHeader(&headerStream);
174*e1eccf28SAndroid Build Coastguard Worker 
175*e1eccf28SAndroid Build Coastguard Worker     free(headerData);
176*e1eccf28SAndroid Build Coastguard Worker 
177*e1eccf28SAndroid Build Coastguard Worker     // Next thing is the size of the header
178*e1eccf28SAndroid Build Coastguard Worker     len = fread(&mDataSize, 1, sizeof(mDataSize), f);
179*e1eccf28SAndroid Build Coastguard Worker     if (len != sizeof(mDataSize) || mDataSize == 0) {
180*e1eccf28SAndroid Build Coastguard Worker         return false;
181*e1eccf28SAndroid Build Coastguard Worker     }
182*e1eccf28SAndroid Build Coastguard Worker 
183*e1eccf28SAndroid Build Coastguard Worker     ALOGV("file open size = %" PRIi64, mDataSize);
184*e1eccf28SAndroid Build Coastguard Worker 
185*e1eccf28SAndroid Build Coastguard Worker     // We should know enough to read the file in at this point.
186*e1eccf28SAndroid Build Coastguard Worker     mAlloc = malloc(mDataSize);
187*e1eccf28SAndroid Build Coastguard Worker     if (!mAlloc) {
188*e1eccf28SAndroid Build Coastguard Worker         return false;
189*e1eccf28SAndroid Build Coastguard Worker     }
190*e1eccf28SAndroid Build Coastguard Worker     mData = (uint8_t *)mAlloc;
191*e1eccf28SAndroid Build Coastguard Worker     len = fread(mAlloc, 1, mDataSize, f);
192*e1eccf28SAndroid Build Coastguard Worker     if (len != mDataSize) {
193*e1eccf28SAndroid Build Coastguard Worker         return false;
194*e1eccf28SAndroid Build Coastguard Worker     }
195*e1eccf28SAndroid Build Coastguard Worker 
196*e1eccf28SAndroid Build Coastguard Worker     mReadStream = new IStream(mData, mUse64BitOffsets);
197*e1eccf28SAndroid Build Coastguard Worker 
198*e1eccf28SAndroid Build Coastguard Worker     ALOGV("Header is read an stream initialized");
199*e1eccf28SAndroid Build Coastguard Worker     return true;
200*e1eccf28SAndroid Build Coastguard Worker }
201*e1eccf28SAndroid Build Coastguard Worker 
getNumIndexEntries() const202*e1eccf28SAndroid Build Coastguard Worker size_t FileA3D::getNumIndexEntries() const {
203*e1eccf28SAndroid Build Coastguard Worker     return mIndex.size();
204*e1eccf28SAndroid Build Coastguard Worker }
205*e1eccf28SAndroid Build Coastguard Worker 
~A3DIndexEntry()206*e1eccf28SAndroid Build Coastguard Worker FileA3D::A3DIndexEntry::~A3DIndexEntry() {
207*e1eccf28SAndroid Build Coastguard Worker     delete[] mObjectName;
208*e1eccf28SAndroid Build Coastguard Worker }
209*e1eccf28SAndroid Build Coastguard Worker 
getIndexEntry(size_t index) const210*e1eccf28SAndroid Build Coastguard Worker const FileA3D::A3DIndexEntry *FileA3D::getIndexEntry(size_t index) const {
211*e1eccf28SAndroid Build Coastguard Worker     if (index < mIndex.size()) {
212*e1eccf28SAndroid Build Coastguard Worker         return mIndex[index];
213*e1eccf28SAndroid Build Coastguard Worker     }
214*e1eccf28SAndroid Build Coastguard Worker     return nullptr;
215*e1eccf28SAndroid Build Coastguard Worker }
216*e1eccf28SAndroid Build Coastguard Worker 
initializeFromEntry(size_t index)217*e1eccf28SAndroid Build Coastguard Worker ObjectBase *FileA3D::initializeFromEntry(size_t index) {
218*e1eccf28SAndroid Build Coastguard Worker     if (index >= mIndex.size()) {
219*e1eccf28SAndroid Build Coastguard Worker         return nullptr;
220*e1eccf28SAndroid Build Coastguard Worker     }
221*e1eccf28SAndroid Build Coastguard Worker 
222*e1eccf28SAndroid Build Coastguard Worker     FileA3D::A3DIndexEntry *entry = mIndex[index];
223*e1eccf28SAndroid Build Coastguard Worker     if (!entry) {
224*e1eccf28SAndroid Build Coastguard Worker         return nullptr;
225*e1eccf28SAndroid Build Coastguard Worker     }
226*e1eccf28SAndroid Build Coastguard Worker 
227*e1eccf28SAndroid Build Coastguard Worker     if (entry->mRsObj) {
228*e1eccf28SAndroid Build Coastguard Worker         entry->mRsObj->incUserRef();
229*e1eccf28SAndroid Build Coastguard Worker         return entry->mRsObj;
230*e1eccf28SAndroid Build Coastguard Worker     }
231*e1eccf28SAndroid Build Coastguard Worker 
232*e1eccf28SAndroid Build Coastguard Worker     // Seek to the beginning of object
233*e1eccf28SAndroid Build Coastguard Worker     mReadStream->reset(entry->mOffset);
234*e1eccf28SAndroid Build Coastguard Worker     switch (entry->mType) {
235*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_UNKNOWN:
236*e1eccf28SAndroid Build Coastguard Worker             return nullptr;
237*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_MESH:
238*e1eccf28SAndroid Build Coastguard Worker             entry->mRsObj = Mesh::createFromStream(mRSC, mReadStream);
239*e1eccf28SAndroid Build Coastguard Worker             break;
240*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_TYPE:
241*e1eccf28SAndroid Build Coastguard Worker             entry->mRsObj = Type::createFromStream(mRSC, mReadStream);
242*e1eccf28SAndroid Build Coastguard Worker             break;
243*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_ELEMENT:
244*e1eccf28SAndroid Build Coastguard Worker             entry->mRsObj = Element::createFromStream(mRSC, mReadStream);
245*e1eccf28SAndroid Build Coastguard Worker             break;
246*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_ALLOCATION:
247*e1eccf28SAndroid Build Coastguard Worker             entry->mRsObj = Allocation::createFromStream(mRSC, mReadStream);
248*e1eccf28SAndroid Build Coastguard Worker             break;
249*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_PROGRAM_VERTEX:
250*e1eccf28SAndroid Build Coastguard Worker             //entry->mRsObj = ProgramVertex::createFromStream(mRSC, mReadStream);
251*e1eccf28SAndroid Build Coastguard Worker             break;
252*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_PROGRAM_RASTER:
253*e1eccf28SAndroid Build Coastguard Worker             //entry->mRsObj = ProgramRaster::createFromStream(mRSC, mReadStream);
254*e1eccf28SAndroid Build Coastguard Worker             break;
255*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_PROGRAM_FRAGMENT:
256*e1eccf28SAndroid Build Coastguard Worker             //entry->mRsObj = ProgramFragment::createFromStream(mRSC, mReadStream);
257*e1eccf28SAndroid Build Coastguard Worker             break;
258*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_PROGRAM_STORE:
259*e1eccf28SAndroid Build Coastguard Worker             //entry->mRsObj = ProgramStore::createFromStream(mRSC, mReadStream);
260*e1eccf28SAndroid Build Coastguard Worker             break;
261*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_SAMPLER:
262*e1eccf28SAndroid Build Coastguard Worker             //entry->mRsObj = Sampler::createFromStream(mRSC, mReadStream);
263*e1eccf28SAndroid Build Coastguard Worker             break;
264*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_ANIMATION:
265*e1eccf28SAndroid Build Coastguard Worker             //entry->mRsObj = Animation::createFromStream(mRSC, mReadStream);
266*e1eccf28SAndroid Build Coastguard Worker             break;
267*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_ADAPTER_1D:
268*e1eccf28SAndroid Build Coastguard Worker             //entry->mRsObj = Adapter1D::createFromStream(mRSC, mReadStream);
269*e1eccf28SAndroid Build Coastguard Worker             break;
270*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_ADAPTER_2D:
271*e1eccf28SAndroid Build Coastguard Worker             //entry->mRsObj = Adapter2D::createFromStream(mRSC, mReadStream);
272*e1eccf28SAndroid Build Coastguard Worker             break;
273*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_SCRIPT_C:
274*e1eccf28SAndroid Build Coastguard Worker             break;
275*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_SCRIPT_KERNEL_ID:
276*e1eccf28SAndroid Build Coastguard Worker             break;
277*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_SCRIPT_INVOKE_ID:
278*e1eccf28SAndroid Build Coastguard Worker             break;
279*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_SCRIPT_FIELD_ID:
280*e1eccf28SAndroid Build Coastguard Worker             break;
281*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_SCRIPT_METHOD_ID:
282*e1eccf28SAndroid Build Coastguard Worker             break;
283*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_SCRIPT_GROUP:
284*e1eccf28SAndroid Build Coastguard Worker             break;
285*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_CLOSURE:
286*e1eccf28SAndroid Build Coastguard Worker             break;
287*e1eccf28SAndroid Build Coastguard Worker         case RS_A3D_CLASS_ID_SCRIPT_GROUP2:
288*e1eccf28SAndroid Build Coastguard Worker             break;
289*e1eccf28SAndroid Build Coastguard Worker     }
290*e1eccf28SAndroid Build Coastguard Worker     if (entry->mRsObj) {
291*e1eccf28SAndroid Build Coastguard Worker         entry->mRsObj->incUserRef();
292*e1eccf28SAndroid Build Coastguard Worker     }
293*e1eccf28SAndroid Build Coastguard Worker     return entry->mRsObj;
294*e1eccf28SAndroid Build Coastguard Worker }
295*e1eccf28SAndroid Build Coastguard Worker 
writeFile(const char * filename)296*e1eccf28SAndroid Build Coastguard Worker bool FileA3D::writeFile(const char *filename) {
297*e1eccf28SAndroid Build Coastguard Worker     if (!mWriteStream) {
298*e1eccf28SAndroid Build Coastguard Worker         ALOGE("No objects to write\n");
299*e1eccf28SAndroid Build Coastguard Worker         return false;
300*e1eccf28SAndroid Build Coastguard Worker     }
301*e1eccf28SAndroid Build Coastguard Worker     if (mWriteStream->getPos() == 0) {
302*e1eccf28SAndroid Build Coastguard Worker         ALOGE("No objects to write\n");
303*e1eccf28SAndroid Build Coastguard Worker         return false;
304*e1eccf28SAndroid Build Coastguard Worker     }
305*e1eccf28SAndroid Build Coastguard Worker 
306*e1eccf28SAndroid Build Coastguard Worker     FILE *writeHandle = fopen(filename, "wbe");
307*e1eccf28SAndroid Build Coastguard Worker     if (!writeHandle) {
308*e1eccf28SAndroid Build Coastguard Worker         ALOGE("Couldn't open the file for writing\n");
309*e1eccf28SAndroid Build Coastguard Worker         return false;
310*e1eccf28SAndroid Build Coastguard Worker     }
311*e1eccf28SAndroid Build Coastguard Worker 
312*e1eccf28SAndroid Build Coastguard Worker     // Open a new stream to make writing the header easier
313*e1eccf28SAndroid Build Coastguard Worker     OStream headerStream(5*1024, false);
314*e1eccf28SAndroid Build Coastguard Worker     headerStream.addU32(mMajorVersion);
315*e1eccf28SAndroid Build Coastguard Worker     headerStream.addU32(mMinorVersion);
316*e1eccf28SAndroid Build Coastguard Worker     uint32_t is64Bit = 0;
317*e1eccf28SAndroid Build Coastguard Worker     headerStream.addU32(is64Bit);
318*e1eccf28SAndroid Build Coastguard Worker 
319*e1eccf28SAndroid Build Coastguard Worker     uint32_t writeIndexSize = mWriteIndex.size();
320*e1eccf28SAndroid Build Coastguard Worker     headerStream.addU32(writeIndexSize);
321*e1eccf28SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < writeIndexSize; i ++) {
322*e1eccf28SAndroid Build Coastguard Worker         headerStream.addString(mWriteIndex[i]->mObjectName);
323*e1eccf28SAndroid Build Coastguard Worker         headerStream.addU32((uint32_t)mWriteIndex[i]->mType);
324*e1eccf28SAndroid Build Coastguard Worker         if (mUse64BitOffsets){
325*e1eccf28SAndroid Build Coastguard Worker             headerStream.addOffset(mWriteIndex[i]->mOffset);
326*e1eccf28SAndroid Build Coastguard Worker             headerStream.addOffset(mWriteIndex[i]->mLength);
327*e1eccf28SAndroid Build Coastguard Worker         } else {
328*e1eccf28SAndroid Build Coastguard Worker             uint32_t offset = (uint32_t)mWriteIndex[i]->mOffset;
329*e1eccf28SAndroid Build Coastguard Worker             headerStream.addU32(offset);
330*e1eccf28SAndroid Build Coastguard Worker             offset = (uint32_t)mWriteIndex[i]->mLength;
331*e1eccf28SAndroid Build Coastguard Worker             headerStream.addU32(offset);
332*e1eccf28SAndroid Build Coastguard Worker         }
333*e1eccf28SAndroid Build Coastguard Worker     }
334*e1eccf28SAndroid Build Coastguard Worker 
335*e1eccf28SAndroid Build Coastguard Worker     // Write our magic string so we know we are reading the right file
336*e1eccf28SAndroid Build Coastguard Worker     fwrite(A3D_MAGIC_KEY, sizeof(char), strlen(A3D_MAGIC_KEY), writeHandle);
337*e1eccf28SAndroid Build Coastguard Worker 
338*e1eccf28SAndroid Build Coastguard Worker     // Store the size of the header to make it easier to parse when we read it
339*e1eccf28SAndroid Build Coastguard Worker     uint64_t headerSize = headerStream.getPos();
340*e1eccf28SAndroid Build Coastguard Worker     fwrite(&headerSize, sizeof(headerSize), 1, writeHandle);
341*e1eccf28SAndroid Build Coastguard Worker 
342*e1eccf28SAndroid Build Coastguard Worker     // Now write our header
343*e1eccf28SAndroid Build Coastguard Worker     fwrite(headerStream.getPtr(), sizeof(uint8_t), headerStream.getPos(), writeHandle);
344*e1eccf28SAndroid Build Coastguard Worker 
345*e1eccf28SAndroid Build Coastguard Worker     // Now write the size of the data part of the file for easier parsing later
346*e1eccf28SAndroid Build Coastguard Worker     uint64_t fileDataSize = mWriteStream->getPos();
347*e1eccf28SAndroid Build Coastguard Worker     fwrite(&fileDataSize, sizeof(fileDataSize), 1, writeHandle);
348*e1eccf28SAndroid Build Coastguard Worker 
349*e1eccf28SAndroid Build Coastguard Worker     fwrite(mWriteStream->getPtr(), sizeof(uint8_t), mWriteStream->getPos(), writeHandle);
350*e1eccf28SAndroid Build Coastguard Worker 
351*e1eccf28SAndroid Build Coastguard Worker     int status = fclose(writeHandle);
352*e1eccf28SAndroid Build Coastguard Worker 
353*e1eccf28SAndroid Build Coastguard Worker     if (status != 0) {
354*e1eccf28SAndroid Build Coastguard Worker         ALOGE("Couldn't close file\n");
355*e1eccf28SAndroid Build Coastguard Worker         return false;
356*e1eccf28SAndroid Build Coastguard Worker     }
357*e1eccf28SAndroid Build Coastguard Worker 
358*e1eccf28SAndroid Build Coastguard Worker     return true;
359*e1eccf28SAndroid Build Coastguard Worker }
360*e1eccf28SAndroid Build Coastguard Worker 
appendToFile(Context * con,ObjectBase * obj)361*e1eccf28SAndroid Build Coastguard Worker void FileA3D::appendToFile(Context *con, ObjectBase *obj) {
362*e1eccf28SAndroid Build Coastguard Worker     if (!obj) {
363*e1eccf28SAndroid Build Coastguard Worker         return;
364*e1eccf28SAndroid Build Coastguard Worker     }
365*e1eccf28SAndroid Build Coastguard Worker     if (!mWriteStream) {
366*e1eccf28SAndroid Build Coastguard Worker         const uint64_t initialStreamSize = 256*1024;
367*e1eccf28SAndroid Build Coastguard Worker         mWriteStream = new OStream(initialStreamSize, false);
368*e1eccf28SAndroid Build Coastguard Worker     }
369*e1eccf28SAndroid Build Coastguard Worker     A3DIndexEntry *indexEntry = new A3DIndexEntry();
370*e1eccf28SAndroid Build Coastguard Worker     indexEntry->mObjectName = rsuCopyString(obj->getName());
371*e1eccf28SAndroid Build Coastguard Worker     indexEntry->mType = obj->getClassId();
372*e1eccf28SAndroid Build Coastguard Worker     indexEntry->mOffset = mWriteStream->getPos();
373*e1eccf28SAndroid Build Coastguard Worker     indexEntry->mRsObj = obj;
374*e1eccf28SAndroid Build Coastguard Worker     mWriteIndex.push_back(indexEntry);
375*e1eccf28SAndroid Build Coastguard Worker     obj->serialize(con, mWriteStream);
376*e1eccf28SAndroid Build Coastguard Worker     indexEntry->mLength = mWriteStream->getPos() - indexEntry->mOffset;
377*e1eccf28SAndroid Build Coastguard Worker     mWriteStream->align(4);
378*e1eccf28SAndroid Build Coastguard Worker }
379*e1eccf28SAndroid Build Coastguard Worker 
380*e1eccf28SAndroid Build Coastguard Worker } // namespace renderscript
381*e1eccf28SAndroid Build Coastguard Worker } // namespace android
382