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