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) { |
203 GLuint max_value = 0; | 204 GLuint max_value = 0; |
204 const T* element = | 205 const T* element = |
205 reinterpret_cast<const T*>(static_cast<const int8_t*>(data) + offset); | 206 reinterpret_cast<const T*>(static_cast<const int8_t*>(data) + offset); |
206 const T* end = element + count; | 207 const T* end = element + count; |
207 for (; element < end; ++element) { | 208 for (; element < end; ++element) { |
208 if (*element > max_value) { | 209 if (*element > max_value) { |
| 210 if (*element == primitive_restart_index) { |
| 211 continue; |
| 212 } |
209 max_value = *element; | 213 max_value = *element; |
210 } | 214 } |
211 } | 215 } |
212 return max_value; | 216 return max_value; |
213 } | 217 } |
214 | 218 |
215 bool Buffer::GetMaxValueForRange( | 219 bool Buffer::GetMaxValueForRange( |
216 GLuint offset, GLsizei count, GLenum type, GLuint* max_value) { | 220 GLuint offset, GLsizei count, GLenum type, bool primitive_restart_enabled, |
217 Range range(offset, count, type); | 221 GLuint* max_value) { |
| 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); |
218 RangeToMaxValueMap::iterator it = range_set_.find(range); | 241 RangeToMaxValueMap::iterator it = range_set_.find(range); |
219 if (it != range_set_.end()) { | 242 if (it != range_set_.end()) { |
220 *max_value = it->second; | 243 *max_value = it->second; |
221 return true; | 244 return true; |
222 } | 245 } |
| 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 } |
223 | 267 |
224 uint32_t size; | 268 uint32_t size; |
225 if (!SafeMultiplyUint32( | 269 if (!SafeMultiplyUint32( |
226 count, GLES2Util::GetGLTypeSizeForBuffers(type), &size)) { | 270 count, GLES2Util::GetGLTypeSizeForBuffers(type), &size)) { |
227 return false; | 271 return false; |
228 } | 272 } |
229 | 273 |
230 if (!SafeAddUint32(offset, size, &size)) { | 274 if (!SafeAddUint32(offset, size, &size)) { |
231 return false; | 275 return false; |
232 } | 276 } |
233 | 277 |
234 if (size > static_cast<uint32_t>(size_)) { | 278 if (size > static_cast<uint32_t>(size_)) { |
235 return false; | 279 return false; |
236 } | 280 } |
237 | 281 |
238 if (!shadowed_) { | 282 if (!shadowed_) { |
239 return false; | 283 return false; |
240 } | 284 } |
241 | 285 |
242 // Scan the range for the max value and store | 286 // Scan the range for the max value and store |
243 GLuint max_v = 0; | 287 GLuint max_v = 0; |
244 switch (type) { | 288 switch (type) { |
245 case GL_UNSIGNED_BYTE: | 289 case GL_UNSIGNED_BYTE: |
246 max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count); | 290 max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count, |
| 291 primitive_restart_index); |
247 break; | 292 break; |
248 case GL_UNSIGNED_SHORT: | 293 case GL_UNSIGNED_SHORT: |
249 // Check we are not accessing an odd byte for a 2 byte value. | 294 // Check we are not accessing an odd byte for a 2 byte value. |
250 if ((offset & 1) != 0) { | 295 if ((offset & 1) != 0) { |
251 return false; | 296 return false; |
252 } | 297 } |
253 max_v = GetMaxValue<uint16_t>(shadow_.get(), offset, count); | 298 max_v = GetMaxValue<uint16_t>(shadow_.get(), offset, count, |
| 299 primitive_restart_index); |
254 break; | 300 break; |
255 case GL_UNSIGNED_INT: | 301 case GL_UNSIGNED_INT: |
256 // Check we are not accessing a non aligned address for a 4 byte value. | 302 // Check we are not accessing a non aligned address for a 4 byte value. |
257 if ((offset & 3) != 0) { | 303 if ((offset & 3) != 0) { |
258 return false; | 304 return false; |
259 } | 305 } |
260 max_v = GetMaxValue<uint32_t>(shadow_.get(), offset, count); | 306 max_v = GetMaxValue<uint32_t>(shadow_.get(), offset, count, |
| 307 primitive_restart_index); |
261 break; | 308 break; |
262 default: | 309 default: |
263 NOTREACHED(); // should never get here by validation. | 310 NOTREACHED(); // should never get here by validation. |
264 break; | 311 break; |
265 } | 312 } |
266 range_set_.insert(std::make_pair(range, max_v)); | 313 range_set_.insert(std::make_pair(range, max_v)); |
267 *max_value = max_v; | 314 *max_value = max_v; |
268 return true; | 315 return true; |
269 } | 316 } |
270 | 317 |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 auto guid = gfx::GetGLBufferGUIDForTracing( | 601 auto guid = gfx::GetGLBufferGUIDForTracing( |
555 memory_tracker_->ShareGroupTracingGUID(), client_buffer_id); | 602 memory_tracker_->ShareGroupTracingGUID(), client_buffer_id); |
556 pmd->CreateSharedGlobalAllocatorDump(guid); | 603 pmd->CreateSharedGlobalAllocatorDump(guid); |
557 pmd->AddOwnershipEdge(dump->guid(), guid); | 604 pmd->AddOwnershipEdge(dump->guid(), guid); |
558 } | 605 } |
559 return true; | 606 return true; |
560 } | 607 } |
561 | 608 |
562 } // namespace gles2 | 609 } // namespace gles2 |
563 } // namespace gpu | 610 } // namespace gpu |
OLD | NEW |