1 /*
2 * Copyright (C) 2017 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 "snapshot/TextureLoader.h"
18
19 #include "aemu/base/EintrWrapper.h"
20 #include "aemu/base/files/DecompressingStream.h"
21
22 #include <assert.h>
23
24 using android::base::DecompressingStream;
25
26 namespace android {
27 namespace snapshot {
28
TextureLoader(android::base::StdioStream && stream)29 TextureLoader::TextureLoader(android::base::StdioStream&& stream)
30 : mStream(std::move(stream)) {}
31
start()32 bool TextureLoader::start() {
33 if (mStarted) {
34 return !mHasError;
35 }
36
37 mStarted = true;
38 bool res = readIndex();
39 if (!res) {
40 mHasError = true;
41 return false;
42 }
43 return true;
44 }
45
loadTexture(uint32_t texId,const loader_t & loader)46 void TextureLoader::loadTexture(uint32_t texId, const loader_t& loader) {
47 android::base::AutoLock scopedLock(mLock);
48 assert(mIndex.count(texId));
49 HANDLE_EINTR(fseeko64(mStream.get(), mIndex[texId], SEEK_SET));
50 switch (mVersion) {
51 case 1:
52 loader(&mStream);
53 break;
54 case 2: {
55 DecompressingStream stream(mStream);
56 loader(&stream);
57 }
58 }
59 if (ferror(mStream.get())) {
60 mHasError = true;
61 }
62 }
63
readIndex()64 bool TextureLoader::readIndex() {
65 #if SNAPSHOT_PROFILE > 1
66 auto start = android::base::System::get()->getHighResTimeUs();
67 #endif
68 assert(mIndex.size() == 0);
69 uint64_t size;
70 if (base::getFileSize(fileno(mStream.get()), &size)) {
71 mDiskSize = size;
72 }
73 auto indexPos = mStream.getBe64();
74 HANDLE_EINTR(fseeko64(mStream.get(), static_cast<int64_t>(indexPos), SEEK_SET));
75 mVersion = mStream.getBe32();
76 if (mVersion < 1 || mVersion > 2) {
77 return false;
78 }
79 uint32_t texCount = mStream.getBe32();
80 mIndex.reserve(texCount);
81 for (uint32_t i = 0; i < texCount; i++) {
82 uint32_t tex = mStream.getBe32();
83 uint64_t filePos = mStream.getBe64();
84 mIndex.emplace(tex, filePos);
85 }
86 #if SNAPSHOT_PROFILE > 1
87 printf("Texture readIndex() time: %.03f\n",
88 (android::base::System::get()->getHighResTimeUs() - start) / 1000.0);
89 #endif
90 return true;
91 }
92
93 } // namespace snapshot
94 } // namespace android
95