1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef FRAMEWORKS_OPENGL_WRAPPER_EGL_BLOB_H
16 #define FRAMEWORKS_OPENGL_WRAPPER_EGL_BLOB_H
17 
18 #include <EGL/egl.h>
19 #include <EGL/eglext.h>
20 #include <memory>
21 #include <vector>
22 #include <string>
23 #include <cstring>
24 #include <cstdint>
25 #include <securec.h>
26 #include <unordered_map>
27 #include <functional>
28 #include "include/private/EGL/cache.h"
29 #include <mutex>
30 #include "egl_wrapper_display.h"
31 #include "egl_defs.h"
32 
33 namespace OHOS {
34 const int MAX_SHADER = 600;
35 const int MAX_SHADER_DELETE = 150;
36 const int HASH_NUM = 31;
37 const int MAX_SHADER_SIZE = 4 * 1024 * 1024;
38 const int DEFER_SAVE_MIN = 4;
39 const int FORMAT_OFFSET = 3;
40 const int CACHE_HEAD = 8;
41 const int CACHE_MAGIC_HEAD = 4;
42 const int BYTE_SIZE = 8;
43 const int CRC_NUM = 24;
44 
45 class BlobCache {
46 public:
47     struct Blob {
48         Blob(const void *dataIn, size_t size);
49         ~Blob();
50         std::shared_ptr<Blob> prev_;
51         std::shared_ptr<Blob> next_;
52         void *data;
53         size_t dataSize;
54     };
55 
56     struct CacheHeader {
57         size_t keySize;
58         size_t valueSize;
59         uint8_t mData[];
60     };
61 
62     //BLobByteHash is the basic hash algorithm to caculate shader.
63     struct BlobByteHash {
operatorBlobByteHash64         size_t operator()(std::shared_ptr<Blob> ptr) const
65         {
66             const unsigned char *bytes = static_cast<const unsigned char *>(ptr->data);
67             size_t hash = 0;
68             for (size_t i = 0; i < ptr->dataSize; ++i) {
69                 hash = hash * HASH_NUM + bytes[i];
70             }
71             return hash;
72         }
73     };
74 
75     //use memcmp to avoid hash collisions
76     struct BlobByteEqual {
operatorBlobByteEqual77         bool operator()(std::shared_ptr<Blob> lhs, std::shared_ptr<Blob> rhs) const
78         {
79             if (lhs->dataSize == rhs->dataSize) {
80                 return memcmp(lhs->data, rhs->data, rhs->dataSize) == 0;
81             } else {
82                 return false;
83             }
84         }
85     };
86 
87     BlobCache();
88     ~BlobCache();
89 
90     //Singoton achievement
91     static BlobCache* Get();
92 
93     //used by ddk
94     static void SetBlobFunc(const void* key, EGLsizeiANDROID keySize, const void* value,
95                             EGLsizeiANDROID valueSize);
96 
97     //used by ddk
98     static EGLsizeiANDROID GetBlobFunc(const void *key, EGLsizeiANDROID keySize, void *value,
99                             EGLsizeiANDROID valueSize);
100 
101     //inner set func
102     void SetBlobLock(const void *key, EGLsizeiANDROID keySize, const void *value,
103                 EGLsizeiANDROID valueSize);
104 
105     //inner get func
106     EGLsizeiANDROID GetBlobLock(const void *key, EGLsizeiANDROID keySize, void *value,
107                             EGLsizeiANDROID valueSize);
108 
109     void SetBlob(const void *key, EGLsizeiANDROID keySize, const void *value,
110                 EGLsizeiANDROID valueSize);
111 
112     EGLsizeiANDROID GetBlob(const void *key, EGLsizeiANDROID keySize, void *value,
113                             EGLsizeiANDROID valueSize);
114 
115     void Init(EglWrapperDisplay* display);
116 
117     //get cache dir from upper layer
118     void SetCacheDir(const std::string dir);
119 
120     void SetCacheShaderSize(int shadermax);
121 
122     void WriteToDisk();
123 
124     void ReadFromDisk();
125 
126     void Terminate();
127 
128     size_t GetCacheSize() const;
129 
130     int GetMapSize() const;
131 
132     bool ValidFile(uint8_t *buf, size_t len);
133 
134     uint32_t CrcGen(const uint8_t *buf, size_t len);
135 
136     void MoveToFront(std::shared_ptr<Blob>& cur);
137 private:
138     static BlobCache *blobCache_;
139     size_t maxShaderSize_;
140     std::unordered_map<std::shared_ptr<Blob>, std::shared_ptr<Blob>, BlobByteHash, BlobByteEqual> mBlobMap_;
141     int blobSize_;
142     int blobSizeMax_;
143     std::shared_ptr<Blob> head_;
144     std::shared_ptr<Blob> tail_;
145     std::string cacheDir_;
146     std::string ddkCacheDir_;
147     std::string fileName_;
148     bool saveStatus_ = false;
149     bool initStatus_;
150     bool readStatus_ = false;
151     std::mutex blobmutex_;
152 };
153 
154 }
155 
156 #endif // FRAMEWORKS_OPENGL_WRAPPER_EGL_BLOB_H
157