gfx/angle/src/libGLESv2/renderer/RenderStateCache.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 #include "precompiled.h"
     2 //
     3 // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
     4 // Use of this source code is governed by a BSD-style license that can be
     5 // found in the LICENSE file.
     6 //
     8 // RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render
     9 // state objects.
    11 #include "libGLESv2/renderer/RenderStateCache.h"
    12 #include "libGLESv2/renderer/renderer11_utils.h"
    14 #include "common/debug.h"
    15 #include "third_party/murmurhash/MurmurHash3.h"
    17 namespace rx
    18 {
    20 // MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState,
    21 // ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum
    22 // number of unique states of each type an application can create is 4096
    23 const unsigned int RenderStateCache::kMaxBlendStates = 4096;
    24 const unsigned int RenderStateCache::kMaxRasterizerStates = 4096;
    25 const unsigned int RenderStateCache::kMaxDepthStencilStates = 4096;
    26 const unsigned int RenderStateCache::kMaxSamplerStates = 4096;
    28 RenderStateCache::RenderStateCache() : mDevice(NULL), mCounter(0),
    29                                        mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates),
    30                                        mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates),
    31                                        mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates),
    32                                        mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates)
    33 {
    34 }
    36 RenderStateCache::~RenderStateCache()
    37 {
    38     clear();
    39 }
    41 void RenderStateCache::initialize(ID3D11Device *device)
    42 {
    43     clear();
    44     mDevice = device;
    45 }
    47 void RenderStateCache::clear()
    48 {
    49     for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++)
    50     {
    51         i->second.first->Release();
    52     }
    53     mBlendStateCache.clear();
    55     for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++)
    56     {
    57         i->second.first->Release();
    58     }
    59     mRasterizerStateCache.clear();
    61     for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
    62     {
    63         i->second.first->Release();
    64     }
    65     mDepthStencilStateCache.clear();
    67     for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++)
    68     {
    69         i->second.first->Release();
    70     }
    71     mSamplerStateCache.clear();
    72 }
    74 std::size_t RenderStateCache::hashBlendState(const gl::BlendState &blendState)
    75 {
    76     static const unsigned int seed = 0xABCDEF98;
    78     std::size_t hash = 0;
    79     MurmurHash3_x86_32(&blendState, sizeof(gl::BlendState), seed, &hash);
    80     return hash;
    81 }
    83 bool RenderStateCache::compareBlendStates(const gl::BlendState &a, const gl::BlendState &b)
    84 {
    85     return memcmp(&a, &b, sizeof(gl::BlendState)) == 0;
    86 }
    88 ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendState)
    89 {
    90     if (!mDevice)
    91     {
    92         ERR("RenderStateCache is not initialized.");
    93         return NULL;
    94     }
    96     BlendStateMap::iterator i = mBlendStateCache.find(blendState);
    97     if (i != mBlendStateCache.end())
    98     {
    99         BlendStateCounterPair &state = i->second;
   100         state.second = mCounter++;
   101         return state.first;
   102     }
   103     else
   104     {
   105         if (mBlendStateCache.size() >= kMaxBlendStates)
   106         {
   107             TRACE("Overflowed the limit of %u blend states, removing the least recently used "
   108                   "to make room.", kMaxBlendStates);
   110             BlendStateMap::iterator leastRecentlyUsed = mBlendStateCache.begin();
   111             for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++)
   112             {
   113                 if (i->second.second < leastRecentlyUsed->second.second)
   114                 {
   115                     leastRecentlyUsed = i;
   116                 }
   117             }
   118             leastRecentlyUsed->second.first->Release();
   119             mBlendStateCache.erase(leastRecentlyUsed);
   120         }
   122         // Create a new blend state and insert it into the cache
   123         D3D11_BLEND_DESC blendDesc = { 0 };
   124         blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage;
   125         blendDesc.IndependentBlendEnable = FALSE;
   127         for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
   128         {
   129             D3D11_RENDER_TARGET_BLEND_DESC &rtBlend = blendDesc.RenderTarget[i];
   131             rtBlend.BlendEnable = blendState.blend;
   132             if (blendState.blend)
   133             {
   134                 rtBlend.SrcBlend = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendRGB, false);
   135                 rtBlend.DestBlend = gl_d3d11::ConvertBlendFunc(blendState.destBlendRGB, false);
   136                 rtBlend.BlendOp = gl_d3d11::ConvertBlendOp(blendState.blendEquationRGB);
   138                 rtBlend.SrcBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendAlpha, true);
   139                 rtBlend.DestBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.destBlendAlpha, true);
   140                 rtBlend.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha);
   141             }
   143             rtBlend.RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendState.colorMaskRed,
   144                                                                        blendState.colorMaskGreen,
   145                                                                        blendState.colorMaskBlue,
   146                                                                        blendState.colorMaskAlpha);
   147         }
   149         ID3D11BlendState *dx11BlendState = NULL;
   150         HRESULT result = mDevice->CreateBlendState(&blendDesc, &dx11BlendState);
   151         if (FAILED(result) || !dx11BlendState)
   152         {
   153             ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result);
   154             return NULL;
   155         }
   157         mBlendStateCache.insert(std::make_pair(blendState, std::make_pair(dx11BlendState, mCounter++)));
   159         return dx11BlendState;
   160     }
   161 }
   163 std::size_t RenderStateCache::hashRasterizerState(const RasterizerStateKey &rasterState)
   164 {
   165     static const unsigned int seed = 0xABCDEF98;
   167     std::size_t hash = 0;
   168     MurmurHash3_x86_32(&rasterState, sizeof(RasterizerStateKey), seed, &hash);
   169     return hash;
   170 }
   172 bool RenderStateCache::compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b)
   173 {
   174     return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0;
   175 }
   177 ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState,
   178                                                             bool scissorEnabled, unsigned int depthSize)
   179 {
   180     if (!mDevice)
   181     {
   182         ERR("RenderStateCache is not initialized.");
   183         return NULL;
   184     }
   186     RasterizerStateKey key;
   187     key.rasterizerState = rasterState;
   188     key.scissorEnabled = scissorEnabled;
   189     key.depthSize = depthSize;
   191     RasterizerStateMap::iterator i = mRasterizerStateCache.find(key);
   192     if (i != mRasterizerStateCache.end())
   193     {
   194         RasterizerStateCounterPair &state = i->second;
   195         state.second = mCounter++;
   196         return state.first;
   197     }
   198     else
   199     {
   200         if (mRasterizerStateCache.size() >= kMaxRasterizerStates)
   201         {
   202             TRACE("Overflowed the limit of %u rasterizer states, removing the least recently used "
   203                   "to make room.", kMaxRasterizerStates);
   205             RasterizerStateMap::iterator leastRecentlyUsed = mRasterizerStateCache.begin();
   206             for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++)
   207             {
   208                 if (i->second.second < leastRecentlyUsed->second.second)
   209                 {
   210                     leastRecentlyUsed = i;
   211                 }
   212             }
   213             leastRecentlyUsed->second.first->Release();
   214             mRasterizerStateCache.erase(leastRecentlyUsed);
   215         }
   217         D3D11_CULL_MODE cullMode = gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode);
   219         // Disable culling if drawing points
   220         if (rasterState.pointDrawMode)
   221         {
   222             cullMode = D3D11_CULL_NONE;
   223         }
   225         D3D11_RASTERIZER_DESC rasterDesc;
   226         rasterDesc.FillMode = D3D11_FILL_SOLID;
   227         rasterDesc.CullMode = cullMode;
   228         rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE: TRUE;
   229         rasterDesc.DepthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast<int>(depthSize));
   230         rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of zero will preform no clamping, must be tested though.
   231         rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor;
   232         rasterDesc.DepthClipEnable = TRUE;
   233         rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE;
   234         rasterDesc.MultisampleEnable = rasterState.multiSample;
   235         rasterDesc.AntialiasedLineEnable = FALSE;
   237         ID3D11RasterizerState *dx11RasterizerState = NULL;
   238         HRESULT result = mDevice->CreateRasterizerState(&rasterDesc, &dx11RasterizerState);
   239         if (FAILED(result) || !dx11RasterizerState)
   240         {
   241             ERR("Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result);
   242             return NULL;
   243         }
   245         mRasterizerStateCache.insert(std::make_pair(key, std::make_pair(dx11RasterizerState, mCounter++)));
   247         return dx11RasterizerState;
   248     }
   249 }
   251 std::size_t RenderStateCache::hashDepthStencilState(const gl::DepthStencilState &dsState)
   252 {
   253     static const unsigned int seed = 0xABCDEF98;
   255     std::size_t hash = 0;
   256     MurmurHash3_x86_32(&dsState, sizeof(gl::DepthStencilState), seed, &hash);
   257     return hash;
   258 }
   260 bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b)
   261 {
   262     return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0;
   263 }
   265 ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState)
   266 {
   267     if (!mDevice)
   268     {
   269         ERR("RenderStateCache is not initialized.");
   270         return NULL;
   271     }
   273     DepthStencilStateMap::iterator i = mDepthStencilStateCache.find(dsState);
   274     if (i != mDepthStencilStateCache.end())
   275     {
   276         DepthStencilStateCounterPair &state = i->second;
   277         state.second = mCounter++;
   278         return state.first;
   279     }
   280     else
   281     {
   282         if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates)
   283         {
   284             TRACE("Overflowed the limit of %u depth stencil states, removing the least recently used "
   285                   "to make room.", kMaxDepthStencilStates);
   287             DepthStencilStateMap::iterator leastRecentlyUsed = mDepthStencilStateCache.begin();
   288             for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
   289             {
   290                 if (i->second.second < leastRecentlyUsed->second.second)
   291                 {
   292                     leastRecentlyUsed = i;
   293                 }
   294             }
   295             leastRecentlyUsed->second.first->Release();
   296             mDepthStencilStateCache.erase(leastRecentlyUsed);
   297         }
   299         D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 };
   300         dsDesc.DepthEnable = dsState.depthTest ? TRUE : FALSE;
   301         dsDesc.DepthWriteMask = gl_d3d11::ConvertDepthMask(dsState.depthMask);
   302         dsDesc.DepthFunc = gl_d3d11::ConvertComparison(dsState.depthFunc);
   303         dsDesc.StencilEnable = dsState.stencilTest ? TRUE : FALSE;
   304         dsDesc.StencilReadMask = gl_d3d11::ConvertStencilMask(dsState.stencilMask);
   305         dsDesc.StencilWriteMask = gl_d3d11::ConvertStencilMask(dsState.stencilWritemask);
   306         dsDesc.FrontFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilFail);
   307         dsDesc.FrontFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthFail);
   308         dsDesc.FrontFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthPass);
   309         dsDesc.FrontFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilFunc);
   310         dsDesc.BackFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackFail);
   311         dsDesc.BackFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthFail);
   312         dsDesc.BackFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthPass);
   313         dsDesc.BackFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilBackFunc);
   315         ID3D11DepthStencilState *dx11DepthStencilState = NULL;
   316         HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState);
   317         if (FAILED(result) || !dx11DepthStencilState)
   318         {
   319             ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
   320             return NULL;
   321         }
   323         mDepthStencilStateCache.insert(std::make_pair(dsState, std::make_pair(dx11DepthStencilState, mCounter++)));
   325         return dx11DepthStencilState;
   326     }
   327 }
   329 std::size_t RenderStateCache::hashSamplerState(const gl::SamplerState &samplerState)
   330 {
   331     static const unsigned int seed = 0xABCDEF98;
   333     std::size_t hash = 0;
   334     MurmurHash3_x86_32(&samplerState, sizeof(gl::SamplerState), seed, &hash);
   335     return hash;
   336 }
   338 bool RenderStateCache::compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b)
   339 {
   340     return memcmp(&a, &b, sizeof(gl::SamplerState)) == 0;
   341 }
   343 ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &samplerState)
   344 {
   345     if (!mDevice)
   346     {
   347         ERR("RenderStateCache is not initialized.");
   348         return NULL;
   349     }
   351     SamplerStateMap::iterator i = mSamplerStateCache.find(samplerState);
   352     if (i != mSamplerStateCache.end())
   353     {
   354         SamplerStateCounterPair &state = i->second;
   355         state.second = mCounter++;
   356         return state.first;
   357     }
   358     else
   359     {
   360         if (mSamplerStateCache.size() >= kMaxSamplerStates)
   361         {
   362             TRACE("Overflowed the limit of %u sampler states, removing the least recently used "
   363                   "to make room.", kMaxSamplerStates);
   365             SamplerStateMap::iterator leastRecentlyUsed = mSamplerStateCache.begin();
   366             for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++)
   367             {
   368                 if (i->second.second < leastRecentlyUsed->second.second)
   369                 {
   370                     leastRecentlyUsed = i;
   371                 }
   372             }
   373             leastRecentlyUsed->second.first->Release();
   374             mSamplerStateCache.erase(leastRecentlyUsed);
   375         }
   377         D3D11_SAMPLER_DESC samplerDesc;
   378         samplerDesc.Filter = gl_d3d11::ConvertFilter(samplerState.minFilter, samplerState.magFilter, samplerState.maxAnisotropy);
   379         samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.wrapS);
   380         samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.wrapT);
   381         samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
   382         samplerDesc.MipLODBias = static_cast<float>(samplerState.lodOffset);
   383         samplerDesc.MaxAnisotropy = samplerState.maxAnisotropy;
   384         samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
   385         samplerDesc.BorderColor[0] = 0.0f;
   386         samplerDesc.BorderColor[1] = 0.0f;
   387         samplerDesc.BorderColor[2] = 0.0f;
   388         samplerDesc.BorderColor[3] = 0.0f;
   389         samplerDesc.MinLOD = gl_d3d11::ConvertMinLOD(samplerState.minFilter, samplerState.lodOffset);
   390         samplerDesc.MaxLOD = gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset);
   392         ID3D11SamplerState *dx11SamplerState = NULL;
   393         HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState);
   394         if (FAILED(result) || !dx11SamplerState)
   395         {
   396             ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
   397             return NULL;
   398         }
   400         mSamplerStateCache.insert(std::make_pair(samplerState, std::make_pair(dx11SamplerState, mCounter++)));
   402         return dx11SamplerState;
   403     }
   404 }
   406 }

mercurial