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

Commit 6cca6c23 authored by Cody Northrop's avatar Cody Northrop
Browse files

Reland "EGL: Refactor multifile blobcache"

This reverts commit 43735418.

Previous CL was reverted due to boot time regressions.

Main change from previous CL is removal of thread.join() if
the thread was not initialized.  This was happening at boot
because a number of processes try to use the cache without
providing a location for the cache.  In that case, both old
and new cache will not initialize.

Test: Boot (quickly)
Test: pubg_mobile_launch ANGLE trace
Test: /data/nativetest64/EGL_test/EGL_test
Test: /data/nativetest64/libEGL_test/libEGL_test
Bug: b/266725576

Change-Id: Ib9add1c8342278a46c2e629c919719f973f8c612
parent 32ce29d9
Loading
Loading
Loading
Loading
+6 −1
Original line number Original line Diff line number Diff line
@@ -144,6 +144,7 @@ cc_library_static {
    srcs: [
    srcs: [
        "EGL/BlobCache.cpp",
        "EGL/BlobCache.cpp",
        "EGL/FileBlobCache.cpp",
        "EGL/FileBlobCache.cpp",
        "EGL/MultifileBlobCache.cpp",
    ],
    ],
    export_include_dirs: ["EGL"],
    export_include_dirs: ["EGL"],
}
}
@@ -160,7 +161,6 @@ cc_library_shared {
    srcs: [
    srcs: [
        "EGL/egl_tls.cpp",
        "EGL/egl_tls.cpp",
        "EGL/egl_cache.cpp",
        "EGL/egl_cache.cpp",
        "EGL/egl_cache_multifile.cpp",
        "EGL/egl_display.cpp",
        "EGL/egl_display.cpp",
        "EGL/egl_object.cpp",
        "EGL/egl_object.cpp",
        "EGL/egl_layers.cpp",
        "EGL/egl_layers.cpp",
@@ -205,6 +205,11 @@ cc_test {
    srcs: [
    srcs: [
        "EGL/BlobCache.cpp",
        "EGL/BlobCache.cpp",
        "EGL/BlobCache_test.cpp",
        "EGL/BlobCache_test.cpp",
        "EGL/MultifileBlobCache.cpp",
        "EGL/MultifileBlobCache_test.cpp",
    ],
    shared_libs: [
        "libutils",
    ],
    ],
}
}


+689 −0

File added.

Preview size limit exceeded, changes collapsed.

+167 −0
Original line number Original line Diff line number Diff line
/*
 ** Copyright 2022, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */

#ifndef ANDROID_MULTIFILE_BLOB_CACHE_H
#define ANDROID_MULTIFILE_BLOB_CACHE_H

#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <future>
#include <map>
#include <queue>
#include <string>
#include <thread>
#include <unordered_map>
#include <unordered_set>

namespace android {

struct MultifileHeader {
    EGLsizeiANDROID keySize;
    EGLsizeiANDROID valueSize;
};

struct MultifileEntryStats {
    EGLsizeiANDROID valueSize;
    size_t fileSize;
    time_t accessTime;
};

struct MultifileHotCache {
    int entryFd;
    uint8_t* entryBuffer;
    size_t entrySize;
};

enum class TaskCommand {
    Invalid = 0,
    WriteToDisk,
    Exit,
};

class DeferredTask {
public:
    DeferredTask(TaskCommand command)
          : mCommand(command), mEntryHash(0), mBuffer(nullptr), mBufferSize(0) {}

    TaskCommand getTaskCommand() { return mCommand; }

    void initWriteToDisk(uint32_t entryHash, std::string fullPath, uint8_t* buffer,
                         size_t bufferSize) {
        mCommand = TaskCommand::WriteToDisk;
        mEntryHash = entryHash;
        mFullPath = std::move(fullPath);
        mBuffer = buffer;
        mBufferSize = bufferSize;
    }

    uint32_t getEntryHash() { return mEntryHash; }
    std::string& getFullPath() { return mFullPath; }
    uint8_t* getBuffer() { return mBuffer; }
    size_t getBufferSize() { return mBufferSize; };

private:
    TaskCommand mCommand;

    // Parameters for WriteToDisk
    uint32_t mEntryHash;
    std::string mFullPath;
    uint8_t* mBuffer;
    size_t mBufferSize;
};

class MultifileBlobCache {
public:
    MultifileBlobCache(size_t maxTotalSize, size_t maxHotCacheSize, const std::string& baseDir);
    ~MultifileBlobCache();

    void set(const void* key, EGLsizeiANDROID keySize, const void* value,
             EGLsizeiANDROID valueSize);
    EGLsizeiANDROID get(const void* key, EGLsizeiANDROID keySize, void* value,
                        EGLsizeiANDROID valueSize);

    void finish();

    size_t getTotalSize() const { return mTotalCacheSize; }

private:
    void trackEntry(uint32_t entryHash, EGLsizeiANDROID valueSize, size_t fileSize,
                    time_t accessTime);
    bool contains(uint32_t entryHash) const;
    bool removeEntry(uint32_t entryHash);
    MultifileEntryStats getEntryStats(uint32_t entryHash);

    size_t getFileSize(uint32_t entryHash);
    size_t getValueSize(uint32_t entryHash);

    void increaseTotalCacheSize(size_t fileSize);
    void decreaseTotalCacheSize(size_t fileSize);

    bool addToHotCache(uint32_t entryHash, int fd, uint8_t* entryBufer, size_t entrySize);
    bool removeFromHotCache(uint32_t entryHash);

    void trimCache(size_t cacheByteLimit);
    bool applyLRU(size_t cacheLimit);

    bool mInitialized;
    std::string mMultifileDirName;

    std::unordered_set<uint32_t> mEntries;
    std::unordered_map<uint32_t, MultifileEntryStats> mEntryStats;
    std::unordered_map<uint32_t, MultifileHotCache> mHotCache;

    size_t mMaxKeySize;
    size_t mMaxValueSize;
    size_t mMaxTotalSize;
    size_t mTotalCacheSize;
    size_t mHotCacheLimit;
    size_t mHotCacheEntryLimit;
    size_t mHotCacheSize;

    // Below are the components used for deferred writes

    // Track whether we have pending writes for an entry
    std::multimap<uint32_t, uint8_t*> mDeferredWrites;

    // Functions to work through tasks in the queue
    void processTasks();
    void processTasksImpl(bool* exitThread);
    void processTask(DeferredTask& task);

    // Used by main thread to create work for the worker thread
    void queueTask(DeferredTask&& task);

    // Used by main thread to wait for worker thread to complete all outstanding work.
    void waitForWorkComplete();

    std::thread mTaskThread;
    std::queue<DeferredTask> mTasks;
    std::mutex mWorkerMutex;

    // This condition will block the worker thread until a task is queued
    std::condition_variable mWorkAvailableCondition;

    // This condition will block the main thread while the worker thread still has tasks
    std::condition_variable mWorkerIdleCondition;

    // This bool will track whether all tasks have been completed
    bool mWorkerThreadIdle;
};

}; // namespace android

#endif // ANDROID_MULTIFILE_BLOB_CACHE_H
+200 −0
Original line number Original line Diff line number Diff line
/*
 ** Copyright 2023, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */

#include "MultifileBlobCache.h"

#include <android-base/test_utils.h>
#include <fcntl.h>
#include <gtest/gtest.h>
#include <stdio.h>

#include <memory>

namespace android {

template <typename T>
using sp = std::shared_ptr<T>;

constexpr size_t kMaxTotalSize = 32 * 1024;
constexpr size_t kMaxPreloadSize = 8 * 1024;

constexpr size_t kMaxKeySize = kMaxPreloadSize / 4;
constexpr size_t kMaxValueSize = kMaxPreloadSize / 2;

class MultifileBlobCacheTest : public ::testing::Test {
protected:
    virtual void SetUp() {
        mTempFile.reset(new TemporaryFile());
        mMBC.reset(new MultifileBlobCache(kMaxTotalSize, kMaxPreloadSize, &mTempFile->path[0]));
    }

    virtual void TearDown() { mMBC.reset(); }

    std::unique_ptr<TemporaryFile> mTempFile;
    std::unique_ptr<MultifileBlobCache> mMBC;
};

TEST_F(MultifileBlobCacheTest, CacheSingleValueSucceeds) {
    unsigned char buf[4] = {0xee, 0xee, 0xee, 0xee};
    mMBC->set("abcd", 4, "efgh", 4);
    ASSERT_EQ(size_t(4), mMBC->get("abcd", 4, buf, 4));
    ASSERT_EQ('e', buf[0]);
    ASSERT_EQ('f', buf[1]);
    ASSERT_EQ('g', buf[2]);
    ASSERT_EQ('h', buf[3]);
}

TEST_F(MultifileBlobCacheTest, CacheTwoValuesSucceeds) {
    unsigned char buf[2] = {0xee, 0xee};
    mMBC->set("ab", 2, "cd", 2);
    mMBC->set("ef", 2, "gh", 2);
    ASSERT_EQ(size_t(2), mMBC->get("ab", 2, buf, 2));
    ASSERT_EQ('c', buf[0]);
    ASSERT_EQ('d', buf[1]);
    ASSERT_EQ(size_t(2), mMBC->get("ef", 2, buf, 2));
    ASSERT_EQ('g', buf[0]);
    ASSERT_EQ('h', buf[1]);
}

TEST_F(MultifileBlobCacheTest, GetSetTwiceSucceeds) {
    unsigned char buf[2] = {0xee, 0xee};
    mMBC->set("ab", 2, "cd", 2);
    ASSERT_EQ(size_t(2), mMBC->get("ab", 2, buf, 2));
    ASSERT_EQ('c', buf[0]);
    ASSERT_EQ('d', buf[1]);
    // Use the same key, but different value
    mMBC->set("ab", 2, "ef", 2);
    ASSERT_EQ(size_t(2), mMBC->get("ab", 2, buf, 2));
    ASSERT_EQ('e', buf[0]);
    ASSERT_EQ('f', buf[1]);
}

TEST_F(MultifileBlobCacheTest, GetOnlyWritesInsideBounds) {
    unsigned char buf[6] = {0xee, 0xee, 0xee, 0xee, 0xee, 0xee};
    mMBC->set("abcd", 4, "efgh", 4);
    ASSERT_EQ(size_t(4), mMBC->get("abcd", 4, buf + 1, 4));
    ASSERT_EQ(0xee, buf[0]);
    ASSERT_EQ('e', buf[1]);
    ASSERT_EQ('f', buf[2]);
    ASSERT_EQ('g', buf[3]);
    ASSERT_EQ('h', buf[4]);
    ASSERT_EQ(0xee, buf[5]);
}

TEST_F(MultifileBlobCacheTest, GetOnlyWritesIfBufferIsLargeEnough) {
    unsigned char buf[3] = {0xee, 0xee, 0xee};
    mMBC->set("abcd", 4, "efgh", 4);
    ASSERT_EQ(size_t(4), mMBC->get("abcd", 4, buf, 3));
    ASSERT_EQ(0xee, buf[0]);
    ASSERT_EQ(0xee, buf[1]);
    ASSERT_EQ(0xee, buf[2]);
}

TEST_F(MultifileBlobCacheTest, GetDoesntAccessNullBuffer) {
    mMBC->set("abcd", 4, "efgh", 4);
    ASSERT_EQ(size_t(4), mMBC->get("abcd", 4, nullptr, 0));
}

TEST_F(MultifileBlobCacheTest, MultipleSetsCacheLatestValue) {
    unsigned char buf[4] = {0xee, 0xee, 0xee, 0xee};
    mMBC->set("abcd", 4, "efgh", 4);
    mMBC->set("abcd", 4, "ijkl", 4);
    ASSERT_EQ(size_t(4), mMBC->get("abcd", 4, buf, 4));
    ASSERT_EQ('i', buf[0]);
    ASSERT_EQ('j', buf[1]);
    ASSERT_EQ('k', buf[2]);
    ASSERT_EQ('l', buf[3]);
}

TEST_F(MultifileBlobCacheTest, SecondSetKeepsFirstValueIfTooLarge) {
    unsigned char buf[kMaxValueSize + 1] = {0xee, 0xee, 0xee, 0xee};
    mMBC->set("abcd", 4, "efgh", 4);
    mMBC->set("abcd", 4, buf, kMaxValueSize + 1);
    ASSERT_EQ(size_t(4), mMBC->get("abcd", 4, buf, 4));
    ASSERT_EQ('e', buf[0]);
    ASSERT_EQ('f', buf[1]);
    ASSERT_EQ('g', buf[2]);
    ASSERT_EQ('h', buf[3]);
}

TEST_F(MultifileBlobCacheTest, DoesntCacheIfKeyIsTooBig) {
    char key[kMaxKeySize + 1];
    unsigned char buf[4] = {0xee, 0xee, 0xee, 0xee};
    for (int i = 0; i < kMaxKeySize + 1; i++) {
        key[i] = 'a';
    }
    mMBC->set(key, kMaxKeySize + 1, "bbbb", 4);
    ASSERT_EQ(size_t(0), mMBC->get(key, kMaxKeySize + 1, buf, 4));
    ASSERT_EQ(0xee, buf[0]);
    ASSERT_EQ(0xee, buf[1]);
    ASSERT_EQ(0xee, buf[2]);
    ASSERT_EQ(0xee, buf[3]);
}

TEST_F(MultifileBlobCacheTest, DoesntCacheIfValueIsTooBig) {
    char buf[kMaxValueSize + 1];
    for (int i = 0; i < kMaxValueSize + 1; i++) {
        buf[i] = 'b';
    }
    mMBC->set("abcd", 4, buf, kMaxValueSize + 1);
    for (int i = 0; i < kMaxValueSize + 1; i++) {
        buf[i] = 0xee;
    }
    ASSERT_EQ(size_t(0), mMBC->get("abcd", 4, buf, kMaxValueSize + 1));
    for (int i = 0; i < kMaxValueSize + 1; i++) {
        SCOPED_TRACE(i);
        ASSERT_EQ(0xee, buf[i]);
    }
}

TEST_F(MultifileBlobCacheTest, CacheMaxKeySizeSucceeds) {
    char key[kMaxKeySize];
    unsigned char buf[4] = {0xee, 0xee, 0xee, 0xee};
    for (int i = 0; i < kMaxKeySize; i++) {
        key[i] = 'a';
    }
    mMBC->set(key, kMaxKeySize, "wxyz", 4);
    ASSERT_EQ(size_t(4), mMBC->get(key, kMaxKeySize, buf, 4));
    ASSERT_EQ('w', buf[0]);
    ASSERT_EQ('x', buf[1]);
    ASSERT_EQ('y', buf[2]);
    ASSERT_EQ('z', buf[3]);
}

TEST_F(MultifileBlobCacheTest, CacheMaxValueSizeSucceeds) {
    char buf[kMaxValueSize];
    for (int i = 0; i < kMaxValueSize; i++) {
        buf[i] = 'b';
    }
    mMBC->set("abcd", 4, buf, kMaxValueSize);
    for (int i = 0; i < kMaxValueSize; i++) {
        buf[i] = 0xee;
    }
    mMBC->get("abcd", 4, buf, kMaxValueSize);
    for (int i = 0; i < kMaxValueSize; i++) {
        SCOPED_TRACE(i);
        ASSERT_EQ('b', buf[i]);
    }
}

TEST_F(MultifileBlobCacheTest, CacheMinKeyAndValueSizeSucceeds) {
    unsigned char buf[1] = {0xee};
    mMBC->set("x", 1, "y", 1);
    ASSERT_EQ(size_t(1), mMBC->get("x", 1, buf, 1));
    ASSERT_EQ('y', buf[0]);
}

} // namespace android
+63 −42
Original line number Original line Diff line number Diff line
@@ -14,6 +14,8 @@
 ** limitations under the License.
 ** limitations under the License.
 */
 */


// #define LOG_NDEBUG 0

#include "egl_cache.h"
#include "egl_cache.h"


#include <android-base/properties.h>
#include <android-base/properties.h>
@@ -25,22 +27,19 @@
#include <thread>
#include <thread>


#include "../egl_impl.h"
#include "../egl_impl.h"
#include "egl_cache_multifile.h"
#include "egl_display.h"
#include "egl_display.h"


// Monolithic cache size limits.
// Monolithic cache size limits.
static const size_t maxKeySize = 12 * 1024;
static const size_t kMaxMonolithicKeySize = 12 * 1024;
static const size_t maxValueSize = 64 * 1024;
static const size_t kMaxMonolithicValueSize = 64 * 1024;
static const size_t maxTotalSize = 32 * 1024 * 1024;
static const size_t kMaxMonolithicTotalSize = 2 * 1024 * 1024;


// The time in seconds to wait before saving newly inserted monolithic cache entries.
// The time in seconds to wait before saving newly inserted monolithic cache entries.
static const unsigned int deferredSaveDelay = 4;
static const unsigned int kDeferredMonolithicSaveDelay = 4;

// Multifile cache size limit
constexpr size_t kMultifileCacheByteLimit = 64 * 1024 * 1024;


// Delay before cleaning up multifile cache entries
// Multifile cache size limits
static const unsigned int deferredMultifileCleanupDelaySeconds = 1;
constexpr uint32_t kMultifileHotCacheLimit = 8 * 1024 * 1024;
constexpr uint32_t kMultifileCacheByteLimit = 32 * 1024 * 1024;


namespace android {
namespace android {


@@ -68,10 +67,7 @@ static EGLsizeiANDROID getBlob(const void* key, EGLsizeiANDROID keySize, void* v
// egl_cache_t definition
// egl_cache_t definition
//
//
egl_cache_t::egl_cache_t()
egl_cache_t::egl_cache_t()
      : mInitialized(false),
      : mInitialized(false), mMultifileMode(false), mCacheByteLimit(kMaxMonolithicTotalSize) {}
        mMultifileMode(false),
        mCacheByteLimit(maxTotalSize),
        mMultifileCleanupPending(false) {}


egl_cache_t::~egl_cache_t() {}
egl_cache_t::~egl_cache_t() {}


@@ -85,7 +81,7 @@ void egl_cache_t::initialize(egl_display_t* display) {
    std::lock_guard<std::mutex> lock(mMutex);
    std::lock_guard<std::mutex> lock(mMutex);


    egl_connection_t* const cnx = &gEGLImpl;
    egl_connection_t* const cnx = &gEGLImpl;
    if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
    if (display && cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
        const char* exts = display->disp.queryString.extensions;
        const char* exts = display->disp.queryString.extensions;
        size_t bcExtLen = strlen(BC_EXT_STR);
        size_t bcExtLen = strlen(BC_EXT_STR);
        size_t extsLen = strlen(exts);
        size_t extsLen = strlen(exts);
@@ -114,14 +110,36 @@ void egl_cache_t::initialize(egl_display_t* display) {
        }
        }
    }
    }


    // Allow forcing monolithic cache for debug purposes
    // Check the device config to decide whether multifile should be used
    if (base::GetProperty("debug.egl.blobcache.multifilemode", "") == "false") {
    if (base::GetBoolProperty("ro.egl.blobcache.multifile", false)) {
        ALOGD("Forcing monolithic cache due to debug.egl.blobcache.multifilemode == \"false\"");
        mMultifileMode = true;
        ALOGV("Using multifile EGL blobcache");
    }

    // Allow forcing the mode for debug purposes
    std::string mode = base::GetProperty("debug.egl.blobcache.multifile", "");
    if (mode == "true") {
        ALOGV("Forcing multifile cache due to debug.egl.blobcache.multifile == %s", mode.c_str());
        mMultifileMode = true;
    } else if (mode == "false") {
        ALOGV("Forcing monolithic cache due to debug.egl.blobcache.multifile == %s", mode.c_str());
        mMultifileMode = false;
        mMultifileMode = false;
    }
    }


    if (mMultifileMode) {
    if (mMultifileMode) {
        mCacheByteLimit = kMultifileCacheByteLimit;
        mCacheByteLimit = static_cast<size_t>(
                base::GetUintProperty<uint32_t>("ro.egl.blobcache.multifile_limit",
                                                kMultifileCacheByteLimit));

        // Check for a debug value
        int debugCacheSize = base::GetIntProperty("debug.egl.blobcache.multifile_limit", -1);
        if (debugCacheSize >= 0) {
            ALOGV("Overriding cache limit %zu with %i from debug.egl.blobcache.multifile_limit",
                  mCacheByteLimit, debugCacheSize);
            mCacheByteLimit = debugCacheSize;
        }

        ALOGV("Using multifile EGL blobcache limit of %zu bytes", mCacheByteLimit);
    }
    }


    mInitialized = true;
    mInitialized = true;
@@ -133,10 +151,10 @@ void egl_cache_t::terminate() {
        mBlobCache->writeToFile();
        mBlobCache->writeToFile();
    }
    }
    mBlobCache = nullptr;
    mBlobCache = nullptr;
    if (mMultifileMode) {
    if (mMultifileBlobCache) {
        checkMultifileCacheSize(mCacheByteLimit);
        mMultifileBlobCache->finish();
    }
    }
    mMultifileMode = false;
    mMultifileBlobCache = nullptr;
    mInitialized = false;
    mInitialized = false;
}
}


@@ -151,20 +169,8 @@ void egl_cache_t::setBlob(const void* key, EGLsizeiANDROID keySize, const void*


    if (mInitialized) {
    if (mInitialized) {
        if (mMultifileMode) {
        if (mMultifileMode) {
            setBlobMultifile(key, keySize, value, valueSize, mFilename);
            MultifileBlobCache* mbc = getMultifileBlobCacheLocked();

            mbc->set(key, keySize, value, valueSize);
            if (!mMultifileCleanupPending) {
                mMultifileCleanupPending = true;
                // Kick off a thread to cull cache files below limit
                std::thread deferredMultifileCleanupThread([this]() {
                    sleep(deferredMultifileCleanupDelaySeconds);
                    std::lock_guard<std::mutex> lock(mMutex);
                    // Check the size of cache and remove entries to stay under limit
                    checkMultifileCacheSize(mCacheByteLimit);
                    mMultifileCleanupPending = false;
                });
                deferredMultifileCleanupThread.detach();
            }
        } else {
        } else {
            BlobCache* bc = getBlobCacheLocked();
            BlobCache* bc = getBlobCacheLocked();
            bc->set(key, keySize, value, valueSize);
            bc->set(key, keySize, value, valueSize);
@@ -172,7 +178,7 @@ void egl_cache_t::setBlob(const void* key, EGLsizeiANDROID keySize, const void*
            if (!mSavePending) {
            if (!mSavePending) {
                mSavePending = true;
                mSavePending = true;
                std::thread deferredSaveThread([this]() {
                std::thread deferredSaveThread([this]() {
                    sleep(deferredSaveDelay);
                    sleep(kDeferredMonolithicSaveDelay);
                    std::lock_guard<std::mutex> lock(mMutex);
                    std::lock_guard<std::mutex> lock(mMutex);
                    if (mInitialized && mBlobCache) {
                    if (mInitialized && mBlobCache) {
                        mBlobCache->writeToFile();
                        mBlobCache->writeToFile();
@@ -196,15 +202,21 @@ EGLsizeiANDROID egl_cache_t::getBlob(const void* key, EGLsizeiANDROID keySize, v


    if (mInitialized) {
    if (mInitialized) {
        if (mMultifileMode) {
        if (mMultifileMode) {
            return getBlobMultifile(key, keySize, value, valueSize, mFilename);
            MultifileBlobCache* mbc = getMultifileBlobCacheLocked();
            return mbc->get(key, keySize, value, valueSize);
        } else {
        } else {
            BlobCache* bc = getBlobCacheLocked();
            BlobCache* bc = getBlobCacheLocked();
            return bc->get(key, keySize, value, valueSize);
            return bc->get(key, keySize, value, valueSize);
        }
        }
    }
    }

    return 0;
    return 0;
}
}


void egl_cache_t::setCacheMode(EGLCacheMode cacheMode) {
    mMultifileMode = (cacheMode == EGLCacheMode::Multifile);
}

void egl_cache_t::setCacheFilename(const char* filename) {
void egl_cache_t::setCacheFilename(const char* filename) {
    std::lock_guard<std::mutex> lock(mMutex);
    std::lock_guard<std::mutex> lock(mMutex);
    mFilename = filename;
    mFilename = filename;
@@ -216,7 +228,7 @@ void egl_cache_t::setCacheLimit(int64_t cacheByteLimit) {
    if (!mMultifileMode) {
    if (!mMultifileMode) {
        // If we're not in multifile mode, ensure the cache limit is only being lowered,
        // If we're not in multifile mode, ensure the cache limit is only being lowered,
        // not increasing above the hard coded platform limit
        // not increasing above the hard coded platform limit
        if (cacheByteLimit > maxTotalSize) {
        if (cacheByteLimit > kMaxMonolithicTotalSize) {
            return;
            return;
        }
        }
    }
    }
@@ -226,8 +238,8 @@ void egl_cache_t::setCacheLimit(int64_t cacheByteLimit) {


size_t egl_cache_t::getCacheSize() {
size_t egl_cache_t::getCacheSize() {
    std::lock_guard<std::mutex> lock(mMutex);
    std::lock_guard<std::mutex> lock(mMutex);
    if (mMultifileMode) {
    if (mMultifileBlobCache) {
        return getMultifileCacheSize();
        return mMultifileBlobCache->getTotalSize();
    }
    }
    if (mBlobCache) {
    if (mBlobCache) {
        return mBlobCache->getSize();
        return mBlobCache->getSize();
@@ -237,9 +249,18 @@ size_t egl_cache_t::getCacheSize() {


BlobCache* egl_cache_t::getBlobCacheLocked() {
BlobCache* egl_cache_t::getBlobCacheLocked() {
    if (mBlobCache == nullptr) {
    if (mBlobCache == nullptr) {
        mBlobCache.reset(new FileBlobCache(maxKeySize, maxValueSize, mCacheByteLimit, mFilename));
        mBlobCache.reset(new FileBlobCache(kMaxMonolithicKeySize, kMaxMonolithicValueSize,
                                           mCacheByteLimit, mFilename));
    }
    }
    return mBlobCache.get();
    return mBlobCache.get();
}
}


MultifileBlobCache* egl_cache_t::getMultifileBlobCacheLocked() {
    if (mMultifileBlobCache == nullptr) {
        mMultifileBlobCache.reset(
                new MultifileBlobCache(mCacheByteLimit, kMultifileHotCacheLimit, mFilename));
    }
    return mMultifileBlobCache.get();
}

}; // namespace android
}; // namespace android
Loading