Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "gpu/command_buffer/service/indexed_buffer_binding_host.h" | |
| 6 | |
| 7 #include "gpu/command_buffer/service/buffer_manager.h" | |
| 8 #include "ui/gl/gl_version_info.h" | |
| 9 | |
| 10 namespace gpu { | |
| 11 namespace gles2 { | |
| 12 | |
| 13 IndexedBufferBindingHost::IndexedBufferBinding::IndexedBufferBinding() | |
| 14 : type(kBindBufferNone), | |
| 15 offset(0), | |
| 16 size(0), | |
| 17 effective_full_buffer_size(0) { | |
| 18 } | |
| 19 | |
| 20 IndexedBufferBindingHost::IndexedBufferBinding::IndexedBufferBinding( | |
| 21 const IndexedBufferBindingHost::IndexedBufferBinding& other) | |
| 22 : type(other.type), | |
| 23 buffer(other.buffer.get()), | |
| 24 offset(other.offset), | |
| 25 size(other.size), | |
| 26 effective_full_buffer_size(other.effective_full_buffer_size) { | |
| 27 } | |
| 28 | |
| 29 IndexedBufferBindingHost::IndexedBufferBinding::~IndexedBufferBinding() { | |
| 30 } | |
| 31 | |
| 32 void IndexedBufferBindingHost::IndexedBufferBinding::SetBindBufferBase( | |
| 33 Buffer* _buffer) { | |
| 34 if (!_buffer) { | |
| 35 Reset(); | |
| 36 return; | |
| 37 } | |
| 38 type = kBindBufferBase; | |
| 39 buffer = _buffer; | |
| 40 offset = 0; | |
| 41 size = 0; | |
| 42 effective_full_buffer_size = 0; | |
| 43 } | |
| 44 | |
| 45 void IndexedBufferBindingHost::IndexedBufferBinding::SetBindBufferRange( | |
| 46 Buffer* _buffer, GLintptr _offset, GLsizeiptr _size) { | |
| 47 if (!_buffer) { | |
| 48 Reset(); | |
| 49 return; | |
| 50 } | |
| 51 type = kBindBufferRange; | |
| 52 buffer = _buffer; | |
| 53 offset = _offset; | |
| 54 size = _size; | |
| 55 effective_full_buffer_size = _buffer ? _buffer->size() : 0; | |
| 56 } | |
| 57 | |
| 58 void IndexedBufferBindingHost::IndexedBufferBinding::Reset() { | |
| 59 type = kBindBufferNone; | |
| 60 buffer = nullptr; | |
| 61 offset = 0; | |
| 62 size = 0; | |
| 63 effective_full_buffer_size = 0; | |
| 64 } | |
| 65 | |
| 66 | |
| 67 IndexedBufferBindingHost::IndexedBufferBindingHost(uint32_t max_bindings) { | |
| 68 buffer_bindings_.resize(max_bindings); | |
| 69 } | |
| 70 | |
| 71 IndexedBufferBindingHost::~IndexedBufferBindingHost() { | |
| 72 } | |
| 73 | |
| 74 void IndexedBufferBindingHost::DoBindBufferBase( | |
| 75 GLenum target, GLuint index, Buffer* buffer) { | |
| 76 DCHECK_LT(index, buffer_bindings_.size()); | |
| 77 GLuint service_id = buffer ? buffer->service_id() : 0; | |
| 78 glBindBufferBase(target, index, service_id); | |
| 79 | |
| 80 buffer_bindings_[index].SetBindBufferBase(buffer); | |
| 81 } | |
| 82 | |
| 83 void IndexedBufferBindingHost::DoBindBufferRange( | |
| 84 const gfx::GLVersionInfo& gl_version_info, GLenum target, GLuint index, | |
| 85 Buffer* buffer, GLintptr offset, GLsizeiptr size) { | |
| 86 DCHECK_LT(index, buffer_bindings_.size()); | |
| 87 GLuint service_id = buffer ? buffer->service_id() : 0; | |
| 88 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.
| |
| 89 DoAdjustedBindBufferRange( | |
| 90 target, index, service_id, offset, size, buffer->size()); | |
| 91 } else { | |
| 92 glBindBufferRange(target, index, service_id, offset, size); | |
| 93 } | |
| 94 | |
| 95 buffer_bindings_[index].SetBindBufferRange(buffer, offset, size); | |
| 96 } | |
| 97 | |
| 98 // static | |
| 99 void IndexedBufferBindingHost::DoAdjustedBindBufferRange( | |
| 100 GLenum target, GLuint index, GLuint service_id, GLintptr offset, | |
| 101 GLsizeiptr size, GLsizeiptr full_buffer_size) { | |
| 102 GLsizeiptr adjusted_size = size; | |
| 103 if (offset >= full_buffer_size) { | |
| 104 // Situation 1: We can't really call glBindBufferRange with reasonable | |
| 105 // offset/size without triggering a GL error because size == 0 isn't | |
| 106 // valid. Therefore, we clear the binding because nothing should be | |
| 107 // 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
| |
| 108 glBindBufferBase(target, index, 0); | |
| 109 glBindBuffer(target, service_id); | |
| 110 return; | |
| 111 } else if (offset + size > full_buffer_size) { | |
| 112 adjusted_size = full_buffer_size - offset; | |
| 113 // size needs to be a multiple of 4. | |
| 114 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.
| |
| 115 if (adjusted_size == 0) { | |
| 116 // Situation 2: The original size is valid, but the adjusted size | |
| 117 // is 0 and isn't valid. Handle it the same way as situation 1. | |
| 118 glBindBufferBase(target, index, 0); | |
| 119 glBindBuffer(target, service_id); | |
| 120 return; | |
| 121 } | |
| 122 } | |
| 123 glBindBufferRange(target, index, service_id, offset, adjusted_size); | |
| 124 } | |
| 125 | |
| 126 void IndexedBufferBindingHost::OnBindHost( | |
| 127 const gfx::GLVersionInfo& gl_version_info, GLenum target) { | |
| 128 if (gl_version_info.IsLowerThanGL(4, 2)) { | |
| 129 // If some bound buffers change size since last time the transformfeedback | |
| 130 // is bound, we might need to reset the ranges. | |
| 131 for (size_t ii = 0; ii < buffer_bindings_.size(); ++ii) { | |
| 132 Buffer* buffer = buffer_bindings_[ii].buffer.get(); | |
| 133 if (buffer && buffer_bindings_[ii].type == kBindBufferRange && | |
| 134 buffer_bindings_[ii].effective_full_buffer_size != buffer->size()) { | |
| 135 DoAdjustedBindBufferRange( | |
| 136 target, ii, buffer->service_id(), buffer_bindings_[ii].offset, | |
| 137 buffer_bindings_[ii].size, buffer->size()); | |
| 138 buffer_bindings_[ii].effective_full_buffer_size = buffer->size(); | |
| 139 } | |
| 140 } | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 void IndexedBufferBindingHost::OnBufferData( | |
| 145 const gfx::GLVersionInfo& gl_version_info, GLenum target, Buffer* buffer) { | |
| 146 DCHECK(buffer); | |
| 147 if (gl_version_info.IsLowerThanGL(4, 2)) { | |
| 148 // If some bound buffers change size since last time the transformfeedback | |
| 149 // is bound, we might need to reset the ranges. | |
| 150 for (size_t ii = 0; ii < buffer_bindings_.size(); ++ii) { | |
| 151 if (buffer_bindings_[ii].buffer.get() != buffer) | |
| 152 continue; | |
| 153 // TODO(zmo): Do we need to recall BindBufferBase if the buffer size | |
| 154 // 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.
| |
| 155 if (buffer_bindings_[ii].type == kBindBufferRange && | |
| 156 buffer_bindings_[ii].effective_full_buffer_size != buffer->size()) { | |
| 157 DoAdjustedBindBufferRange( | |
| 158 target, ii, buffer->service_id(), buffer_bindings_[ii].offset, | |
| 159 buffer_bindings_[ii].size, buffer->size()); | |
| 160 buffer_bindings_[ii].effective_full_buffer_size = buffer->size(); | |
| 161 } | |
| 162 } | |
| 163 } | |
| 164 } | |
| 165 | |
| 166 void IndexedBufferBindingHost::RemoveBoundBuffer(Buffer* buffer) { | |
| 167 for (size_t ii = 0; ii < buffer_bindings_.size(); ++ii) { | |
| 168 if (buffer_bindings_[ii].buffer.get() == buffer) { | |
| 169 buffer_bindings_[ii].Reset(); | |
| 170 } | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 Buffer* IndexedBufferBindingHost::GetBufferBinding(GLuint index) const { | |
| 175 DCHECK_LT(index, buffer_bindings_.size()); | |
| 176 return buffer_bindings_[index].buffer.get(); | |
| 177 } | |
| 178 | |
| 179 GLsizeiptr IndexedBufferBindingHost::GetBufferSize(GLuint index) const { | |
| 180 DCHECK_LT(index, buffer_bindings_.size()); | |
| 181 return buffer_bindings_[index].size; | |
| 182 } | |
| 183 | |
| 184 GLintptr IndexedBufferBindingHost::GetBufferStart(GLuint index) const { | |
| 185 DCHECK_LT(index, buffer_bindings_.size()); | |
| 186 return buffer_bindings_[index].offset; | |
| 187 } | |
| 188 | |
| 189 } // namespace gles2 | |
| 190 } // namespace gpu | |
| OLD | NEW |