Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1113)

Side by Side Diff: gpu/command_buffer/service/buffer_manager.cc

Issue 1813163003: Fix PRIMITIVE_RESTART_FIXED_INDEX handling in command buffer and WebGL 2.0. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Refactored and expanded unittests. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/buffer_manager.h ('k') | gpu/command_buffer/service/buffer_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698