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

Commit 14211aaf authored by Stan Iliev's avatar Stan Iliev
Browse files

Store VkPipelineCache to ShaderCache

Store vulkan pipeline cache in ShaderCache. Avoid writing to disk
unless pipeline cache size has changed or there was a new shader
compilation.

Test: Ran app startup test. Ran Calc app.
Bug: 122659224
Change-Id: Ie54ea8f0ee9c87387c310b369b2350310e20fa13
parent 266d408d
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "FileBlobCache.h"
#include "Properties.h"
#include "utils/TraceUtils.h"
#include <GrContext.h>

namespace android {
namespace uirenderer {
@@ -168,6 +169,24 @@ void ShaderCache::store(const SkData& key, const SkData& data) {
    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);
        }
        if (mNewPipelineCacheSize != -1 && mNewPipelineCacheSize == valueSize) {
            // There has not been change in pipeline cache size. Stop trying to save.
            mTryToStorePipelineCache = false;
            return;
        }
        mNewPipelineCacheSize = valueSize;
    } else {
        mCacheDirty = true;
        // If there are new shaders compiled, we probably have new pipeline state too.
        // Store pipeline cache on the next flush.
        mNewPipelineCacheSize = -1;
        mTryToStorePipelineCache = true;
    }
    bc->set(key.data(), keySize, value, valueSize);

    if (!mSavePending && mDeferredSaveDelay > 0) {
@@ -175,12 +194,31 @@ void ShaderCache::store(const SkData& key, const SkData& data) {
        std::thread deferredSaveThread([this]() {
            sleep(mDeferredSaveDelay);
            std::lock_guard<std::mutex> lock(mMutex);
            // Store file on disk if there a new shader or Vulkan pipeline cache size changed.
            if (mCacheDirty || mNewPipelineCacheSize != mOldPipelineCacheSize) {
                saveToDiskLocked();
                mOldPipelineCacheSize = mNewPipelineCacheSize;
                mTryToStorePipelineCache = false;
                mCacheDirty = false;
            }
        });
        deferredSaveThread.detach();
    }
}

void ShaderCache::onVkFrameFlushed(GrContext* context) {
    {
        std::lock_guard<std::mutex> lock(mMutex);

        if (!mInitialized || !mTryToStorePipelineCache) {
            return;
        }
    }
    mInStoreVkPipelineInProgress = true;
    context->storeVkPipelineCacheData();
    mInStoreVkPipelineInProgress = false;
}

} /* namespace skiapipeline */
} /* namespace uirenderer */
} /* namespace android */
+34 −0
Original line number Diff line number Diff line
@@ -75,6 +75,13 @@ public:
     */
    void store(const SkData& key, const SkData& data) override;

    /**
     * "onVkFrameFlushed" tries to store Vulkan pipeline cache state.
     * Pipeline cache is saved on disk only if the size of the data has changed or there was
     * a new shader compiled.
     */
    void onVkFrameFlushed(GrContext* context);

private:
    // Creation and (the lack of) destruction is handled internally.
    ShaderCache();
@@ -166,6 +173,33 @@ private:
     */
    mutable std::mutex mMutex;

    /**
     *  If set to "true", the next call to onVkFrameFlushed, will invoke
     * GrCanvas::storeVkPipelineCacheData. This does not guarantee that data will be stored on disk.
     */
    bool mTryToStorePipelineCache = true;

    /**
     * This flag is used by "ShaderCache::store" to distinguish between shader data and
     * Vulkan pipeline data.
     */
    bool mInStoreVkPipelineInProgress = false;

    /**
     *  "mNewPipelineCacheSize" has the size of the new Vulkan pipeline cache data. It is used
     *  to prevent unnecessary disk writes, if the pipeline cache size has not changed.
     */
    size_t mNewPipelineCacheSize = -1;
    /**
     *  "mOldPipelineCacheSize" has the size of the Vulkan pipeline cache data stored on disk.
     */
    size_t mOldPipelineCacheSize = -1;

    /**
     *  "mCacheDirty" is true when there is new shader cache data, which is not saved to disk.
     */
    bool mCacheDirty = false;

    /**
     * "sCache" is the singleton ShaderCache object.
     */
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "VkInteropFunctorDrawable.h"
#include "renderstate/RenderState.h"
#include "renderthread/Frame.h"
#include "ShaderCache.h"

#include <SkSurface.h>
#include <SkTypes.h>
@@ -73,6 +74,7 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, con
    }
    SkiaPipeline::updateLighting(lightGeometry, lightInfo);
    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer);
    ShaderCache::get().onVkFrameFlushed(mRenderThread.getGrContext());
    layerUpdateQueue->clear();

    // Draw visual debugging features