Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 169e321c authored by Matt Buckley's avatar Matt Buckley Committed by Automerger Merge Worker
Browse files

Merge "Fix HWUI ShaderCache mIDHash eviction race" into udc-qpr-dev am: 9fb2833f

parents 9f1795dc 9fb2833f
Loading
Loading
Loading
Loading
+12 −20
Original line number Diff line number Diff line
@@ -88,6 +88,9 @@ void ShaderCache::initShaderDiskCache(const void* identity, ssize_t size) {
        mBlobCache.reset(new FileBlobCache(maxKeySize, maxValueSize, maxTotalSize, mFilename));
        validateCache(identity, size);
        mInitialized = true;
        if (identity != nullptr && size > 0 && mIDHash.size()) {
            set(&sIDKey, sizeof(sIDKey), mIDHash.data(), mIDHash.size());
        }
    }
}

@@ -96,11 +99,6 @@ void ShaderCache::setFilename(const char* filename) {
    mFilename = filename;
}

BlobCache* ShaderCache::getBlobCacheLocked() {
    LOG_ALWAYS_FATAL_IF(!mInitialized, "ShaderCache has not been initialized");
    return mBlobCache.get();
}

sk_sp<SkData> ShaderCache::load(const SkData& key) {
    ATRACE_NAME("ShaderCache::load");
    size_t keySize = key.size();
@@ -115,8 +113,7 @@ sk_sp<SkData> ShaderCache::load(const SkData& key) {
    if (!valueBuffer) {
        return nullptr;
    }
    BlobCache* bc = getBlobCacheLocked();
    size_t valueSize = bc->get(key.data(), keySize, valueBuffer, mObservedBlobValueSize);
    size_t valueSize = mBlobCache->get(key.data(), keySize, valueBuffer, mObservedBlobValueSize);
    int maxTries = 3;
    while (valueSize > mObservedBlobValueSize && maxTries > 0) {
        mObservedBlobValueSize = std::min(valueSize, maxValueSize);
@@ -126,7 +123,7 @@ sk_sp<SkData> ShaderCache::load(const SkData& key) {
            return nullptr;
        }
        valueBuffer = newValueBuffer;
        valueSize = bc->get(key.data(), keySize, valueBuffer, mObservedBlobValueSize);
        valueSize = mBlobCache->get(key.data(), keySize, valueBuffer, mObservedBlobValueSize);
        maxTries--;
    }
    if (!valueSize) {
@@ -143,16 +140,17 @@ sk_sp<SkData> ShaderCache::load(const SkData& key) {
    return SkData::MakeFromMalloc(valueBuffer, valueSize);
}

namespace {
// Helper for BlobCache::set to trace the result.
void set(BlobCache* cache, const void* key, size_t keySize, const void* value, size_t valueSize) {
    switch (cache->set(key, keySize, value, valueSize)) {
void ShaderCache::set(const void* key, size_t keySize, const void* value, size_t valueSize) {
    switch (mBlobCache->set(key, keySize, value, valueSize)) {
        case BlobCache::InsertResult::kInserted:
            // This is what we expect/hope. It means the cache is large enough.
            return;
        case BlobCache::InsertResult::kDidClean: {
            ATRACE_FORMAT("ShaderCache: evicted an entry to fit {key: %lu value %lu}!", keySize,
                          valueSize);
            if (mIDHash.size()) {
                set(&sIDKey, sizeof(sIDKey), mIDHash.data(), mIDHash.size());
            }
            return;
        }
        case BlobCache::InsertResult::kNotEnoughSpace: {
@@ -172,15 +170,10 @@ void set(BlobCache* cache, const void* key, size_t keySize, const void* value, s
        }
    }
}
}  // namespace

void ShaderCache::saveToDiskLocked() {
    ATRACE_NAME("ShaderCache::saveToDiskLocked");
    if (mInitialized && mBlobCache) {
        if (mIDHash.size()) {
            auto key = sIDKey;
            set(mBlobCache.get(), &key, sizeof(key), mIDHash.data(), mIDHash.size());
        }
        // The most straightforward way to make ownership shared
        mMutex.unlock();
        mMutex.lock_shared();
@@ -209,11 +202,10 @@ void ShaderCache::store(const SkData& key, const SkData& data, const SkString& /

    const void* value = data.data();

    BlobCache* bc = getBlobCacheLocked();
    if (mInStoreVkPipelineInProgress) {
        if (mOldPipelineCacheSize == -1) {
            // Record the initial pipeline cache size stored in the file.
            mOldPipelineCacheSize = bc->get(key.data(), keySize, nullptr, 0);
            mOldPipelineCacheSize = mBlobCache->get(key.data(), keySize, nullptr, 0);
        }
        if (mNewPipelineCacheSize != -1 && mNewPipelineCacheSize == valueSize) {
            // There has not been change in pipeline cache size. Stop trying to save.
@@ -228,7 +220,7 @@ void ShaderCache::store(const SkData& key, const SkData& data, const SkString& /
        mNewPipelineCacheSize = -1;
        mTryToStorePipelineCache = true;
    }
    set(bc, key.data(), keySize, value, valueSize);
    set(key.data(), keySize, value, valueSize);

    if (!mSavePending && mDeferredSaveDelayMs > 0) {
        mSavePending = true;
+9 −13
Original line number Diff line number Diff line
@@ -95,20 +95,18 @@ private:
    ShaderCache(const ShaderCache&) = delete;
    void operator=(const ShaderCache&) = delete;

    /**
     * "getBlobCacheLocked" returns the BlobCache object being used to store the
     * key/value blob pairs.  If the BlobCache object has not yet been created,
     * this will do so, loading the serialized cache contents from disk if
     * possible.
     */
    BlobCache* getBlobCacheLocked() REQUIRES(mMutex);

    /**
     * "validateCache" updates the cache to match the given identity.  If the
     * cache currently has the wrong identity, all entries in the cache are cleared.
     */
    bool validateCache(const void* identity, ssize_t size) REQUIRES(mMutex);

    /**
     * Helper for BlobCache::set to trace the result and ensure the identity hash
     * does not get evicted.
     */
    void set(const void* key, size_t keySize, const void* value, size_t valueSize) REQUIRES(mMutex);

    /**
     * "saveToDiskLocked" attempts to save the current contents of the cache to
     * disk. If the identity hash exists, we will insert the identity hash into
@@ -127,11 +125,9 @@ private:
    bool mInitialized GUARDED_BY(mMutex) = false;

    /**
     * "mBlobCache" is the cache in which the key/value blob pairs are stored.  It
     * is initially NULL, and will be initialized by getBlobCacheLocked the
     * first time it's needed.
     * The blob cache contains the Android build number. We treat version mismatches as an empty
     * cache (logic implemented in BlobCache::unflatten).
     * "mBlobCache" is the cache in which the key/value blob pairs are stored.
     * The blob cache contains the Android build number. We treat version mismatches
     * as an empty cache (logic implemented in BlobCache::unflatten).
     */
    std::unique_ptr<FileBlobCache> mBlobCache GUARDED_BY(mMutex);