diff options
| -rw-r--r-- | libs/hwui/pipeline/skia/ShaderCache.cpp | 40 | ||||
| -rw-r--r-- | libs/hwui/pipeline/skia/ShaderCache.h | 34 | ||||
| -rw-r--r-- | libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp | 2 |
3 files changed, 75 insertions, 1 deletions
diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp index 562a3b225e36..1661905eff57 100644 --- a/libs/hwui/pipeline/skia/ShaderCache.cpp +++ b/libs/hwui/pipeline/skia/ShaderCache.cpp @@ -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); - saveToDiskLocked(); + // 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 */ diff --git a/libs/hwui/pipeline/skia/ShaderCache.h b/libs/hwui/pipeline/skia/ShaderCache.h index d41aadb269dd..0898017d52a1 100644 --- a/libs/hwui/pipeline/skia/ShaderCache.h +++ b/libs/hwui/pipeline/skia/ShaderCache.h @@ -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(); @@ -167,6 +174,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. */ static ShaderCache sCache; diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp index 1d3a24463057..b9aae9839bdc 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp @@ -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 |