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/System.h" 18 #include "snapshot/common.h" 19 20 #include <functional> 21 #include <vector> 22 23 namespace android { 24 namespace snapshot { 25 26 class ITextureSaver { 27 DISALLOW_COPY_AND_ASSIGN(ITextureSaver); 28 29 protected: 30 ~ITextureSaver() = default; 31 32 public: 33 ITextureSaver() = default; 34 35 using Buffer = android::base::SmallVector<unsigned char>; 36 using saver_t = std::function<void(android::base::Stream*, Buffer*)>; 37 38 // Save texture to a stream as well as update the index 39 virtual void saveTexture(uint32_t texId, const saver_t& saver) = 0; 40 virtual bool hasError() const = 0; 41 virtual uint64_t diskSize() const = 0; 42 virtual bool compressed() const = 0; 43 virtual bool getDuration(uint64_t* duration) = 0; 44 }; 45 46 class TextureSaver final : public ITextureSaver { 47 DISALLOW_COPY_AND_ASSIGN(TextureSaver); 48 49 public: 50 AEMU_EXPORT TextureSaver(android::base::StdioStream&& stream); 51 AEMU_EXPORT ~TextureSaver(); 52 AEMU_EXPORT void saveTexture(uint32_t texId, const saver_t& saver) override; 53 AEMU_EXPORT void done(); 54 hasError()55 AEMU_EXPORT bool hasError() const override { return mHasError; } diskSize()56 AEMU_EXPORT uint64_t diskSize() const override { return mDiskSize; } compressed()57 AEMU_EXPORT bool compressed() const override { return mIndex.version > 1; } 58 59 // getDuration(): 60 // Returns true if there was save with measurable time 61 // (and writes it to |duration| if |duration| is not null), 62 // otherwise returns false. getDuration(uint64_t * duration)63 AEMU_EXPORT bool getDuration(uint64_t* duration) override { 64 if (mEndTime < mStartTime) { 65 return false; 66 } 67 68 if (duration) { 69 *duration = mEndTime - mStartTime; 70 } 71 return true; 72 } 73 74 private: 75 struct FileIndex { 76 struct Texture { 77 uint32_t texId; 78 int64_t filePos; 79 }; 80 81 int64_t startPosInFile; 82 int32_t version = 2; 83 std::vector<Texture> textures; 84 }; 85 86 void writeIndex(); 87 88 android::base::StdioStream mStream; 89 // A buffer for fetching data from GPU memory to RAM. 90 android::base::SmallFixedVector<unsigned char, 128> mBuffer; 91 92 FileIndex mIndex; 93 uint64_t mDiskSize = 0; 94 bool mFinished = false; 95 bool mHasError = false; 96 97 uint64_t mStartTime = 0; 98 uint64_t mEndTime = 0; 99 }; 100 101 } // namespace snapshot 102 } // namespace android 103