• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma once
13 
14 #include "base/SmallVector.h"
15 #include "base/export.h"
16 #include "base/StdioStream.h"
17 #include "base/Lock.h"
18 #include "base/System.h"
19 #include "base/Thread.h"
20 #include "snapshot/common.h"
21 
22 #include <functional>
23 #include <memory>
24 #include <unordered_map>
25 
26 namespace android {
27 namespace snapshot {
28 
29 class ITextureLoader {
30     DISALLOW_COPY_AND_ASSIGN(ITextureLoader);
31 
32 protected:
33     ~ITextureLoader() = default;
34 
35 public:
36     ITextureLoader() = default;
37 
38     using LoaderThreadPtr = std::shared_ptr<android::base::InterruptibleThread>;
39     using loader_t = std::function<void(android::base::Stream*)>;
40 
41     virtual bool start() = 0;
42     // Move file position to texId and trigger loader
43     virtual void loadTexture(uint32_t texId, const loader_t& loader) = 0;
44     virtual void acquireLoaderThread(LoaderThreadPtr thread) = 0;
45     virtual bool hasError() const = 0;
46     virtual uint64_t diskSize() const = 0;
47     virtual bool compressed() const = 0;
48     virtual void join() = 0;
49     virtual void interrupt() = 0;
50 };
51 
52 class TextureLoader final : public ITextureLoader {
53 public:
54     AEMU_EXPORT TextureLoader(android::base::StdioStream&& stream);
55 
56     AEMU_EXPORT bool start() override;
57     AEMU_EXPORT void loadTexture(uint32_t texId, const loader_t& loader) override;
hasError()58     AEMU_EXPORT bool hasError() const override { return mHasError; }
diskSize()59     AEMU_EXPORT uint64_t diskSize() const override { return mDiskSize; }
compressed()60     AEMU_EXPORT bool compressed() const override { return mVersion > 1; }
61 
acquireLoaderThread(LoaderThreadPtr thread)62     AEMU_EXPORT void acquireLoaderThread(LoaderThreadPtr thread) override {
63         mLoaderThread = std::move(thread);
64     }
65 
join()66     AEMU_EXPORT void join() override {
67         if (mLoaderThread) {
68             mLoaderThread->wait();
69             mLoaderThread.reset();
70         }
71         mStream.close();
72         mEndTime = base::getHighResTimeUs();
73     }
74 
interrupt()75     AEMU_EXPORT void interrupt() override {
76         if (mLoaderThread) {
77             mLoaderThread->interrupt();
78             mLoaderThread->wait();
79             mLoaderThread.reset();
80         }
81         mStream.close();
82         mEndTime = base::getHighResTimeUs();
83     }
84 
85     // getDuration():
86     // Returns true if there was save with measurable time
87     // (and writes it to |duration| if |duration| is not null),
88     // otherwise returns false.
getDuration(uint64_t * duration)89     AEMU_EXPORT bool getDuration(uint64_t* duration) {
90         if (mEndTime < mStartTime) {
91             return false;
92         }
93 
94         if (duration) {
95             *duration = mEndTime - mStartTime;
96         }
97         return true;
98     }
99 
100 private:
101     bool readIndex();
102 
103     android::base::StdioStream mStream;
104     std::unordered_map<uint32_t, int64_t> mIndex;
105     android::base::Lock mLock;
106     bool mStarted = false;
107     bool mHasError = false;
108     int mVersion = 0;
109     uint64_t mDiskSize = 0;
110     LoaderThreadPtr mLoaderThread;
111 
112     uint64_t mStartTime = 0;
113     uint64_t mEndTime = 0;
114 };
115 
116 }  // namespace snapshot
117 }  // namespace android
118