blob: 8a20c8b8baa327ef6c1ac2242a01c3f1ab469064 [file] [log] [blame]
// Copyright (C) 2021 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 "ShaderCache.h"
#include "aemu/base/MruCache.h"
#include <string.h>
#include <cstdio>
#include <map>
#include <vector>
namespace {
using BlobCacheType = std::vector<uint8_t>;
template <class K, class V>
class CacheObserver : android::base::MruCache<K, V>::MruCacheObserver {
public:
int count = 0;
CacheObserver(android::base::MruCache<K, V>* cacheReference) {
mCacheRef = cacheReference;
cacheReference->setObserver(this);
}
void cacheChanged() override {
// TODO: This will dictate when we flatten the cache.
}
private:
android::base::MruCache<K, V>* mCacheRef;
};
template <class K, class V>
class CacheFlattener : public android::base::MruCache<K, V>::CacheFlattener {
using MruCache = std::map<typename android::base::MruCache<K, V>::template EntryWithSize<K>,
typename android::base::MruCache<K, V>::template EntryWithSize<V>>;
public:
void handleFlatten(MruCache &mCache, void* buf, size_t bufSize) {
// TODO: This will handle the actual serialization.
}
};
CacheFlattener<BlobCacheType, BlobCacheType> testFlattener;
// 3200 is ~32MB of shaders, very rough estimate.
android::base::MruCache<BlobCacheType, BlobCacheType> mruCache(3200, &testFlattener);
CacheObserver<BlobCacheType, BlobCacheType> sss(&mruCache);
}
void SetBlob(const void* key, EGLsizeiANDROID keySize, const void* value, EGLsizeiANDROID valueSize) {
std::vector<uint8_t> keyVec(keySize);
memcpy(keyVec.data(), key, keySize);
std::vector<uint8_t> valueVec(valueSize);
memcpy(valueVec.data(), value, valueSize);
mruCache.put(keyVec, keySize, std::move(valueVec), valueSize);
}
EGLsizeiANDROID GetBlob(const void* key, EGLsizeiANDROID keySize, void* value, EGLsizeiANDROID valueSize) {
std::vector<uint8_t> keyVec(keySize);
memcpy(keyVec.data(), key, keySize);
const std::vector<uint8_t> *result;
auto found = mruCache.get(keyVec, &result);
if (!found) {
return 0;
}
if (result->size() <= static_cast<size_t>(valueSize)) {
memcpy(value, result->data(), result->size());
}
// If the size provided was too small, return the right size regardless.
return result->size();
}