tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ShaderCache.h (2854B)


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