blob: cfe523ba09fd6f794e3f46b7fb8351baf06676db [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
7// Display.h: Defines egl::ShaderCache, a cache of Direct3D shader objects
8// keyed by their byte code.
9
10#ifndef LIBEGL_SHADER_CACHE_H_
11#define LIBEGL_SHADER_CACHE_H_
12
13#include <d3d9.h>
daniel@transgaming.comdb2115d2012-08-27 16:25:33 +000014
15#ifdef _MSC_VER
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000016#include <hash_map>
daniel@transgaming.comdb2115d2012-08-27 16:25:33 +000017#else
18#include <unordered_map>
19#endif
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000020
21namespace egl
22{
23template <typename ShaderObject>
24class 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 ShaderObject *create(const DWORD *function, size_t length)
43 {
44 std::string key(reinterpret_cast<const char*>(function), length);
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000045 typename Map::iterator it = mMap.find(key);
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000046 if (it != mMap.end())
47 {
48 it->second->AddRef();
49 return it->second;
50 }
51
52 ShaderObject *shader;
53 HRESULT result = createShader(function, &shader);
54 if (FAILED(result))
55 {
56 return NULL;
57 }
58
59 // Random eviction policy.
60 if (mMap.size() >= kMaxMapSize)
61 {
62 mMap.begin()->second->Release();
63 mMap.erase(mMap.begin());
64 }
65
66 shader->AddRef();
67 mMap[key] = shader;
68
69 return shader;
70 }
71
72 void clear()
73 {
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000074 for (typename Map::iterator it = mMap.begin(); it != mMap.end(); ++it)
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +000075 {
76 it->second->Release();
77 }
78
79 mMap.clear();
80 }
81
82 private:
83 DISALLOW_COPY_AND_ASSIGN(ShaderCache);
84
85 const static size_t kMaxMapSize = 100;
86
87 HRESULT createShader(const DWORD *function, IDirect3DVertexShader9 **shader)
88 {
89 return mDevice->CreateVertexShader(function, shader);
90 }
91
92 HRESULT createShader(const DWORD *function, IDirect3DPixelShader9 **shader)
93 {
94 return mDevice->CreatePixelShader(function, shader);
95 }
96
daniel@transgaming.comdb2115d2012-08-27 16:25:33 +000097#ifndef HASH_MAP
98# ifdef _MSC_VER
99# define HASH_MAP stdext::hash_map
100# else
101# define HASH_MAP std::unordered_map
102# endif
103#endif
104
105 typedef HASH_MAP<std::string, ShaderObject*> Map;
apatrick@chromium.org3cfd7222012-07-13 22:36:58 +0000106 Map mMap;
107
108 IDirect3DDevice9 *mDevice;
109};
110
111typedef ShaderCache<IDirect3DVertexShader9> VertexShaderCache;
112typedef ShaderCache<IDirect3DPixelShader9> PixelShaderCache;
113
114}
115
116#endif // LIBEGL_SHADER_CACHE_H_