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