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