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

Unified 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: 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 side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/buffer_manager.cc
diff --git a/gpu/command_buffer/service/buffer_manager.cc b/gpu/command_buffer/service/buffer_manager.cc
index 914d9b09da06e8fb3a71c2162e9a8e6291dea962..e2c24e6eb8c2dd8211de3d35421c7004640dcf5c 100644
--- a/gpu/command_buffer/service/buffer_manager.cc
+++ b/gpu/command_buffer/service/buffer_manager.cc
@@ -199,13 +199,17 @@ void Buffer::ClearCache() {
}
template <typename T>
-GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count) {
+GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count,
+ GLuint primitive_restart_index) {
GLuint max_value = 0;
const T* element =
reinterpret_cast<const T*>(static_cast<const int8_t*>(data) + offset);
const T* end = element + count;
for (; element < end; ++element) {
if (*element > max_value) {
+ if (*element == primitive_restart_index) {
+ continue;
+ }
max_value = *element;
}
}
@@ -213,13 +217,55 @@ GLuint GetMaxValue(const void* data, GLuint offset, GLsizei count) {
}
bool Buffer::GetMaxValueForRange(
- GLuint offset, GLsizei count, GLenum type, GLuint* max_value) {
- Range range(offset, count, type);
+ GLuint offset, GLsizei count, GLenum type, bool primitive_restart_enabled,
+ GLuint* max_value) {
+ bool index_buffer =
+ this->initial_target() == GL_ELEMENT_ARRAY_BUFFER ? true : false;
piman 2016/03/19 00:56:11 nit: "? true : false" is redundant
piman 2016/03/19 00:56:11 What is this check for? This is only used for thin
Ken Russell (switch to Gerrit) 2016/03/19 04:06:52 Good point -- I copied this code from the original
yunchao 2016/03/21 15:11:35 I am not familiar with GetMaxValueInBufferCHROMIUM
Ken Russell (switch to Gerrit) 2016/03/21 17:41:46 GetMaxValueInBufferCHROMIUM is used to emulate cli
+ GLuint primitive_restart_index = 0;
+ if (index_buffer && primitive_restart_enabled) {
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ primitive_restart_index = 0xFF;
+ break;
+ case GL_UNSIGNED_SHORT:
+ primitive_restart_index = 0xFFFF;
+ break;
+ case GL_UNSIGNED_INT:
+ primitive_restart_index = 0xFFFFFFFF;
+ break;
+ default:
+ NOTREACHED(); // should never get here by validation.
+ break;
+ }
+ }
+
+ Range range(offset, count, type, primitive_restart_enabled);
RangeToMaxValueMap::iterator it = range_set_.find(range);
if (it != range_set_.end()) {
*max_value = it->second;
return true;
}
+ // Optimization. If:
+ // - primitive restart is enabled
+ // - we don't have an entry in the range set for these parameters
+ // for the situation when primitive restart is enabled
+ // - we do have an entry in the range set for these parameters for
+ // the situation when primitive restart is disabled
+ // - this entry is less than the primitive restart index
+ // Then we can repurpose this entry for the situation when primitive
+ // restart is enabled. Otherwise, we need to compute the max index
+ // from scratch.
+ if (primitive_restart_enabled) {
+ Range disabled_range(offset, count, type, false);
+ RangeToMaxValueMap::iterator it = range_set_.find(disabled_range);
+ if (it != range_set_.end() && it->second < primitive_restart_index) {
+ // This reuses the max value for the case where primitive
+ // restart is enabled.
+ range_set_.insert(std::make_pair(range, it->second));
+ *max_value = it->second;
+ return true;
+ }
+ }
uint32_t size;
if (!SafeMultiplyUint32(
@@ -243,21 +289,24 @@ bool Buffer::GetMaxValueForRange(
GLuint max_v = 0;
switch (type) {
case GL_UNSIGNED_BYTE:
- max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count);
+ max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count,
+ primitive_restart_index);
break;
case GL_UNSIGNED_SHORT:
// Check we are not accessing an odd byte for a 2 byte value.
if ((offset & 1) != 0) {
return false;
}
- max_v = GetMaxValue<uint16_t>(shadow_.get(), offset, count);
+ max_v = GetMaxValue<uint16_t>(shadow_.get(), offset, count,
+ primitive_restart_index);
break;
case GL_UNSIGNED_INT:
// Check we are not accessing a non aligned address for a 4 byte value.
if ((offset & 3) != 0) {
return false;
}
- max_v = GetMaxValue<uint32_t>(shadow_.get(), offset, count);
+ max_v = GetMaxValue<uint32_t>(shadow_.get(), offset, count,
+ primitive_restart_index);
break;
default:
NOTREACHED(); // should never get here by validation.

Powered by Google App Engine
This is Rietveld 408576698