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