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