gfx/angle/src/libGLESv2/renderer/VertexDataManager.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) 2002-2012 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 // VertexDataManager.h: Defines the VertexDataManager, a class that
michael@0 9 // runs the Buffer translation process.
michael@0 10
michael@0 11 #include "libGLESv2/renderer/VertexDataManager.h"
michael@0 12 #include "libGLESv2/renderer/BufferStorage.h"
michael@0 13
michael@0 14 #include "libGLESv2/Buffer.h"
michael@0 15 #include "libGLESv2/ProgramBinary.h"
michael@0 16 #include "libGLESv2/Context.h"
michael@0 17 #include "libGLESv2/renderer/VertexBuffer.h"
michael@0 18
michael@0 19 namespace
michael@0 20 {
michael@0 21 enum { INITIAL_STREAM_BUFFER_SIZE = 1024*1024 };
michael@0 22 // This has to be at least 4k or else it fails on ATI cards.
michael@0 23 enum { CONSTANT_VERTEX_BUFFER_SIZE = 4096 };
michael@0 24 }
michael@0 25
michael@0 26 namespace rx
michael@0 27 {
michael@0 28
michael@0 29 static int elementsInBuffer(const gl::VertexAttribute &attribute, unsigned int size)
michael@0 30 {
michael@0 31 // Size cannot be larger than a GLsizei
michael@0 32 if (size > static_cast<unsigned int>(std::numeric_limits<int>::max()))
michael@0 33 {
michael@0 34 size = static_cast<unsigned int>(std::numeric_limits<int>::max());
michael@0 35 }
michael@0 36
michael@0 37 GLsizei stride = attribute.stride();
michael@0 38 return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride;
michael@0 39 }
michael@0 40
michael@0 41 VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer)
michael@0 42 {
michael@0 43 for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
michael@0 44 {
michael@0 45 mCurrentValue[i][0] = std::numeric_limits<float>::quiet_NaN();
michael@0 46 mCurrentValue[i][1] = std::numeric_limits<float>::quiet_NaN();
michael@0 47 mCurrentValue[i][2] = std::numeric_limits<float>::quiet_NaN();
michael@0 48 mCurrentValue[i][3] = std::numeric_limits<float>::quiet_NaN();
michael@0 49 mCurrentValueBuffer[i] = NULL;
michael@0 50 mCurrentValueOffsets[i] = 0;
michael@0 51 }
michael@0 52
michael@0 53 mStreamingBuffer = new StreamingVertexBufferInterface(renderer, INITIAL_STREAM_BUFFER_SIZE);
michael@0 54
michael@0 55 if (!mStreamingBuffer)
michael@0 56 {
michael@0 57 ERR("Failed to allocate the streaming vertex buffer.");
michael@0 58 }
michael@0 59 }
michael@0 60
michael@0 61 VertexDataManager::~VertexDataManager()
michael@0 62 {
michael@0 63 delete mStreamingBuffer;
michael@0 64
michael@0 65 for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
michael@0 66 {
michael@0 67 delete mCurrentValueBuffer[i];
michael@0 68 }
michael@0 69 }
michael@0 70
michael@0 71 static bool directStoragePossible(VertexBufferInterface* vb, const gl::VertexAttribute& attrib)
michael@0 72 {
michael@0 73 gl::Buffer *buffer = attrib.mBoundBuffer.get();
michael@0 74 BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
michael@0 75
michael@0 76 const bool isAligned = (attrib.stride() % 4 == 0) && (attrib.mOffset % 4 == 0);
michael@0 77
michael@0 78 return storage && storage->supportsDirectBinding() && !vb->getVertexBuffer()->requiresConversion(attrib) && isAligned;
michael@0 79 }
michael@0 80
michael@0 81 GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
michael@0 82 {
michael@0 83 if (!mStreamingBuffer)
michael@0 84 {
michael@0 85 return GL_OUT_OF_MEMORY;
michael@0 86 }
michael@0 87
michael@0 88 for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
michael@0 89 {
michael@0 90 translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1);
michael@0 91 }
michael@0 92
michael@0 93 // Invalidate static buffers that don't contain matching attributes
michael@0 94 for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
michael@0 95 {
michael@0 96 if (translated[i].active && attribs[i].mArrayEnabled)
michael@0 97 {
michael@0 98 gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
michael@0 99 StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
michael@0 100
michael@0 101 if (staticBuffer && staticBuffer->getBufferSize() > 0 && !staticBuffer->lookupAttribute(attribs[i], NULL) &&
michael@0 102 !directStoragePossible(staticBuffer, attribs[i]))
michael@0 103 {
michael@0 104 buffer->invalidateStaticData();
michael@0 105 }
michael@0 106 }
michael@0 107 }
michael@0 108
michael@0 109 // Reserve the required space in the buffers
michael@0 110 for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
michael@0 111 {
michael@0 112 if (translated[i].active && attribs[i].mArrayEnabled)
michael@0 113 {
michael@0 114 gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
michael@0 115 StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
michael@0 116 VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
michael@0 117
michael@0 118 if (!directStoragePossible(vertexBuffer, attribs[i]))
michael@0 119 {
michael@0 120 if (staticBuffer)
michael@0 121 {
michael@0 122 if (staticBuffer->getBufferSize() == 0)
michael@0 123 {
michael@0 124 int totalCount = elementsInBuffer(attribs[i], buffer->size());
michael@0 125 if (!staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0))
michael@0 126 {
michael@0 127 return GL_OUT_OF_MEMORY;
michael@0 128 }
michael@0 129 }
michael@0 130 }
michael@0 131 else
michael@0 132 {
michael@0 133 if (!mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances))
michael@0 134 {
michael@0 135 return GL_OUT_OF_MEMORY;
michael@0 136 }
michael@0 137 }
michael@0 138 }
michael@0 139 }
michael@0 140 }
michael@0 141
michael@0 142 // Perform the vertex data translations
michael@0 143 for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
michael@0 144 {
michael@0 145 if (translated[i].active)
michael@0 146 {
michael@0 147 if (attribs[i].mArrayEnabled)
michael@0 148 {
michael@0 149 gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
michael@0 150
michael@0 151 if (!buffer && attribs[i].mPointer == NULL)
michael@0 152 {
michael@0 153 // This is an application error that would normally result in a crash, but we catch it and return an error
michael@0 154 ERR("An enabled vertex array has no buffer and no pointer.");
michael@0 155 return GL_INVALID_OPERATION;
michael@0 156 }
michael@0 157
michael@0 158 StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
michael@0 159 VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
michael@0 160
michael@0 161 BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
michael@0 162 bool directStorage = directStoragePossible(vertexBuffer, attribs[i]);
michael@0 163
michael@0 164 unsigned int streamOffset = 0;
michael@0 165 unsigned int outputElementSize = 0;
michael@0 166
michael@0 167 if (directStorage)
michael@0 168 {
michael@0 169 outputElementSize = attribs[i].stride();
michael@0 170 streamOffset = attribs[i].mOffset + outputElementSize * start;
michael@0 171 storage->markBufferUsage();
michael@0 172 }
michael@0 173 else if (staticBuffer)
michael@0 174 {
michael@0 175 if (!staticBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize))
michael@0 176 {
michael@0 177 return GL_OUT_OF_MEMORY;
michael@0 178 }
michael@0 179
michael@0 180 if (!staticBuffer->lookupAttribute(attribs[i], &streamOffset))
michael@0 181 {
michael@0 182 // Convert the entire buffer
michael@0 183 int totalCount = elementsInBuffer(attribs[i], storage->getSize());
michael@0 184 int startIndex = attribs[i].mOffset / attribs[i].stride();
michael@0 185
michael@0 186 if (!staticBuffer->storeVertexAttributes(attribs[i], -startIndex, totalCount, 0, &streamOffset))
michael@0 187 {
michael@0 188 return GL_OUT_OF_MEMORY;
michael@0 189 }
michael@0 190 }
michael@0 191
michael@0 192 unsigned int firstElementOffset = (attribs[i].mOffset / attribs[i].stride()) * outputElementSize;
michael@0 193 unsigned int startOffset = (instances == 0 || attribs[i].mDivisor == 0) ? start * outputElementSize : 0;
michael@0 194 if (streamOffset + firstElementOffset + startOffset < streamOffset)
michael@0 195 {
michael@0 196 return GL_OUT_OF_MEMORY;
michael@0 197 }
michael@0 198
michael@0 199 streamOffset += firstElementOffset + startOffset;
michael@0 200 }
michael@0 201 else
michael@0 202 {
michael@0 203 if (!mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0, &outputElementSize) ||
michael@0 204 !mStreamingBuffer->storeVertexAttributes(attribs[i], start, count, instances, &streamOffset))
michael@0 205 {
michael@0 206 return GL_OUT_OF_MEMORY;
michael@0 207 }
michael@0 208 }
michael@0 209
michael@0 210 translated[i].storage = directStorage ? storage : NULL;
michael@0 211 translated[i].vertexBuffer = vertexBuffer->getVertexBuffer();
michael@0 212 translated[i].serial = directStorage ? storage->getSerial() : vertexBuffer->getSerial();
michael@0 213 translated[i].divisor = attribs[i].mDivisor;
michael@0 214
michael@0 215 translated[i].attribute = &attribs[i];
michael@0 216 translated[i].stride = outputElementSize;
michael@0 217 translated[i].offset = streamOffset;
michael@0 218 }
michael@0 219 else
michael@0 220 {
michael@0 221 if (!mCurrentValueBuffer[i])
michael@0 222 {
michael@0 223 mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mRenderer, CONSTANT_VERTEX_BUFFER_SIZE);
michael@0 224 }
michael@0 225
michael@0 226 StreamingVertexBufferInterface *buffer = mCurrentValueBuffer[i];
michael@0 227
michael@0 228 if (mCurrentValue[i][0] != attribs[i].mCurrentValue[0] ||
michael@0 229 mCurrentValue[i][1] != attribs[i].mCurrentValue[1] ||
michael@0 230 mCurrentValue[i][2] != attribs[i].mCurrentValue[2] ||
michael@0 231 mCurrentValue[i][3] != attribs[i].mCurrentValue[3])
michael@0 232 {
michael@0 233 unsigned int requiredSpace = sizeof(float) * 4;
michael@0 234 if (!buffer->reserveRawDataSpace(requiredSpace))
michael@0 235 {
michael@0 236 return GL_OUT_OF_MEMORY;
michael@0 237 }
michael@0 238
michael@0 239 unsigned int streamOffset;
michael@0 240 if (!buffer->storeRawData(attribs[i].mCurrentValue, requiredSpace, &streamOffset))
michael@0 241 {
michael@0 242 return GL_OUT_OF_MEMORY;
michael@0 243 }
michael@0 244
michael@0 245 mCurrentValueOffsets[i] = streamOffset;
michael@0 246 }
michael@0 247
michael@0 248 translated[i].storage = NULL;
michael@0 249 translated[i].vertexBuffer = mCurrentValueBuffer[i]->getVertexBuffer();
michael@0 250 translated[i].serial = mCurrentValueBuffer[i]->getSerial();
michael@0 251 translated[i].divisor = 0;
michael@0 252
michael@0 253 translated[i].attribute = &attribs[i];
michael@0 254 translated[i].stride = 0;
michael@0 255 translated[i].offset = mCurrentValueOffsets[i];
michael@0 256 }
michael@0 257 }
michael@0 258 }
michael@0 259
michael@0 260 for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
michael@0 261 {
michael@0 262 if (translated[i].active && attribs[i].mArrayEnabled)
michael@0 263 {
michael@0 264 gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
michael@0 265
michael@0 266 if (buffer)
michael@0 267 {
michael@0 268 buffer->promoteStaticUsage(count * attribs[i].typeSize());
michael@0 269 }
michael@0 270 }
michael@0 271 }
michael@0 272
michael@0 273 return GL_NO_ERROR;
michael@0 274 }
michael@0 275
michael@0 276 }

mercurial