Home | History | Annotate | Download | only in d3d9
      1 //
      2 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // ShaderCache: Defines rx::ShaderCache, a cache of Direct3D shader objects
      8 // keyed by their byte code.
      9 
     10 #ifndef LIBGLESV2_RENDERER_SHADER_CACHE_H_
     11 #define LIBGLESV2_RENDERER_SHADER_CACHE_H_
     12 
     13 #include "common/debug.h"
     14 
     15 #include <cstddef>
     16 #include <unordered_map>
     17 #include <string>
     18 
     19 namespace rx
     20 {
     21 template <typename ShaderObject>
     22 class ShaderCache
     23 {
     24   public:
     25     ShaderCache() : mDevice(NULL)
     26     {
     27     }
     28 
     29     ~ShaderCache()
     30     {
     31         // Call clear while the device is still valid.
     32         ASSERT(mMap.empty());
     33     }
     34 
     35     void initialize(IDirect3DDevice9* device)
     36     {
     37         mDevice = device;
     38     }
     39 
     40     ShaderObject *create(const DWORD *function, size_t length)
     41     {
     42         std::string key(reinterpret_cast<const char*>(function), length);
     43         typename Map::iterator it = mMap.find(key);
     44         if (it != mMap.end())
     45         {
     46             it->second->AddRef();
     47             return it->second;
     48         }
     49 
     50         ShaderObject *shader;
     51         HRESULT result = createShader(function, &shader);
     52         if (FAILED(result))
     53         {
     54             return NULL;
     55         }
     56 
     57         // Random eviction policy.
     58         if (mMap.size() >= kMaxMapSize)
     59         {
     60             SafeRelease(mMap.begin()->second);
     61             mMap.erase(mMap.begin());
     62         }
     63 
     64         shader->AddRef();
     65         mMap[key] = shader;
     66 
     67         return shader;
     68     }
     69 
     70     void clear()
     71     {
     72         for (typename Map::iterator it = mMap.begin(); it != mMap.end(); ++it)
     73         {
     74             SafeRelease(it->second);
     75         }
     76 
     77         mMap.clear();
     78     }
     79 
     80   private:
     81     DISALLOW_COPY_AND_ASSIGN(ShaderCache);
     82 
     83     const static size_t kMaxMapSize = 100;
     84 
     85     HRESULT createShader(const DWORD *function, IDirect3DVertexShader9 **shader)
     86     {
     87         return mDevice->CreateVertexShader(function, shader);
     88     }
     89 
     90     HRESULT createShader(const DWORD *function, IDirect3DPixelShader9 **shader)
     91     {
     92         return mDevice->CreatePixelShader(function, shader);
     93     }
     94 
     95     typedef std::unordered_map<std::string, ShaderObject*> Map;
     96     Map mMap;
     97 
     98     IDirect3DDevice9 *mDevice;
     99 };
    100 
    101 typedef ShaderCache<IDirect3DVertexShader9> VertexShaderCache;
    102 typedef ShaderCache<IDirect3DPixelShader9> PixelShaderCache;
    103 
    104 }
    105 
    106 #endif   // LIBGLESV2_RENDERER_SHADER_CACHE_H_
    107