OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/buffer_manager.h" | 5 #include "gpu/command_buffer/service/buffer_manager.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <limits> | 9 #include <limits> |
10 | 10 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 return NULL; | 192 return NULL; |
193 } | 193 } |
194 return shadow_.get() + offset; | 194 return shadow_.get() + offset; |
195 } | 195 } |
196 | 196 |
197 void Buffer::ClearCache() { | 197 void Buffer::ClearCache() { |
198 range_set_.clear(); | 198 range_set_.clear(); |
199 } | 199 } |
200 | 200 |
201 template <typename T> | 201 template <typename T> |
202 GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count, | 202 GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count) { |
203 GLuint primitive_restart_index) { | |
204 GLuint max_value = 0; | 203 GLuint max_value = 0; |
205 const T* element = | 204 const T* element = |
206 reinterpret_cast<const T*>(static_cast<const int8_t*>(data) + offset); | 205 reinterpret_cast<const T*>(static_cast<const int8_t*>(data) + offset); |
207 const T* end = element + count; | 206 const T* end = element + count; |
208 for (; element < end; ++element) { | 207 for (; element < end; ++element) { |
209 if (*element > max_value) { | 208 if (*element > max_value) { |
210 if (*element == primitive_restart_index) { | |
211 continue; | |
212 } | |
213 max_value = *element; | 209 max_value = *element; |
214 } | 210 } |
215 } | 211 } |
216 return max_value; | 212 return max_value; |
217 } | 213 } |
218 | 214 |
219 bool Buffer::GetMaxValueForRange( | 215 bool Buffer::GetMaxValueForRange( |
220 GLuint offset, GLsizei count, GLenum type, bool primitive_restart_enabled, | 216 GLuint offset, GLsizei count, GLenum type, GLuint* max_value) { |
221 GLuint* max_value) { | 217 Range range(offset, count, type); |
222 GLuint primitive_restart_index = 0; | |
223 if (primitive_restart_enabled) { | |
224 switch (type) { | |
225 case GL_UNSIGNED_BYTE: | |
226 primitive_restart_index = 0xFF; | |
227 break; | |
228 case GL_UNSIGNED_SHORT: | |
229 primitive_restart_index = 0xFFFF; | |
230 break; | |
231 case GL_UNSIGNED_INT: | |
232 primitive_restart_index = 0xFFFFFFFF; | |
233 break; | |
234 default: | |
235 NOTREACHED(); // should never get here by validation. | |
236 break; | |
237 } | |
238 } | |
239 | |
240 Range range(offset, count, type, primitive_restart_enabled); | |
241 RangeToMaxValueMap::iterator it = range_set_.find(range); | 218 RangeToMaxValueMap::iterator it = range_set_.find(range); |
242 if (it != range_set_.end()) { | 219 if (it != range_set_.end()) { |
243 *max_value = it->second; | 220 *max_value = it->second; |
244 return true; | 221 return true; |
245 } | 222 } |
246 // Optimization. If: | |
247 // - primitive restart is enabled | |
248 // - we don't have an entry in the range set for these parameters | |
249 // for the situation when primitive restart is enabled | |
250 // - we do have an entry in the range set for these parameters for | |
251 // the situation when primitive restart is disabled | |
252 // - this entry is less than the primitive restart index | |
253 // Then we can repurpose this entry for the situation when primitive | |
254 // restart is enabled. Otherwise, we need to compute the max index | |
255 // from scratch. | |
256 if (primitive_restart_enabled) { | |
257 Range disabled_range(offset, count, type, false); | |
258 RangeToMaxValueMap::iterator it = range_set_.find(disabled_range); | |
259 if (it != range_set_.end() && it->second < primitive_restart_index) { | |
260 // This reuses the max value for the case where primitive | |
261 // restart is enabled. | |
262 range_set_.insert(std::make_pair(range, it->second)); | |
263 *max_value = it->second; | |
264 return true; | |
265 } | |
266 } | |
267 | 223 |
268 uint32_t size; | 224 uint32_t size; |
269 if (!SafeMultiplyUint32( | 225 if (!SafeMultiplyUint32( |
270 count, GLES2Util::GetGLTypeSizeForBuffers(type), &size)) { | 226 count, GLES2Util::GetGLTypeSizeForBuffers(type), &size)) { |
271 return false; | 227 return false; |
272 } | 228 } |
273 | 229 |
274 if (!SafeAddUint32(offset, size, &size)) { | 230 if (!SafeAddUint32(offset, size, &size)) { |
275 return false; | 231 return false; |
276 } | 232 } |
277 | 233 |
278 if (size > static_cast<uint32_t>(size_)) { | 234 if (size > static_cast<uint32_t>(size_)) { |
279 return false; | 235 return false; |
280 } | 236 } |
281 | 237 |
282 if (!shadowed_) { | 238 if (!shadowed_) { |
283 return false; | 239 return false; |
284 } | 240 } |
285 | 241 |
286 // Scan the range for the max value and store | 242 // Scan the range for the max value and store |
287 GLuint max_v = 0; | 243 GLuint max_v = 0; |
288 switch (type) { | 244 switch (type) { |
289 case GL_UNSIGNED_BYTE: | 245 case GL_UNSIGNED_BYTE: |
290 max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count, | 246 max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count); |
291 primitive_restart_index); | |
292 break; | 247 break; |
293 case GL_UNSIGNED_SHORT: | 248 case GL_UNSIGNED_SHORT: |
294 // Check we are not accessing an odd byte for a 2 byte value. | 249 // Check we are not accessing an odd byte for a 2 byte value. |
295 if ((offset & 1) != 0) { | 250 if ((offset & 1) != 0) { |
296 return false; | 251 return false; |
297 } | 252 } |
298 max_v = GetMaxValue<uint16_t>(shadow_.get(), offset, count, | 253 max_v = GetMaxValue<uint16_t>(shadow_.get(), offset, count); |
299 primitive_restart_index); | |
300 break; | 254 break; |
301 case GL_UNSIGNED_INT: | 255 case GL_UNSIGNED_INT: |
302 // Check we are not accessing a non aligned address for a 4 byte value. | 256 // Check we are not accessing a non aligned address for a 4 byte value. |
303 if ((offset & 3) != 0) { | 257 if ((offset & 3) != 0) { |
304 return false; | 258 return false; |
305 } | 259 } |
306 max_v = GetMaxValue<uint32_t>(shadow_.get(), offset, count, | 260 max_v = GetMaxValue<uint32_t>(shadow_.get(), offset, count); |
307 primitive_restart_index); | |
308 break; | 261 break; |
309 default: | 262 default: |
310 NOTREACHED(); // should never get here by validation. | 263 NOTREACHED(); // should never get here by validation. |
311 break; | 264 break; |
312 } | 265 } |
313 range_set_.insert(std::make_pair(range, max_v)); | 266 range_set_.insert(std::make_pair(range, max_v)); |
314 *max_value = max_v; | 267 *max_value = max_v; |
315 return true; | 268 return true; |
316 } | 269 } |
317 | 270 |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 auto guid = gfx::GetGLBufferGUIDForTracing( | 554 auto guid = gfx::GetGLBufferGUIDForTracing( |
602 memory_tracker_->ShareGroupTracingGUID(), client_buffer_id); | 555 memory_tracker_->ShareGroupTracingGUID(), client_buffer_id); |
603 pmd->CreateSharedGlobalAllocatorDump(guid); | 556 pmd->CreateSharedGlobalAllocatorDump(guid); |
604 pmd->AddOwnershipEdge(dump->guid(), guid); | 557 pmd->AddOwnershipEdge(dump->guid(), guid); |
605 } | 558 } |
606 return true; | 559 return true; |
607 } | 560 } |
608 | 561 |
609 } // namespace gles2 | 562 } // namespace gles2 |
610 } // namespace gpu | 563 } // namespace gpu |
OLD | NEW |