blob: 4391ac271a363b2f2956e13bfb7040749eda115e [file] [log] [blame]
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +00001//
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
daniel@transgaming.com76d3e6e2012-10-31 19:55:33 +00007// ShaderCache: Defines rx::ShaderCache, a cache of Direct3D shader objects
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +00008// keyed by their byte code.
9
daniel@transgaming.come4733d72012-10-31 18:07:01 +000010#ifndef LIBGLESV2_RENDERER_SHADER_CACHE_H_
11#define LIBGLESV2_RENDERER_SHADER_CACHE_H_
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000012
daniel@transgaming.come4733d72012-10-31 18:07:01 +000013#include "common/debug.h"
14
daniel@transgaming.com76d3e6e2012-10-31 19:55:33 +000015namespace rx
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000016{
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);
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000039 typename Map::iterator it = mMap.find(key);
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000040 if (it != mMap.end())
41 {
42 it->second->AddRef();
43 return it->second;
44 }
daniel@transgaming.come4733d72012-10-31 18:07:01 +000045
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000046 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 {
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000068 for (typename Map::iterator it = mMap.begin(); it != mMap.end(); ++it)
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000069 {
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
daniel@transgaming.comdb2115d2012-08-27 16:25:33 +000091#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;
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +0000100 Map mMap;
101
102 IDirect3DDevice9 *mDevice;
103};
104
105typedef ShaderCache<IDirect3DVertexShader9> VertexShaderCache;
106typedef ShaderCache<IDirect3DPixelShader9> PixelShaderCache;
107
108}
109
daniel@transgaming.come4733d72012-10-31 18:07:01 +0000110#endif // LIBGLESV2_RENDERER_SHADER_CACHE_H_