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 |