|
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 namespace rx |
|
16 { |
|
17 template <typename ShaderObject> |
|
18 class 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 mMap.begin()->second->Release(); |
|
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 it->second->Release(); |
|
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 #ifndef HASH_MAP |
|
92 # ifdef _MSC_VER |
|
93 # define HASH_MAP stdext::hash_map |
|
94 # else |
|
95 # define HASH_MAP std::unordered_map |
|
96 # endif |
|
97 #endif |
|
98 |
|
99 typedef HASH_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_ |