gfx/angle/src/libGLESv2/renderer/InputLayoutCache.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 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 // InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches
     9 // D3D11 input layouts.
    11 #include "libGLESv2/renderer/InputLayoutCache.h"
    12 #include "libGLESv2/renderer/VertexBuffer11.h"
    13 #include "libGLESv2/renderer/BufferStorage11.h"
    14 #include "libGLESv2/renderer/ShaderExecutable11.h"
    15 #include "libGLESv2/ProgramBinary.h"
    16 #include "libGLESv2/Context.h"
    17 #include "libGLESv2/renderer/VertexDataManager.h"
    19 #include "third_party/murmurhash/MurmurHash3.h"
    21 namespace rx
    22 {
    24 const unsigned int InputLayoutCache::kMaxInputLayouts = 1024;
    26 InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts)
    27 {
    28     mCounter = 0;
    29     mDevice = NULL;
    30     mDeviceContext = NULL;
    31     mCurrentIL = NULL;
    32     for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
    33     {
    34         mCurrentBuffers[i] = -1;
    35         mCurrentVertexStrides[i] = -1;
    36         mCurrentVertexOffsets[i] = -1;
    37     }
    38 }
    40 InputLayoutCache::~InputLayoutCache()
    41 {
    42     clear();
    43 }
    45 void InputLayoutCache::initialize(ID3D11Device *device, ID3D11DeviceContext *context)
    46 {
    47     clear();
    48     mDevice = device;
    49     mDeviceContext = context;
    50 }
    52 void InputLayoutCache::clear()
    53 {
    54     for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
    55     {
    56         i->second.inputLayout->Release();
    57     }
    58     mInputLayoutMap.clear();
    59     markDirty();
    60 }
    62 void InputLayoutCache::markDirty()
    63 {
    64     mCurrentIL = NULL;
    65     for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
    66     {
    67         mCurrentBuffers[i] = -1;
    68         mCurrentVertexStrides[i] = -1;
    69         mCurrentVertexOffsets[i] = -1;
    70     }
    71 }
    73 GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
    74                                             gl::ProgramBinary *programBinary)
    75 {
    76     int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS];
    77     programBinary->sortAttributesByLayout(attributes, sortedSemanticIndices);
    79     if (!mDevice || !mDeviceContext)
    80     {
    81         ERR("InputLayoutCache is not initialized.");
    82         return GL_INVALID_OPERATION;
    83     }
    85     InputLayoutKey ilKey = { 0 };
    87     ID3D11Buffer *vertexBuffers[gl::MAX_VERTEX_ATTRIBS] = { NULL };
    88     unsigned int vertexBufferSerials[gl::MAX_VERTEX_ATTRIBS] = { 0 };
    89     UINT vertexStrides[gl::MAX_VERTEX_ATTRIBS] = { 0 };
    90     UINT vertexOffsets[gl::MAX_VERTEX_ATTRIBS] = { 0 };
    92     static const char* semanticName = "TEXCOORD";
    94     for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
    95     {
    96         if (attributes[i].active)
    97         {
    98             VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer);
    99             BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL;
   101             D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
   103             // Record the type of the associated vertex shader vector in our key
   104             // This will prevent mismatched vertex shaders from using the same input layout
   105             GLint attributeSize;
   106             programBinary->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.glslElementType[ilKey.elementCount], NULL);
   108             ilKey.elements[ilKey.elementCount].SemanticName = semanticName;
   109             ilKey.elements[ilKey.elementCount].SemanticIndex = sortedSemanticIndices[i];
   110             ilKey.elements[ilKey.elementCount].Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT;
   111             ilKey.elements[ilKey.elementCount].InputSlot = i;
   112             ilKey.elements[ilKey.elementCount].AlignedByteOffset = 0;
   113             ilKey.elements[ilKey.elementCount].InputSlotClass = inputClass;
   114             ilKey.elements[ilKey.elementCount].InstanceDataStepRate = attributes[i].divisor;
   115             ilKey.elementCount++;
   117             vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer() : vertexBuffer->getBuffer();
   118             vertexBufferSerials[i] = bufferStorage ? bufferStorage->getSerial() : vertexBuffer->getSerial();
   119             vertexStrides[i] = attributes[i].stride;
   120             vertexOffsets[i] = attributes[i].offset;
   121         }
   122     }
   124     ID3D11InputLayout *inputLayout = NULL;
   126     InputLayoutMap::iterator i = mInputLayoutMap.find(ilKey);
   127     if (i != mInputLayoutMap.end())
   128     {
   129         inputLayout = i->second.inputLayout;
   130         i->second.lastUsedTime = mCounter++;
   131     }
   132     else
   133     {
   134         ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable());
   136         HRESULT result = mDevice->CreateInputLayout(ilKey.elements, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout);
   137         if (FAILED(result))
   138         {
   139             ERR("Failed to crate input layout, result: 0x%08x", result);
   140             return GL_INVALID_OPERATION;
   141         }
   143         if (mInputLayoutMap.size() >= kMaxInputLayouts)
   144         {
   145             TRACE("Overflowed the limit of %u input layouts, removing the least recently used "
   146                   "to make room.", kMaxInputLayouts);
   148             InputLayoutMap::iterator leastRecentlyUsed = mInputLayoutMap.begin();
   149             for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
   150             {
   151                 if (i->second.lastUsedTime < leastRecentlyUsed->second.lastUsedTime)
   152                 {
   153                     leastRecentlyUsed = i;
   154                 }
   155             }
   156             leastRecentlyUsed->second.inputLayout->Release();
   157             mInputLayoutMap.erase(leastRecentlyUsed);
   158         }
   160         InputLayoutCounterPair inputCounterPair;
   161         inputCounterPair.inputLayout = inputLayout;
   162         inputCounterPair.lastUsedTime = mCounter++;
   164         mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair));
   165     }
   167     if (inputLayout != mCurrentIL)
   168     {
   169         mDeviceContext->IASetInputLayout(inputLayout);
   170         mCurrentIL = inputLayout;
   171     }
   173     for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
   174     {
   175         if (vertexBufferSerials[i] != mCurrentBuffers[i] || vertexStrides[i] != mCurrentVertexStrides[i] ||
   176             vertexOffsets[i] != mCurrentVertexOffsets[i])
   177         {
   178             mDeviceContext->IASetVertexBuffers(i, 1, &vertexBuffers[i], &vertexStrides[i], &vertexOffsets[i]);
   179             mCurrentBuffers[i] = vertexBufferSerials[i];
   180             mCurrentVertexStrides[i] = vertexStrides[i];
   181             mCurrentVertexOffsets[i] = vertexOffsets[i];
   182         }
   183     }
   185     return GL_NO_ERROR;
   186 }
   188 std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout)
   189 {
   190     static const unsigned int seed = 0xDEADBEEF;
   192     std::size_t hash = 0;
   193     MurmurHash3_x86_32(&inputLayout, sizeof(InputLayoutKey), seed, &hash);
   194     return hash;
   195 }
   197 bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b)
   198 {
   199     return memcmp(&a, &b, sizeof(InputLayoutKey)) == 0;
   200 }
   202 }

mercurial