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
15namespace rx
16{
17template <typename ShaderObject>
18class ShaderCache
19{
20  public:
21    ShaderCache() : mDevice(NULL)
22    {
23    }
24
25    ~ShaderCache()
26    {
27        // Call clear while the device is still valid.
28        ASSERT(mMap.empty());
29    }
30
31    void initialize(IDirect3DDevice9* device)
32    {
33        mDevice = device;
34    }
35
36    ShaderObject *create(const DWORD *function, size_t length)
37    {
38        std::string key(reinterpret_cast<const char*>(function), length);
39        typename Map::iterator it = mMap.find(key);
40        if (it != mMap.end())
41        {
42            it->second->AddRef();
43            return it->second;
44        }
45
46        ShaderObject *shader;
47        HRESULT result = createShader(function, &shader);
48        if (FAILED(result))
49        {
50            return NULL;
51        }
52
53        // Random eviction policy.
54        if (mMap.size() >= kMaxMapSize)
55        {
56            SafeRelease(mMap.begin()->second);
57            mMap.erase(mMap.begin());
58        }
59
60        shader->AddRef();
61        mMap[key] = shader;
62
63        return shader;
64    }
65
66    void clear()
67    {
68        for (typename Map::iterator it = mMap.begin(); it != mMap.end(); ++it)
69        {
70            SafeRelease(it->second);
71        }
72
73        mMap.clear();
74    }
75
76  private:
77    DISALLOW_COPY_AND_ASSIGN(ShaderCache);
78
79    const static size_t kMaxMapSize = 100;
80
81    HRESULT createShader(const DWORD *function, IDirect3DVertexShader9 **shader)
82    {
83        return mDevice->CreateVertexShader(function, shader);
84    }
85
86    HRESULT createShader(const DWORD *function, IDirect3DPixelShader9 **shader)
87    {
88        return mDevice->CreatePixelShader(function, shader);
89    }
90
91    typedef std::unordered_map<std::string, ShaderObject*> Map;
92    Map mMap;
93
94    IDirect3DDevice9 *mDevice;
95};
96
97typedef ShaderCache<IDirect3DVertexShader9> VertexShaderCache;
98typedef ShaderCache<IDirect3DPixelShader9> PixelShaderCache;
99
100}
101
102#endif   // LIBGLESV2_RENDERER_SHADER_CACHE_H_
103