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

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..87e65ec632562d456309cd027d4028feb4ecfbc3
--- /dev/null
+++ b/gpu/command_buffer/service/indexed_buffer_binding_host.cc
@@ -0,0 +1,190 @@
+// 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"
+#include "ui/gl/gl_version_info.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) {
+ 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(
+ const gfx::GLVersionInfo& gl_version_info, 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 && gl_version_info.IsLowerThanGL(4, 2)) {
piman 2016/04/28 01:38:47 nit: could we check the gl version in the construc
Zhenyao Mo 2016/04/29 21:07:54 Done.
+ 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. Therefore, we clear the binding because nothing should be
+ // written to the buffer.
piman 2016/04/28 01:38:47 Note, this will cause a GL_INVALID_OPERATION when
Zhenyao Mo 2016/04/29 21:07:54 It turns out glBindBufferBase(target, index, servi
+ glBindBufferBase(target, index, 0);
+ glBindBuffer(target, 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 >> 2) << 2;
piman 2016/04/28 01:38:47 nit: you can use adjusted_size & ~3;
Zhenyao Mo 2016/04/29 21:07:54 Done.
+ 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, 0);
+ glBindBuffer(target, service_id);
+ return;
+ }
+ }
+ glBindBufferRange(target, index, service_id, offset, adjusted_size);
+}
+
+void IndexedBufferBindingHost::OnBindHost(
+ const gfx::GLVersionInfo& gl_version_info, GLenum target) {
+ if (gl_version_info.IsLowerThanGL(4, 2)) {
+ // 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(
+ const gfx::GLVersionInfo& gl_version_info, GLenum target, Buffer* buffer) {
+ DCHECK(buffer);
+ if (gl_version_info.IsLowerThanGL(4, 2)) {
+ // 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;
+ // TODO(zmo): Do we need to recall BindBufferBase if the buffer size
+ // changes?
piman 2016/04/28 01:38:47 I don't think so. Though TBH the spec is extremely
Zhenyao Mo 2016/04/29 21:07:54 Acknowledged.
+ 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