// // Copyright 2018 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // BlobCache: Stores keyed blobs in memory to support EGL_ANDROID_blob_cache. // Can be used in conjunction with the platform layer to warm up the cache from // disk. MemoryProgramCache uses this to handle caching of compiled programs.
// In oder to store more cache in blob cache, compress cacheData to compressedData // before being stored. bool CompressBlobCacheData(const size_t cacheSize, const uint8_t *cacheData,
angle::MemoryBuffer *compressedData)
{
uLong uncompressedSize = static_cast<uLong>(cacheSize);
uLong expectedCompressedSize = zlib_internal::GzipExpectedCompressedSize(uncompressedSize);
// Allocate memory. if (!compressedData->resize(expectedCompressedSize))
{
ERR() << "Failed to allocate memory for compression"; returnfalse;
}
int zResult = zlib_internal::GzipCompressHelper(compressedData->data(), &expectedCompressedSize,
cacheData, uncompressedSize, nullptr, nullptr);
if (zResult != Z_OK)
{
ERR() << "Failed to compress cache data: " << zResult; returnfalse;
}
// Resize it to expected size. if (!compressedData->resize(expectedCompressedSize))
{ returnfalse;
}
// Cache it inside blob cache only if caching inside the application is not possible.
mBlobCache.put(key, std::move(newEntry), newEntry.first.size());
}
bool BlobCache::get(angle::ScratchBuffer *scratchBuffer, const BlobCache::Key &key,
BlobCache::Value *valueOut,
size_t *bufferSizeOut)
{ // Look into the application's cache, if there is such a cache if (areBlobCacheFuncsSet())
{
std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
EGLsizeiANDROID valueSize = mGetBlobFunc(key.data(), key.size(), nullptr, 0); if (valueSize <= 0)
{ returnfalse;
}
angle::MemoryBuffer *scratchMemory; bool result = scratchBuffer->get(valueSize, &scratchMemory); if (!result)
{
ERR() << "Failed to allocate memory for binary blob"; returnfalse;
}
// Make sure the key/value pair still exists/is unchanged after the second call // (modifications to the application cache by another thread are a possibility) if (valueSize != originalValueSize)
{ // This warning serves to find issues with the application cache, none of which are // currently known to be thread-safe. If such a use ever arises, this WARN can be // removed.
WARN() << "Binary blob no longer available in cache (removed by a thread?)"; returnfalse;
}
std::scoped_lock<std::mutex> lock(mBlobCacheMutex); // Otherwise we are doing caching internally, so try to find it there const CacheEntry *entry; bool result = mBlobCache.get(key, &entry);
Value compressedValue;
size_t compressedSize; if (!get(scratchBuffer, key, &compressedValue, &compressedSize))
{ return GetAndDecompressResult::NotFound;
}
{ // This needs to be locked because `DecompressBlobCacheData` is reading shared memory from // `compressedValue.data()`.
std::scoped_lock<std::mutex> lock(mBlobCacheMutex); if (!DecompressBlobCacheData(compressedValue.data(), compressedSize, uncompressedValueOut))
{ return GetAndDecompressResult::DecompressFailure;
}
}
bool BlobCache::areBlobCacheFuncsSet() const
{
std::scoped_lock<std::mutex> lock(mBlobCacheMutex); // Either none or both of the callbacks should be set.
ASSERT((mSetBlobFunc != nullptr) == (mGetBlobFunc != nullptr));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.