1 // Copyright 2017 The Android Open Source Project
2 //
3 // This software is licensed under the terms of the GNU General Public
4 // License version 2, as published by the Free Software Foundation, and
5 // may be copied, distributed, and modified under those terms.
6 //
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License for more details.
11
12 #include "snapshot/TextureLoader.h"
13
14 #include "base/EintrWrapper.h"
15 #include "base/DecompressingStream.h"
16
17 #include <assert.h>
18
19 using android::base::DecompressingStream;
20
21 namespace android {
22 namespace snapshot {
23
TextureLoader(android::base::StdioStream && stream)24 TextureLoader::TextureLoader(android::base::StdioStream&& stream)
25 : mStream(std::move(stream)) {}
26
start()27 bool TextureLoader::start() {
28 if (mStarted) {
29 return !mHasError;
30 }
31
32 mStarted = true;
33 bool res = readIndex();
34 if (!res) {
35 mHasError = true;
36 return false;
37 }
38 return true;
39 }
40
loadTexture(uint32_t texId,const loader_t & loader)41 void TextureLoader::loadTexture(uint32_t texId, const loader_t& loader) {
42 android::base::AutoLock scopedLock(mLock);
43 assert(mIndex.count(texId));
44 HANDLE_EINTR(fseeko64(mStream.get(), mIndex[texId], SEEK_SET));
45 switch (mVersion) {
46 case 1:
47 loader(&mStream);
48 break;
49 case 2: {
50 DecompressingStream stream(mStream);
51 loader(&stream);
52 }
53 }
54 if (ferror(mStream.get())) {
55 mHasError = true;
56 }
57 }
58
readIndex()59 bool TextureLoader::readIndex() {
60 #if SNAPSHOT_PROFILE > 1
61 auto start = android::base::System::get()->getHighResTimeUs();
62 #endif
63 assert(mIndex.size() == 0);
64 uint64_t size;
65 if (base::getFileSize(fileno(mStream.get()), &size)) {
66 mDiskSize = size;
67 }
68 auto indexPos = mStream.getBe64();
69 HANDLE_EINTR(fseeko64(mStream.get(), static_cast<int64_t>(indexPos), SEEK_SET));
70 mVersion = mStream.getBe32();
71 if (mVersion < 1 || mVersion > 2) {
72 return false;
73 }
74 uint32_t texCount = mStream.getBe32();
75 mIndex.reserve(texCount);
76 for (uint32_t i = 0; i < texCount; i++) {
77 uint32_t tex = mStream.getBe32();
78 uint64_t filePos = mStream.getBe64();
79 mIndex.emplace(tex, filePos);
80 }
81 #if SNAPSHOT_PROFILE > 1
82 printf("Texture readIndex() time: %.03f\n",
83 (android::base::System::get()->getHighResTimeUs() - start) / 1000.0);
84 #endif
85 return true;
86 }
87
88 } // namespace snapshot
89 } // namespace android
90