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/files/Stream.h" 21 #include "snapshot/LazySnapshotObj.h" 22 #include "GLcommon/NamedObject.h" 23 #include "GLcommon/TextureData.h" 24 #include "GLcommon/TranslatorIfaces.h" 25 26 #include <GLES2/gl2ext.h> 27 28 #include <atomic> 29 #include <functional> 30 #include <memory> 31 32 class GLDispatch; 33 class GlobalNameSpace; 34 class TextureData; 35 36 // TextureGlobal is an auxiliary class when save and load a texture / EglImage. 37 // We need it only for texture because texture is the only GL object that can be 38 // shared globally (i.e. across guest processes) by wrapping it up in EglImage. 39 40 // Lifespan: 41 // When saving a snapshot, TextureGlobal should be populated in the pre-save 42 // stage, save data in save stage and get destroyed right after that. 43 // When loading from a snapshot, TextureGlobal will be populated and restoring 44 // hardware texture before restoring any EglImage or GLES texture handles. 45 // EglImages and GLES textures get their global handles from TextureGlobal when 46 // EglImages and GLES textures are being loaded. Then TextureGlobal will be 47 // destroyed. 48 49 class SaveableTexture : 50 public android::snapshot::LazySnapshotObj<SaveableTexture> { 51 public: 52 using Buffer = android::base::SmallVector<unsigned char>; 53 using saver_t = void (*)(SaveableTexture*, 54 android::base::Stream*, 55 Buffer* buffer); 56 // loader_t is supposed to setup a stream and trigger loadFromStream. 57 typedef std::function<void(SaveableTexture*)> loader_t; 58 using creator_t = SaveableTexture* (*)(GlobalNameSpace*, loader_t&&); 59 using restorer_t = void (*)(SaveableTexture*); 60 61 SaveableTexture() = delete; 62 SaveableTexture(SaveableTexture&&) = delete; 63 SaveableTexture(GlobalNameSpace* globalNameSpace, loader_t&& loader); 64 SaveableTexture& operator=(SaveableTexture&&) = delete; 65 66 SaveableTexture(const TextureData& texture); 67 // preSave and postSave should be called exactly once before and after 68 // all texture saves. 69 // The bound context cannot be changed from preSave to onSave to postSave 70 static void preSave(); 71 static void postSave(); 72 // precondition: a context must be properly bound 73 void onSave(android::base::Stream* stream); 74 // getGlobalObject() will touch and load data onto GPU if it is not yet 75 // restored 76 const NamedObjectPtr& getGlobalObject(); 77 // precondition: a context must be properly bound 78 void fillEglImage(EglImage* eglImage); 79 void loadFromStream(android::base::Stream* stream); 80 void makeDirty(); 81 bool isDirty() const; 82 void setTarget(GLenum target); 83 void setMipmapLevelAtLeast(unsigned int level); 84 85 unsigned int getGlobalName(); 86 87 // precondition: (1) a context must be properly bound 88 // (2) m_fileReader is set up 89 void restore(); 90 91 private: 92 unsigned int m_target = GL_TEXTURE_2D; 93 unsigned int m_width = 0; 94 unsigned int m_height = 0; 95 unsigned int m_depth = 0; // For texture 3D 96 unsigned int m_format = GL_RGBA; 97 unsigned int m_internalFormat = GL_RGBA; 98 unsigned int m_type = GL_UNSIGNED_BYTE; 99 unsigned int m_border = 0; 100 unsigned int m_texStorageLevels = 0; 101 unsigned int m_maxMipmapLevel = 0; 102 // Attributes used when saving a snapshot 103 unsigned int m_globalName = 0; 104 // Attributes used when loaded from a snapshot 105 NamedObjectPtr m_globalTexObj = nullptr; 106 struct LevelImageData { 107 unsigned int m_width = 0; 108 unsigned int m_height = 0; 109 unsigned int m_depth = 0; 110 android::base::SmallFixedVector<unsigned char, 16> m_data; 111 }; 112 std::unique_ptr<LevelImageData[]> m_levelData[6] = {}; 113 std::unordered_map<GLenum, GLint> m_texParam; 114 loader_t m_loader; 115 GlobalNameSpace* m_globalNamespace = nullptr; 116 bool m_isDirty = true; 117 std::atomic<bool> m_loadedFromStream { false }; 118 }; 119 120 typedef std::shared_ptr<SaveableTexture> SaveableTexturePtr; 121