gfx/angle/src/libGLESv2/renderer/BufferStorage11.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.

michael@0 1 #include "precompiled.h"
michael@0 2 //
michael@0 3 // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
michael@0 4 // Use of this source code is governed by a BSD-style license that can be
michael@0 5 // found in the LICENSE file.
michael@0 6 //
michael@0 7
michael@0 8 // BufferStorage11.cpp Defines the BufferStorage11 class.
michael@0 9
michael@0 10 #include "libGLESv2/renderer/BufferStorage11.h"
michael@0 11 #include "libGLESv2/main.h"
michael@0 12 #include "libGLESv2/renderer/Renderer11.h"
michael@0 13
michael@0 14 namespace rx
michael@0 15 {
michael@0 16
michael@0 17 BufferStorage11::BufferStorage11(Renderer11 *renderer)
michael@0 18 {
michael@0 19 mRenderer = renderer;
michael@0 20
michael@0 21 mStagingBuffer = NULL;
michael@0 22 mStagingBufferSize = 0;
michael@0 23
michael@0 24 mBuffer = NULL;
michael@0 25 mBufferSize = 0;
michael@0 26
michael@0 27 mSize = 0;
michael@0 28
michael@0 29 mResolvedData = NULL;
michael@0 30 mResolvedDataSize = 0;
michael@0 31 mResolvedDataValid = false;
michael@0 32
michael@0 33 mReadUsageCount = 0;
michael@0 34 mWriteUsageCount = 0;
michael@0 35 }
michael@0 36
michael@0 37 BufferStorage11::~BufferStorage11()
michael@0 38 {
michael@0 39 if (mStagingBuffer)
michael@0 40 {
michael@0 41 mStagingBuffer->Release();
michael@0 42 mStagingBuffer = NULL;
michael@0 43 }
michael@0 44
michael@0 45 if (mBuffer)
michael@0 46 {
michael@0 47 mBuffer->Release();
michael@0 48 mBuffer = NULL;
michael@0 49 }
michael@0 50
michael@0 51 if (mResolvedData)
michael@0 52 {
michael@0 53 free(mResolvedData);
michael@0 54 mResolvedData = NULL;
michael@0 55 }
michael@0 56 }
michael@0 57
michael@0 58 BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage)
michael@0 59 {
michael@0 60 ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage));
michael@0 61 return static_cast<BufferStorage11*>(bufferStorage);
michael@0 62 }
michael@0 63
michael@0 64 void *BufferStorage11::getData()
michael@0 65 {
michael@0 66 if (!mResolvedDataValid)
michael@0 67 {
michael@0 68 ID3D11Device *device = mRenderer->getDevice();
michael@0 69 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
michael@0 70 HRESULT result;
michael@0 71
michael@0 72 if (!mStagingBuffer || mStagingBufferSize < mBufferSize)
michael@0 73 {
michael@0 74 if (mStagingBuffer)
michael@0 75 {
michael@0 76 mStagingBuffer->Release();
michael@0 77 mStagingBuffer = NULL;
michael@0 78 mStagingBufferSize = 0;
michael@0 79 }
michael@0 80
michael@0 81 D3D11_BUFFER_DESC bufferDesc;
michael@0 82 bufferDesc.ByteWidth = mSize;
michael@0 83 bufferDesc.Usage = D3D11_USAGE_STAGING;
michael@0 84 bufferDesc.BindFlags = 0;
michael@0 85 bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
michael@0 86 bufferDesc.MiscFlags = 0;
michael@0 87 bufferDesc.StructureByteStride = 0;
michael@0 88
michael@0 89 result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer);
michael@0 90 if (FAILED(result))
michael@0 91 {
michael@0 92 return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
michael@0 93 }
michael@0 94
michael@0 95 mStagingBufferSize = bufferDesc.ByteWidth;
michael@0 96 }
michael@0 97
michael@0 98 if (!mResolvedData || mResolvedDataSize < mBufferSize)
michael@0 99 {
michael@0 100 free(mResolvedData);
michael@0 101 mResolvedData = malloc(mSize);
michael@0 102 mResolvedDataSize = mSize;
michael@0 103 }
michael@0 104
michael@0 105 D3D11_BOX srcBox;
michael@0 106 srcBox.left = 0;
michael@0 107 srcBox.right = mSize;
michael@0 108 srcBox.top = 0;
michael@0 109 srcBox.bottom = 1;
michael@0 110 srcBox.front = 0;
michael@0 111 srcBox.back = 1;
michael@0 112
michael@0 113 context->CopySubresourceRegion(mStagingBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox);
michael@0 114
michael@0 115 D3D11_MAPPED_SUBRESOURCE mappedResource;
michael@0 116 result = context->Map(mStagingBuffer, 0, D3D11_MAP_READ, 0, &mappedResource);
michael@0 117 if (FAILED(result))
michael@0 118 {
michael@0 119 return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
michael@0 120 }
michael@0 121
michael@0 122 memcpy(mResolvedData, mappedResource.pData, mSize);
michael@0 123
michael@0 124 context->Unmap(mStagingBuffer, 0);
michael@0 125
michael@0 126 mResolvedDataValid = true;
michael@0 127 }
michael@0 128
michael@0 129 mReadUsageCount = 0;
michael@0 130
michael@0 131 return mResolvedData;
michael@0 132 }
michael@0 133
michael@0 134 void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset)
michael@0 135 {
michael@0 136 ID3D11Device *device = mRenderer->getDevice();
michael@0 137 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
michael@0 138 HRESULT result;
michael@0 139
michael@0 140 unsigned int requiredBufferSize = size + offset;
michael@0 141 unsigned int requiredStagingSize = size;
michael@0 142 bool directInitialization = offset == 0 && (!mBuffer || mBufferSize < size + offset);
michael@0 143
michael@0 144 if (!directInitialization)
michael@0 145 {
michael@0 146 if (!mStagingBuffer || mStagingBufferSize < requiredStagingSize)
michael@0 147 {
michael@0 148 if (mStagingBuffer)
michael@0 149 {
michael@0 150 mStagingBuffer->Release();
michael@0 151 mStagingBuffer = NULL;
michael@0 152 mStagingBufferSize = 0;
michael@0 153 }
michael@0 154
michael@0 155 D3D11_BUFFER_DESC bufferDesc;
michael@0 156 bufferDesc.ByteWidth = size;
michael@0 157 bufferDesc.Usage = D3D11_USAGE_STAGING;
michael@0 158 bufferDesc.BindFlags = 0;
michael@0 159 bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
michael@0 160 bufferDesc.MiscFlags = 0;
michael@0 161 bufferDesc.StructureByteStride = 0;
michael@0 162
michael@0 163 if (data)
michael@0 164 {
michael@0 165 D3D11_SUBRESOURCE_DATA initialData;
michael@0 166 initialData.pSysMem = data;
michael@0 167 initialData.SysMemPitch = size;
michael@0 168 initialData.SysMemSlicePitch = 0;
michael@0 169
michael@0 170 result = device->CreateBuffer(&bufferDesc, &initialData, &mStagingBuffer);
michael@0 171 }
michael@0 172 else
michael@0 173 {
michael@0 174 result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer);
michael@0 175 }
michael@0 176
michael@0 177 if (FAILED(result))
michael@0 178 {
michael@0 179 return gl::error(GL_OUT_OF_MEMORY);
michael@0 180 }
michael@0 181
michael@0 182 mStagingBufferSize = size;
michael@0 183 }
michael@0 184 else if (data)
michael@0 185 {
michael@0 186 D3D11_MAPPED_SUBRESOURCE mappedResource;
michael@0 187 result = context->Map(mStagingBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource);
michael@0 188 if (FAILED(result))
michael@0 189 {
michael@0 190 return gl::error(GL_OUT_OF_MEMORY);
michael@0 191 }
michael@0 192
michael@0 193 memcpy(mappedResource.pData, data, size);
michael@0 194
michael@0 195 context->Unmap(mStagingBuffer, 0);
michael@0 196 }
michael@0 197 }
michael@0 198
michael@0 199 if (!mBuffer || mBufferSize < size + offset)
michael@0 200 {
michael@0 201 D3D11_BUFFER_DESC bufferDesc;
michael@0 202 bufferDesc.ByteWidth = requiredBufferSize;
michael@0 203 bufferDesc.Usage = D3D11_USAGE_DEFAULT;
michael@0 204 bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER;
michael@0 205 bufferDesc.CPUAccessFlags = 0;
michael@0 206 bufferDesc.MiscFlags = 0;
michael@0 207 bufferDesc.StructureByteStride = 0;
michael@0 208
michael@0 209 if (directInitialization)
michael@0 210 {
michael@0 211 // Since the data will fill the entire buffer (being larger than the initial size and having
michael@0 212 // no offset), the buffer can be initialized with the data so no staging buffer is required
michael@0 213
michael@0 214 // No longer need the old buffer
michael@0 215 if (mBuffer)
michael@0 216 {
michael@0 217 mBuffer->Release();
michael@0 218 mBuffer = NULL;
michael@0 219 mBufferSize = 0;
michael@0 220 }
michael@0 221
michael@0 222 if (data)
michael@0 223 {
michael@0 224 D3D11_SUBRESOURCE_DATA initialData;
michael@0 225 initialData.pSysMem = data;
michael@0 226 initialData.SysMemPitch = size;
michael@0 227 initialData.SysMemSlicePitch = 0;
michael@0 228
michael@0 229 result = device->CreateBuffer(&bufferDesc, &initialData, &mBuffer);
michael@0 230 }
michael@0 231 else
michael@0 232 {
michael@0 233 result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
michael@0 234 }
michael@0 235
michael@0 236 if (FAILED(result))
michael@0 237 {
michael@0 238 return gl::error(GL_OUT_OF_MEMORY);
michael@0 239 }
michael@0 240 }
michael@0 241 else if (mBuffer && offset > 0)
michael@0 242 {
michael@0 243 // If offset is greater than zero and the buffer is non-null, need to preserve the data from
michael@0 244 // the old buffer up to offset
michael@0 245 ID3D11Buffer *newBuffer = NULL;
michael@0 246
michael@0 247 result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer);
michael@0 248 if (FAILED(result))
michael@0 249 {
michael@0 250 return gl::error(GL_OUT_OF_MEMORY);
michael@0 251 }
michael@0 252
michael@0 253 D3D11_BOX srcBox;
michael@0 254 srcBox.left = 0;
michael@0 255 srcBox.right = std::min(offset, mBufferSize);
michael@0 256 srcBox.top = 0;
michael@0 257 srcBox.bottom = 1;
michael@0 258 srcBox.front = 0;
michael@0 259 srcBox.back = 1;
michael@0 260
michael@0 261 context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox);
michael@0 262
michael@0 263 mBuffer->Release();
michael@0 264 mBuffer = newBuffer;
michael@0 265 }
michael@0 266 else
michael@0 267 {
michael@0 268 // Simple case, nothing needs to be copied from the old buffer to the new one, just create
michael@0 269 // a new buffer
michael@0 270
michael@0 271 // No longer need the old buffer
michael@0 272 if (mBuffer)
michael@0 273 {
michael@0 274 mBuffer->Release();
michael@0 275 mBuffer = NULL;
michael@0 276 mBufferSize = 0;
michael@0 277 }
michael@0 278
michael@0 279 // Create a new buffer for data storage
michael@0 280 result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
michael@0 281 if (FAILED(result))
michael@0 282 {
michael@0 283 return gl::error(GL_OUT_OF_MEMORY);
michael@0 284 }
michael@0 285 }
michael@0 286
michael@0 287 updateSerial();
michael@0 288 mBufferSize = bufferDesc.ByteWidth;
michael@0 289 }
michael@0 290
michael@0 291 if (!directInitialization)
michael@0 292 {
michael@0 293 ASSERT(mStagingBuffer && mStagingBufferSize >= requiredStagingSize);
michael@0 294
michael@0 295 // Data is already put into the staging buffer, copy it over to the data buffer
michael@0 296 D3D11_BOX srcBox;
michael@0 297 srcBox.left = 0;
michael@0 298 srcBox.right = size;
michael@0 299 srcBox.top = 0;
michael@0 300 srcBox.bottom = 1;
michael@0 301 srcBox.front = 0;
michael@0 302 srcBox.back = 1;
michael@0 303
michael@0 304 context->CopySubresourceRegion(mBuffer, 0, offset, 0, 0, mStagingBuffer, 0, &srcBox);
michael@0 305 }
michael@0 306
michael@0 307 mSize = std::max(mSize, offset + size);
michael@0 308
michael@0 309 mWriteUsageCount = 0;
michael@0 310
michael@0 311 mResolvedDataValid = false;
michael@0 312 }
michael@0 313
michael@0 314 void BufferStorage11::clear()
michael@0 315 {
michael@0 316 mResolvedDataValid = false;
michael@0 317 mSize = 0;
michael@0 318 }
michael@0 319
michael@0 320 unsigned int BufferStorage11::getSize() const
michael@0 321 {
michael@0 322 return mSize;
michael@0 323 }
michael@0 324
michael@0 325 bool BufferStorage11::supportsDirectBinding() const
michael@0 326 {
michael@0 327 return true;
michael@0 328 }
michael@0 329
michael@0 330 void BufferStorage11::markBufferUsage()
michael@0 331 {
michael@0 332 mReadUsageCount++;
michael@0 333 mWriteUsageCount++;
michael@0 334
michael@0 335 static const unsigned int usageLimit = 5;
michael@0 336
michael@0 337 if (mReadUsageCount > usageLimit && mResolvedData)
michael@0 338 {
michael@0 339 free(mResolvedData);
michael@0 340 mResolvedData = NULL;
michael@0 341 mResolvedDataSize = 0;
michael@0 342 mResolvedDataValid = false;
michael@0 343 }
michael@0 344
michael@0 345 if (mReadUsageCount > usageLimit && mWriteUsageCount > usageLimit && mStagingBuffer)
michael@0 346 {
michael@0 347 mStagingBuffer->Release();
michael@0 348 mStagingBuffer = NULL;
michael@0 349 mStagingBufferSize = 0;
michael@0 350 }
michael@0 351 }
michael@0 352
michael@0 353 ID3D11Buffer *BufferStorage11::getBuffer() const
michael@0 354 {
michael@0 355 return mBuffer;
michael@0 356 }
michael@0 357
michael@0 358 }

mercurial