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