blob: 500c87862182113df20e5c90ceb7756f58cd20a4 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GPU_IPC_HOST_SHADER_DISK_CACHE_H_
#define GPU_IPC_HOST_SHADER_DISK_CACHE_H_
#include <stdint.h>
#include <map>
#include <string>
#include <unordered_map>
#include "base/containers/queue.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "net/base/completion_callback.h"
#include "net/disk_cache/disk_cache.h"
namespace gpu {
class ShaderCacheFactory;
class ShaderDiskCacheEntry;
class ShaderDiskReadHelper;
class ShaderClearHelper;
// ShaderDiskCache is the interface to the on disk cache for
// GL shaders.
class ShaderDiskCache : public base::RefCounted<ShaderDiskCache> {
public:
using ShaderLoadedCallback =
base::RepeatingCallback<void(const std::string&, const std::string&)>;
void set_shader_loaded_callback(const ShaderLoadedCallback& callback) {
shader_loaded_callback_ = callback;
}
// Store the |shader| into the cache under |key|.
void Cache(const std::string& key, const std::string& shader);
// Clear a range of entries. This supports unbounded deletes in either
// direction by using null Time values for either |begin_time| or |end_time|.
// The return value is a net error code. If this method returns
// ERR_IO_PENDING, the |completion_callback| will be invoked when the
// operation completes.
int Clear(const base::Time begin_time,
const base::Time end_time,
const net::CompletionCallback& completion_callback);
// Sets a callback for when the cache is available. If the cache is
// already available the callback will not be called and net::OK is returned.
// If the callback is set net::ERR_IO_PENDING is returned and the callback
// will be executed when the cache is available.
int SetAvailableCallback(const net::CompletionCallback& callback);
// Returns the number of elements currently in the cache.
int32_t Size();
// Set a callback notification for when all current entries have been
// written to the cache.
// The return value is a net error code. If this method returns
// ERR_IO_PENDING, the |callback| will be invoked when all entries have
// been written to the cache.
int SetCacheCompleteCallback(const net::CompletionCallback& callback);
// Returns the size which should be used for the shader disk cache.
static size_t CacheSizeBytes();
private:
friend class base::RefCounted<ShaderDiskCache>;
friend class ShaderDiskCacheEntry;
friend class ShaderDiskReadHelper;
friend class ShaderCacheFactory;
ShaderDiskCache(ShaderCacheFactory* factory,
const base::FilePath& cache_path);
~ShaderDiskCache();
void Init();
void CacheCreatedCallback(int rv);
disk_cache::Backend* backend() { return backend_.get(); }
void EntryComplete(ShaderDiskCacheEntry* entry);
void ReadComplete();
ShaderCacheFactory* factory_;
bool cache_available_;
base::FilePath cache_path_;
bool is_initialized_;
net::CompletionCallback available_callback_;
net::CompletionCallback cache_complete_callback_;
ShaderLoadedCallback shader_loaded_callback_;
std::unique_ptr<disk_cache::Backend> backend_;
std::unique_ptr<ShaderDiskReadHelper> helper_;
std::unordered_map<ShaderDiskCacheEntry*,
std::unique_ptr<ShaderDiskCacheEntry>>
entries_;
DISALLOW_COPY_AND_ASSIGN(ShaderDiskCache);
};
// ShaderCacheFactory maintains a cache of ShaderDiskCache objects
// so we only create one per profile directory.
class ShaderCacheFactory : public base::ThreadChecker {
public:
ShaderCacheFactory();
~ShaderCacheFactory();
// Clear the shader disk cache for the given |path|. This supports unbounded
// deletes in either direction by using null Time values for either
// |begin_time| or |end_time|. The |callback| will be executed when the
// clear is complete.
void ClearByPath(const base::FilePath& path,
const base::Time& begin_time,
const base::Time& end_time,
base::OnceClosure callback);
// Same as ClearByPath, but looks up the cache by |client_id|. The |callback|
// will be executed when the clear is complete.
void ClearByClientId(int32_t client_id,
const base::Time& begin_time,
const base::Time& end_time,
base::OnceClosure callback);
// Retrieve the shader disk cache for the provided |client_id|.
scoped_refptr<ShaderDiskCache> Get(int32_t client_id);
// Set the |path| to be used for the disk cache for |client_id|.
void SetCacheInfo(int32_t client_id, const base::FilePath& path);
// Remove the path mapping for |client_id|.
void RemoveCacheInfo(int32_t client_id);
// Set the provided |cache| into the cache map for the given |path|.
void AddToCache(const base::FilePath& path, ShaderDiskCache* cache);
// Remove the provided |path| from our cache map.
void RemoveFromCache(const base::FilePath& path);
private:
friend class ShaderClearHelper;
scoped_refptr<ShaderDiskCache> GetByPath(const base::FilePath& path);
void CacheCleared(const base::FilePath& path);
using ShaderCacheMap = std::map<base::FilePath, ShaderDiskCache*>;
ShaderCacheMap shader_cache_map_;
using ClientIdToPathMap = std::map<int32_t, base::FilePath>;
ClientIdToPathMap client_id_to_path_map_;
using ShaderClearQueue = base::queue<std::unique_ptr<ShaderClearHelper>>;
using ShaderClearMap = std::map<base::FilePath, ShaderClearQueue>;
ShaderClearMap shader_clear_map_;
DISALLOW_COPY_AND_ASSIGN(ShaderCacheFactory);
};
} // namespace gpu
#endif // GPU_IPC_HOST_SHADER_DISK_CACHE_H_