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

Unified Diff: gpu/command_buffer/service/buffer_manager.cc

Issue 1845963003: Make sure we call glBufferData on the same data we store internally. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: shadow->use_shadow, Format, vector Clear+Insert/Resize 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
« no previous file with comments | « gpu/command_buffer/service/buffer_manager.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 261b2edd10b18f5935d0b9325b6493d487ae7f4a..3281d763a6423c0639260452a503fdf2edd0d17e 100644
--- a/gpu/command_buffer/service/buffer_manager.cc
+++ b/gpu/command_buffer/service/buffer_manager.cc
@@ -119,7 +119,6 @@ Buffer::Buffer(BufferManager* manager, GLuint service_id)
: manager_(manager),
size_(0),
deleted_(false),
- shadowed_(false),
is_client_side_array_(false),
service_id_(service_id),
initial_target_(0),
@@ -138,28 +137,36 @@ Buffer::~Buffer() {
}
}
-void Buffer::SetInfo(
- GLsizeiptr size, GLenum usage, bool shadow, const GLvoid* data,
- bool is_client_side_array) {
- usage_ = usage;
- is_client_side_array_ = is_client_side_array;
- ClearCache();
- if (size != size_ || shadow != shadowed_) {
- shadowed_ = shadow;
- size_ = size;
- if (shadowed_) {
- shadow_.reset(new int8_t[size]);
- } else {
- shadow_.reset();
- }
- }
- if (shadowed_) {
+const GLvoid* Buffer::StageShadow(bool use_shadow,
+ GLsizeiptr size,
+ const GLvoid* data) {
+ shadow_.clear();
+ if (use_shadow) {
if (data) {
- memcpy(shadow_.get(), data, size);
+ shadow_.insert(shadow_.begin(),
+ static_cast<const uint8_t*>(data),
+ static_cast<const uint8_t*>(data) + size);
} else {
- memset(shadow_.get(), 0, size);
+ shadow_.resize(size);
}
+ return shadow_.data();
+ } else {
+ return data;
}
+}
+
+void Buffer::SetInfo(GLsizeiptr size,
+ GLenum usage,
+ bool use_shadow,
+ bool is_client_side_array) {
+ usage_ = usage;
+ is_client_side_array_ = is_client_side_array;
+ ClearCache();
+
+ // Shadow must have been setup already.
+ DCHECK_EQ(shadow_.size(), static_cast<size_t>(use_shadow ? size : 0u));
+ size_ = size;
+
mapped_range_.reset(nullptr);
}
@@ -177,8 +184,9 @@ bool Buffer::SetRange(
if (!CheckRange(offset, size)) {
return false;
}
- if (shadowed_) {
- memcpy(shadow_.get() + offset, data, size);
+ if (!shadow_.empty()) {
+ DCHECK_LE(static_cast<size_t>(offset + size), shadow_.size());
+ memcpy(shadow_.data() + offset, data, size);
ClearCache();
}
return true;
@@ -186,13 +194,14 @@ bool Buffer::SetRange(
const void* Buffer::GetRange(
GLintptr offset, GLsizeiptr size) const {
- if (!shadowed_) {
+ if (shadow_.empty()) {
return NULL;
}
if (!CheckRange(offset, size)) {
return NULL;
}
- return shadow_.get() + offset;
+ DCHECK_LE(static_cast<size_t>(offset + size), shadow_.size());
+ return shadow_.data() + offset;
}
void Buffer::ClearCache() {
@@ -280,7 +289,7 @@ bool Buffer::GetMaxValueForRange(
return false;
}
- if (!shadowed_) {
+ if (shadow_.empty()) {
return false;
}
@@ -288,24 +297,24 @@ bool Buffer::GetMaxValueForRange(
GLuint max_v = 0;
switch (type) {
case GL_UNSIGNED_BYTE:
- max_v = GetMaxValue<uint8_t>(shadow_.get(), offset, count,
- primitive_restart_index);
+ max_v = GetMaxValue<uint8_t>(shadow_.data(), 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,
- primitive_restart_index);
+ max_v = GetMaxValue<uint16_t>(shadow_.data(), 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,
- primitive_restart_index);
+ max_v = GetMaxValue<uint32_t>(shadow_.data(), offset, count,
+ primitive_restart_index);
break;
default:
NOTREACHED(); // should never get here by validation.
@@ -338,19 +347,25 @@ bool BufferManager::UseNonZeroSizeForClientSideArrayBuffer() {
.use_non_zero_size_for_client_side_stream_buffers;
}
-void BufferManager::SetInfo(Buffer* buffer, GLenum target, GLsizeiptr size,
- GLenum usage, const GLvoid* data) {
- DCHECK(buffer);
- memory_type_tracker_->TrackMemFree(buffer->size());
+bool BufferManager::UseShadowBuffer(GLenum target, GLenum usage) {
const bool is_client_side_array = IsUsageClientSideArray(usage);
const bool support_fixed_attribs =
gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
+
// TODO(zmo): Don't shadow buffer data on ES3. crbug.com/491002.
- const bool shadow = target == GL_ELEMENT_ARRAY_BUFFER ||
- allow_buffers_on_multiple_targets_ ||
- (allow_fixed_attribs_ && !support_fixed_attribs) ||
- is_client_side_array;
- buffer->SetInfo(size, usage, shadow, data, is_client_side_array);
+ return (
+ target == GL_ELEMENT_ARRAY_BUFFER || allow_buffers_on_multiple_targets_ ||
+ (allow_fixed_attribs_ && !support_fixed_attribs) || is_client_side_array);
+}
+
+void BufferManager::SetInfo(Buffer* buffer,
+ GLenum target,
+ GLsizeiptr size,
+ GLenum usage,
+ bool use_shadow) {
+ DCHECK(buffer);
+ memory_type_tracker_->TrackMemFree(buffer->size());
+ buffer->SetInfo(size, usage, use_shadow, IsUsageClientSideArray(usage));
memory_type_tracker_->TrackMemAlloc(buffer->size());
}
@@ -398,13 +413,10 @@ void BufferManager::DoBufferData(
GLsizeiptr size,
GLenum usage,
const GLvoid* data) {
- // Clear the buffer to 0 if no initial data was passed in.
- scoped_ptr<int8_t[]> zero;
- if (!data) {
- zero.reset(new int8_t[size]);
- memset(zero.get(), 0, size);
- data = zero.get();
- }
+ // Stage the shadow buffer first if we are using a shadow buffer so that we
+ // validate what we store internally.
+ const bool use_shadow = UseShadowBuffer(target, usage);
+ data = buffer->StageShadow(use_shadow, size, data);
ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state, "glBufferData");
if (IsUsageClientSideArray(usage)) {
@@ -414,11 +426,12 @@ void BufferManager::DoBufferData(
glBufferData(target, size, data, usage);
}
GLenum error = ERRORSTATE_PEEK_GL_ERROR(error_state, "glBufferData");
- if (error == GL_NO_ERROR) {
- SetInfo(buffer, target, size, usage, data);
- } else {
- SetInfo(buffer, target, 0, usage, NULL);
+ if (error != GL_NO_ERROR) {
+ size = 0;
+ buffer->StageShadow(false, 0, nullptr); // Also clear the shadow.
}
+
+ SetInfo(buffer, target, size, usage, use_shadow);
}
void BufferManager::ValidateAndDoBufferSubData(
« no previous file with comments | « gpu/command_buffer/service/buffer_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698