blob: cfe523ba09fd6f794e3f46b7fb8351baf06676db [file] [log] [blame]
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Display.h: Defines egl::ShaderCache, a cache of Direct3D shader objects
// keyed by their byte code.
#ifndef LIBEGL_SHADER_CACHE_H_
#define LIBEGL_SHADER_CACHE_H_
#include <d3d9.h>
#ifdef _MSC_VER
#include <hash_map>
#else
#include <unordered_map>
#endif
namespace egl
{
template <typename ShaderObject>
class ShaderCache
{
public:
ShaderCache() : mDevice(NULL)
{
}
~ShaderCache()
{
// Call clear while the device is still valid.
ASSERT(mMap.empty());
}
void initialize(IDirect3DDevice9* device)
{
mDevice = device;
}
ShaderObject *create(const DWORD *function, size_t length)
{
std::string key(reinterpret_cast<const char*>(function), length);
typename Map::iterator it = mMap.find(key);
if (it != mMap.end())
{
it->second->AddRef();
return it->second;
}
ShaderObject *shader;
HRESULT result = createShader(function, &shader);
if (FAILED(result))
{
return NULL;
}
// Random eviction policy.
if (mMap.size() >= kMaxMapSize)
{
mMap.begin()->second->Release();
mMap.erase(mMap.begin());
}
shader->AddRef();
mMap[key] = shader;
return shader;
}
void clear()
{
for (typename Map::iterator it = mMap.begin(); it != mMap.end(); ++it)
{
it->second->Release();
}
mMap.clear();
}
private:
DISALLOW_COPY_AND_ASSIGN(ShaderCache);
const static size_t kMaxMapSize = 100;
HRESULT createShader(const DWORD *function, IDirect3DVertexShader9 **shader)
{
return mDevice->CreateVertexShader(function, shader);
}
HRESULT createShader(const DWORD *function, IDirect3DPixelShader9 **shader)
{
return mDevice->CreatePixelShader(function, shader);
}
#ifndef HASH_MAP
# ifdef _MSC_VER
# define HASH_MAP stdext::hash_map
# else
# define HASH_MAP std::unordered_map
# endif
#endif
typedef HASH_MAP<std::string, ShaderObject*> Map;
Map mMap;
IDirect3DDevice9 *mDevice;
};
typedef ShaderCache<IDirect3DVertexShader9> VertexShaderCache;
typedef ShaderCache<IDirect3DPixelShader9> PixelShaderCache;
}
#endif // LIBEGL_SHADER_CACHE_H_