// // 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 #ifdef _MSC_VER #include #else #include #endif namespace egl { template 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(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 Map; Map mMap; IDirect3DDevice9 *mDevice; }; typedef ShaderCache VertexShaderCache; typedef ShaderCache PixelShaderCache; } #endif // LIBEGL_SHADER_CACHE_H_