• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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