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

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

Issue 1922633002: Implement TransformFeedbackManager in GPU command buffer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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/indexed_buffer_binding_host.cc
diff --git a/gpu/command_buffer/service/indexed_buffer_binding_host.cc b/gpu/command_buffer/service/indexed_buffer_binding_host.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e093e1dd0c3e4cde3d6bd1bcce7118cd23ac18f7
--- /dev/null
+++ b/gpu/command_buffer/service/indexed_buffer_binding_host.cc
@@ -0,0 +1,187 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/indexed_buffer_binding_host.h"
+
+#include "gpu/command_buffer/service/buffer_manager.h"
+
+namespace gpu {
+namespace gles2 {
+
+IndexedBufferBindingHost::IndexedBufferBinding::IndexedBufferBinding()
+ : type(kBindBufferNone),
+ offset(0),
+ size(0),
+ effective_full_buffer_size(0) {
+}
+
+IndexedBufferBindingHost::IndexedBufferBinding::IndexedBufferBinding(
+ const IndexedBufferBindingHost::IndexedBufferBinding& other)
+ : type(other.type),
+ buffer(other.buffer.get()),
+ offset(other.offset),
+ size(other.size),
+ effective_full_buffer_size(other.effective_full_buffer_size) {
+}
+
+IndexedBufferBindingHost::IndexedBufferBinding::~IndexedBufferBinding() {
+}
+
+void IndexedBufferBindingHost::IndexedBufferBinding::SetBindBufferBase(
+ Buffer* _buffer) {
+ if (!_buffer) {
+ Reset();
+ return;
+ }
+ type = kBindBufferBase;
+ buffer = _buffer;
+ offset = 0;
+ size = 0;
+ effective_full_buffer_size = 0;
+}
+
+void IndexedBufferBindingHost::IndexedBufferBinding::SetBindBufferRange(
+ Buffer* _buffer, GLintptr _offset, GLsizeiptr _size) {
+ if (!_buffer) {
+ Reset();
+ return;
+ }
+ type = kBindBufferRange;
+ buffer = _buffer;
+ offset = _offset;
+ size = _size;
+ effective_full_buffer_size = _buffer ? _buffer->size() : 0;
+}
+
+void IndexedBufferBindingHost::IndexedBufferBinding::Reset() {
+ type = kBindBufferNone;
+ buffer = nullptr;
+ offset = 0;
+ size = 0;
+ effective_full_buffer_size = 0;
+}
+
+
+IndexedBufferBindingHost::IndexedBufferBindingHost(
+ uint32_t max_bindings, bool needs_emulation)
+ : needs_emulation_(needs_emulation) {
+ buffer_bindings_.resize(max_bindings);
+}
+
+IndexedBufferBindingHost::~IndexedBufferBindingHost() {
+}
+
+void IndexedBufferBindingHost::DoBindBufferBase(
+ GLenum target, GLuint index, Buffer* buffer) {
+ DCHECK_LT(index, buffer_bindings_.size());
+ GLuint service_id = buffer ? buffer->service_id() : 0;
+ glBindBufferBase(target, index, service_id);
+
+ buffer_bindings_[index].SetBindBufferBase(buffer);
+}
+
+void IndexedBufferBindingHost::DoBindBufferRange(
+ GLenum target, GLuint index, Buffer* buffer, GLintptr offset,
+ GLsizeiptr size) {
+ DCHECK_LT(index, buffer_bindings_.size());
+ GLuint service_id = buffer ? buffer->service_id() : 0;
+ if (buffer && needs_emulation_) {
+ DoAdjustedBindBufferRange(
+ target, index, service_id, offset, size, buffer->size());
+ } else {
+ glBindBufferRange(target, index, service_id, offset, size);
+ }
+
+ buffer_bindings_[index].SetBindBufferRange(buffer, offset, size);
+}
+
+// static
+void IndexedBufferBindingHost::DoAdjustedBindBufferRange(
+ GLenum target, GLuint index, GLuint service_id, GLintptr offset,
+ GLsizeiptr size, GLsizeiptr full_buffer_size) {
+ GLsizeiptr adjusted_size = size;
+ if (offset >= full_buffer_size) {
+ // Situation 1: We can't really call glBindBufferRange with reasonable
+ // offset/size without triggering a GL error because size == 0 isn't
+ // valid.
+ // TODO(zmo): it's ambiguous in the GL 4.1 spec whether BindBufferBase
+ // generates a GL error in such case. In reality, no error is generated on
+ // MacOSX with AMD/4.1.
+ glBindBufferBase(target, index, service_id);
+ return;
+ } else if (offset + size > full_buffer_size) {
+ adjusted_size = full_buffer_size - offset;
+ // size needs to be a multiple of 4.
+ adjusted_size = adjusted_size & ~3;
+ if (adjusted_size == 0) {
+ // Situation 2: The original size is valid, but the adjusted size
+ // is 0 and isn't valid. Handle it the same way as situation 1.
+ glBindBufferBase(target, index, service_id);
+ return;
+ }
+ }
+ glBindBufferRange(target, index, service_id, offset, adjusted_size);
+}
+
+void IndexedBufferBindingHost::OnBindHost(GLenum target) {
+ if (needs_emulation_) {
+ // If some bound buffers change size since last time the transformfeedback
+ // is bound, we might need to reset the ranges.
+ for (size_t ii = 0; ii < buffer_bindings_.size(); ++ii) {
+ Buffer* buffer = buffer_bindings_[ii].buffer.get();
+ if (buffer && buffer_bindings_[ii].type == kBindBufferRange &&
+ buffer_bindings_[ii].effective_full_buffer_size != buffer->size()) {
+ DoAdjustedBindBufferRange(
+ target, ii, buffer->service_id(), buffer_bindings_[ii].offset,
+ buffer_bindings_[ii].size, buffer->size());
+ buffer_bindings_[ii].effective_full_buffer_size = buffer->size();
+ }
+ }
+ }
+}
+
+void IndexedBufferBindingHost::OnBufferData(GLenum target, Buffer* buffer) {
+ DCHECK(buffer);
+ if (needs_emulation_) {
+ // If some bound buffers change size since last time the transformfeedback
+ // is bound, we might need to reset the ranges.
+ for (size_t ii = 0; ii < buffer_bindings_.size(); ++ii) {
+ if (buffer_bindings_[ii].buffer.get() != buffer)
+ continue;
+ if (buffer_bindings_[ii].type == kBindBufferRange &&
+ buffer_bindings_[ii].effective_full_buffer_size != buffer->size()) {
+ DoAdjustedBindBufferRange(
+ target, ii, buffer->service_id(), buffer_bindings_[ii].offset,
+ buffer_bindings_[ii].size, buffer->size());
+ buffer_bindings_[ii].effective_full_buffer_size = buffer->size();
+ }
+ }
+ }
+}
+
+void IndexedBufferBindingHost::RemoveBoundBuffer(Buffer* buffer) {
+ for (size_t ii = 0; ii < buffer_bindings_.size(); ++ii) {
+ if (buffer_bindings_[ii].buffer.get() == buffer) {
+ buffer_bindings_[ii].Reset();
+ }
+ }
+}
+
+Buffer* IndexedBufferBindingHost::GetBufferBinding(GLuint index) const {
+ DCHECK_LT(index, buffer_bindings_.size());
+ return buffer_bindings_[index].buffer.get();
+}
+
+GLsizeiptr IndexedBufferBindingHost::GetBufferSize(GLuint index) const {
+ DCHECK_LT(index, buffer_bindings_.size());
+ return buffer_bindings_[index].size;
+}
+
+GLintptr IndexedBufferBindingHost::GetBufferStart(GLuint index) const {
+ DCHECK_LT(index, buffer_bindings_.size());
+ return buffer_bindings_[index].offset;
+}
+
+} // namespace gles2
+} // namespace gpu

Powered by Google App Engine
This is Rietveld 408576698