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

Side by Side Diff: gpu/command_buffer/client/gles2_implementation.cc

Issue 11413094: Fix VAOs and client side arrays (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // A class to emulate GLES2 over command buffers. 5 // A class to emulate GLES2 over command buffers.
6 6
7 #include "../client/gles2_implementation.h" 7 #include "../client/gles2_implementation.h"
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <map> 10 #include <map>
11 #include <queue> 11 #include <queue>
12 #include <set> 12 #include <set>
13 #include <limits> 13 #include <limits>
14 #include <stdio.h> 14 #include <stdio.h>
15 #include <string.h> 15 #include <string.h>
16 #include <GLES2/gl2ext.h> 16 #include <GLES2/gl2ext.h>
17 #include "../client/buffer_tracker.h" 17 #include "../client/buffer_tracker.h"
18 #include "../client/mapped_memory.h" 18 #include "../client/mapped_memory.h"
19 #include "../client/program_info_manager.h" 19 #include "../client/program_info_manager.h"
20 #include "../client/query_tracker.h" 20 #include "../client/query_tracker.h"
21 #include "../client/transfer_buffer.h" 21 #include "../client/transfer_buffer.h"
22 #include "../client/vertex_array_object_manager.h"
22 #include "../common/gles2_cmd_utils.h" 23 #include "../common/gles2_cmd_utils.h"
23 #include "../common/trace_event.h" 24 #include "../common/trace_event.h"
24 25
25 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 26 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
26 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS 27 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
27 #endif 28 #endif
28 29
29 #if defined(GPU_CLIENT_DEBUG) 30 #if defined(GPU_CLIENT_DEBUG)
30 #include "ui/gl/gl_switches.h" 31 #include "ui/gl/gl_switches.h"
31 #include "base/command_line.h" 32 #include "base/command_line.h"
32 #endif 33 #endif
33 34
34 namespace gpu { 35 namespace gpu {
35 namespace gles2 { 36 namespace gles2 {
36 37
37 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. 38 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint.
38 static GLuint ToGLuint(const void* ptr) { 39 static GLuint ToGLuint(const void* ptr) {
39 return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); 40 return static_cast<GLuint>(reinterpret_cast<size_t>(ptr));
40 } 41 }
41 42
42 static GLsizei RoundUpToMultipleOf4(GLsizei size) {
43 return (size + 3) & ~3;
44 }
45
46 // This class tracks VertexAttribPointers and helps emulate client side buffers.
47 //
48 // The way client side buffers work is we shadow all the Vertex Attribs so we
49 // know which ones are pointing to client side buffers.
50 //
51 // At Draw time, for any attribs pointing to client side buffers we copy them
52 // to a special VBO and reset the actual vertex attrib pointers to point to this
53 // VBO.
54 //
55 // This also means we have to catch calls to query those values so that when
56 // an attrib is a client side buffer we pass the info back the user expects.
57 class ClientSideBufferHelper {
58 public:
59 // Info about Vertex Attributes. This is used to track what the user currently
60 // has bound on each Vertex Attribute so we can simulate client side buffers
61 // at glDrawXXX time.
62 class VertexAttribInfo {
63 public:
64 VertexAttribInfo()
65 : enabled_(false),
66 buffer_id_(0),
67 size_(4),
68 type_(GL_FLOAT),
69 normalized_(GL_FALSE),
70 pointer_(NULL),
71 gl_stride_(0),
72 divisor_(0) {
73 }
74
75 bool enabled() const {
76 return enabled_;
77 }
78
79 void set_enabled(bool enabled) {
80 enabled_ = enabled;
81 }
82
83 GLuint buffer_id() const {
84 return buffer_id_;
85 }
86
87 GLenum type() const {
88 return type_;
89 }
90
91 GLint size() const {
92 return size_;
93 }
94
95 GLsizei stride() const {
96 return gl_stride_;
97 }
98
99 GLboolean normalized() const {
100 return normalized_;
101 }
102
103 const GLvoid* pointer() const {
104 return pointer_;
105 }
106
107 bool IsClientSide() const {
108 return buffer_id_ == 0;
109 }
110
111 GLuint divisor() const {
112 return divisor_;
113 }
114
115 void SetInfo(
116 GLuint buffer_id,
117 GLint size,
118 GLenum type,
119 GLboolean normalized,
120 GLsizei gl_stride,
121 const GLvoid* pointer) {
122 buffer_id_ = buffer_id;
123 size_ = size;
124 type_ = type;
125 normalized_ = normalized;
126 gl_stride_ = gl_stride;
127 pointer_ = pointer;
128 }
129
130 void SetDivisor(GLuint divisor) {
131 divisor_ = divisor;
132 }
133
134 private:
135 // Whether or not this attribute is enabled.
136 bool enabled_;
137
138 // The id of the buffer. 0 = client side buffer.
139 GLuint buffer_id_;
140
141 // Number of components (1, 2, 3, 4).
142 GLint size_;
143
144 // GL_BYTE, GL_FLOAT, etc. See glVertexAttribPointer.
145 GLenum type_;
146
147 // GL_TRUE or GL_FALSE
148 GLboolean normalized_;
149
150 // The pointer/offset into the buffer.
151 const GLvoid* pointer_;
152
153 // The stride that will be used to access the buffer. This is the bogus GL
154 // stride where 0 = compute the stride based on size and type.
155 GLsizei gl_stride_;
156
157 // Divisor, for geometry instancing.
158 GLuint divisor_;
159 };
160
161 ClientSideBufferHelper(GLuint max_vertex_attribs,
162 GLuint array_buffer_id,
163 GLuint element_array_buffer_id)
164 : max_vertex_attribs_(max_vertex_attribs),
165 num_client_side_pointers_enabled_(0),
166 array_buffer_id_(array_buffer_id),
167 array_buffer_size_(0),
168 array_buffer_offset_(0),
169 element_array_buffer_id_(element_array_buffer_id),
170 element_array_buffer_size_(0),
171 collection_buffer_size_(0) {
172 vertex_attrib_infos_.reset(new VertexAttribInfo[max_vertex_attribs]);
173 }
174
175 bool HaveEnabledClientSideBuffers() const {
176 return num_client_side_pointers_enabled_ > 0;
177 }
178
179 void SetAttribEnable(GLuint index, bool enabled) {
180 if (index < max_vertex_attribs_) {
181 VertexAttribInfo& info = vertex_attrib_infos_[index];
182 if (info.enabled() != enabled) {
183 if (info.IsClientSide()) {
184 num_client_side_pointers_enabled_ += enabled ? 1 : -1;
185 }
186 info.set_enabled(enabled);
187 }
188 }
189 }
190
191 void SetAttribPointer(
192 GLuint buffer_id,
193 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
194 const void* ptr) {
195 if (index < max_vertex_attribs_) {
196 VertexAttribInfo& info = vertex_attrib_infos_[index];
197 if (info.IsClientSide() && info.enabled()) {
198 --num_client_side_pointers_enabled_;
199 }
200
201 info.SetInfo(buffer_id, size, type, normalized, stride, ptr);
202
203 if (info.IsClientSide() && info.enabled()) {
204 ++num_client_side_pointers_enabled_;
205 }
206 }
207 }
208
209 void SetAttribDivisor(GLuint index, GLuint divisor) {
210 if (index < max_vertex_attribs_) {
211 VertexAttribInfo& info = vertex_attrib_infos_[index];
212
213 info.SetDivisor(divisor);
214 }
215 }
216
217 // Gets the Attrib pointer for an attrib but only if it's a client side
218 // pointer. Returns true if it got the pointer.
219 bool GetAttribPointer(GLuint index, GLenum pname, void** ptr) const {
220 const VertexAttribInfo* info = GetAttribInfo(index);
221 if (info && pname == GL_VERTEX_ATTRIB_ARRAY_POINTER) {
222 *ptr = const_cast<void*>(info->pointer());
223 return true;
224 }
225 return false;
226 }
227
228 // Gets an attrib info if it's in range and it's client side.
229 const VertexAttribInfo* GetAttribInfo(GLuint index) const {
230 if (index < max_vertex_attribs_) {
231 VertexAttribInfo* info = &vertex_attrib_infos_[index];
232 if (info->IsClientSide()) {
233 return info;
234 }
235 }
236 return NULL;
237 }
238
239 // Collects the data into the collection buffer and returns the number of
240 // bytes collected.
241 GLsizei CollectData(const void* data,
242 GLsizei bytes_per_element,
243 GLsizei real_stride,
244 GLsizei num_elements) {
245 GLsizei bytes_needed = bytes_per_element * num_elements;
246 if (collection_buffer_size_ < bytes_needed) {
247 collection_buffer_.reset(new int8[bytes_needed]);
248 collection_buffer_size_ = bytes_needed;
249 }
250 const int8* src = static_cast<const int8*>(data);
251 int8* dst = collection_buffer_.get();
252 int8* end = dst + bytes_per_element * num_elements;
253 for (; dst < end; src += real_stride, dst += bytes_per_element) {
254 memcpy(dst, src, bytes_per_element);
255 }
256 return bytes_needed;
257 }
258
259 // Returns true if buffers were setup.
260 void SetupSimulatedClientSideBuffers(
261 GLES2Implementation* gl,
262 GLES2CmdHelper* gl_helper,
263 GLsizei num_elements,
264 GLsizei primcount) {
265 GLsizei total_size = 0;
266 // Compute the size of the buffer we need.
267 for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) {
268 VertexAttribInfo& info = vertex_attrib_infos_[ii];
269 if (info.IsClientSide() && info.enabled()) {
270 size_t bytes_per_element =
271 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(info.type()) *
272 info.size();
273 GLsizei elements = (primcount && info.divisor() > 0) ?
274 ((primcount - 1) / info.divisor() + 1) : num_elements;
275 total_size += RoundUpToMultipleOf4(
276 bytes_per_element * elements);
277 }
278 }
279 gl_helper->BindBuffer(GL_ARRAY_BUFFER, array_buffer_id_);
280 array_buffer_offset_ = 0;
281 if (total_size > array_buffer_size_) {
282 gl->BufferDataHelper(GL_ARRAY_BUFFER, total_size, NULL, GL_DYNAMIC_DRAW);
283 array_buffer_size_ = total_size;
284 }
285 for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) {
286 VertexAttribInfo& info = vertex_attrib_infos_[ii];
287 if (info.IsClientSide() && info.enabled()) {
288 size_t bytes_per_element =
289 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(info.type()) *
290 info.size();
291 GLsizei real_stride = info.stride() ?
292 info.stride() : static_cast<GLsizei>(bytes_per_element);
293 GLsizei elements = (primcount && info.divisor() > 0) ?
294 ((primcount - 1) / info.divisor() + 1) : num_elements;
295 GLsizei bytes_collected = CollectData(
296 info.pointer(), bytes_per_element, real_stride, elements);
297 gl->BufferSubDataHelper(
298 GL_ARRAY_BUFFER, array_buffer_offset_, bytes_collected,
299 collection_buffer_.get());
300 gl_helper->VertexAttribPointer(
301 ii, info.size(), info.type(), info.normalized(), 0,
302 array_buffer_offset_);
303 array_buffer_offset_ += RoundUpToMultipleOf4(bytes_collected);
304 GPU_DCHECK_LE(array_buffer_offset_, array_buffer_size_);
305 }
306 }
307 }
308
309 // Copies in indices to the service and returns the highest index accessed + 1
310 bool SetupSimulatedIndexBuffer(
311 GLES2Implementation* gl,
312 GLES2CmdHelper* gl_helper,
313 GLsizei count,
314 GLenum type,
315 const void* indices,
316 GLsizei* max_index_out) {
317 GLsizei max_index = -1;
318 switch (type) {
319 case GL_UNSIGNED_BYTE: {
320 const uint8* src = static_cast<const uint8*>(indices);
321 for (GLsizei ii = 0; ii < count; ++ii) {
322 if (src[ii] > max_index) {
323 max_index = src[ii];
324 }
325 }
326 break;
327 }
328 case GL_UNSIGNED_SHORT: {
329 const uint16* src = static_cast<const uint16*>(indices);
330 for (GLsizei ii = 0; ii < count; ++ii) {
331 if (src[ii] > max_index) {
332 max_index = src[ii];
333 }
334 }
335 break;
336 }
337 case GL_UNSIGNED_INT: {
338 uint32 max_glsizei = static_cast<uint32>(
339 std::numeric_limits<GLsizei>::max());
340 const uint32* src = static_cast<const uint32*>(indices);
341 for (GLsizei ii = 0; ii < count; ++ii) {
342 // Other parts of the API use GLsizei (signed) to store limits.
343 // As such, if we encounter a index that cannot be represented with
344 // an unsigned int we need to flag it as an error here.
345
346 if(src[ii] > max_glsizei) {
347 return false;
348 }
349 GLsizei signed_index = static_cast<GLsizei>(src[ii]);
350 if (signed_index > max_index) {
351 max_index = signed_index;
352 }
353 }
354 break;
355 }
356 default:
357 break;
358 }
359 gl_helper->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_array_buffer_id_);
360 GLsizei bytes_per_element =
361 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
362 GLsizei bytes_needed = bytes_per_element * count;
363 if (bytes_needed > element_array_buffer_size_) {
364 element_array_buffer_size_ = bytes_needed;
365 gl->BufferDataHelper(
366 GL_ELEMENT_ARRAY_BUFFER, bytes_needed, NULL, GL_DYNAMIC_DRAW);
367 }
368 gl->BufferSubDataHelper(
369 GL_ELEMENT_ARRAY_BUFFER, 0, bytes_needed, indices);
370
371 *max_index_out = max_index + 1;
372 return true;
373 }
374
375 private:
376 GLuint max_vertex_attribs_;
377 GLuint num_client_side_pointers_enabled_;
378 GLuint array_buffer_id_;
379 GLsizei array_buffer_size_;
380 GLsizei array_buffer_offset_;
381 GLuint element_array_buffer_id_;
382 GLsizei element_array_buffer_size_;
383 scoped_array<VertexAttribInfo> vertex_attrib_infos_;
384 GLsizei collection_buffer_size_;
385 scoped_array<int8> collection_buffer_;
386
387 DISALLOW_COPY_AND_ASSIGN(ClientSideBufferHelper);
388 };
389
390 #if !defined(_MSC_VER) 43 #if !defined(_MSC_VER)
391 const size_t GLES2Implementation::kMaxSizeOfSimpleResult; 44 const size_t GLES2Implementation::kMaxSizeOfSimpleResult;
392 const unsigned int GLES2Implementation::kStartingOffset; 45 const unsigned int GLES2Implementation::kStartingOffset;
393 #endif 46 #endif
394 47
395 GLES2Implementation::GLStaticState::IntState::IntState() 48 GLES2Implementation::GLStaticState::IntState::IntState()
396 : max_combined_texture_image_units(0), 49 : max_combined_texture_image_units(0),
397 max_cube_map_texture_size(0), 50 max_cube_map_texture_size(0),
398 max_fragment_uniform_vectors(0), 51 max_fragment_uniform_vectors(0),
399 max_renderbuffer_size(0), 52 max_renderbuffer_size(0),
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 unpack_flip_y_(false), 86 unpack_flip_y_(false),
434 unpack_row_length_(0), 87 unpack_row_length_(0),
435 unpack_skip_rows_(0), 88 unpack_skip_rows_(0),
436 unpack_skip_pixels_(0), 89 unpack_skip_pixels_(0),
437 pack_reverse_row_order_(false), 90 pack_reverse_row_order_(false),
438 active_texture_unit_(0), 91 active_texture_unit_(0),
439 bound_framebuffer_(0), 92 bound_framebuffer_(0),
440 bound_renderbuffer_(0), 93 bound_renderbuffer_(0),
441 current_program_(0), 94 current_program_(0),
442 bound_array_buffer_id_(0), 95 bound_array_buffer_id_(0),
443 bound_element_array_buffer_id_(0),
444 bound_pixel_unpack_transfer_buffer_id_(0), 96 bound_pixel_unpack_transfer_buffer_id_(0),
445 client_side_array_id_(0),
446 client_side_element_array_id_(0),
447 bound_vertex_array_id_(0),
448 error_bits_(0), 97 error_bits_(0),
449 debug_(false), 98 debug_(false),
450 use_count_(0), 99 use_count_(0),
451 current_query_(NULL), 100 current_query_(NULL),
452 error_message_callback_(NULL) { 101 error_message_callback_(NULL) {
453 GPU_DCHECK(helper); 102 GPU_DCHECK(helper);
454 GPU_DCHECK(transfer_buffer); 103 GPU_DCHECK(transfer_buffer);
455 104
456 char temp[128]; 105 char temp[128];
457 sprintf(temp, "%p", static_cast<void*>(this)); 106 sprintf(temp, "%p", static_cast<void*>(this));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 texture_units_.reset( 166 texture_units_.reset(
518 new TextureUnit[ 167 new TextureUnit[
519 static_state_.int_state.max_combined_texture_image_units]); 168 static_state_.int_state.max_combined_texture_image_units]);
520 169
521 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); 170 query_tracker_.reset(new QueryTracker(mapped_memory_.get()));
522 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); 171 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get()));
523 172
524 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 173 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
525 GetIdHandler(id_namespaces::kBuffers)->MakeIds( 174 GetIdHandler(id_namespaces::kBuffers)->MakeIds(
526 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); 175 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]);
176 #endif
527 177
528 client_side_buffer_helper_.reset(new ClientSideBufferHelper( 178 vertex_array_object_manager_.reset(new VertexArrayObjectManager(
529 static_state_.int_state.max_vertex_attribs, 179 static_state_.int_state.max_vertex_attribs,
530 reserved_ids_[0], 180 reserved_ids_[0],
531 reserved_ids_[1])); 181 reserved_ids_[1]));
532 #endif
533 182
534 return true; 183 return true;
535 } 184 }
536 185
537 GLES2Implementation::~GLES2Implementation() { 186 GLES2Implementation::~GLES2Implementation() {
538 // Make sure the queries are finished otherwise we'll delete the 187 // Make sure the queries are finished otherwise we'll delete the
539 // shared memory (mapped_memory_) which will free the memory used 188 // shared memory (mapped_memory_) which will free the memory used
540 // by the queries. The GPU process when validating that memory is still 189 // by the queries. The GPU process when validating that memory is still
541 // shared will fail and abort (ie, it will stop running). 190 // shared will fail and abort (ie, it will stop running).
542 Finish(); 191 Finish();
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 *params = static_state_.int_state.num_shader_binary_formats; 546 *params = static_state_.int_state.num_shader_binary_formats;
898 return true; 547 return true;
899 case GL_ARRAY_BUFFER_BINDING: 548 case GL_ARRAY_BUFFER_BINDING:
900 if (share_group_->bind_generates_resource()) { 549 if (share_group_->bind_generates_resource()) {
901 *params = bound_array_buffer_id_; 550 *params = bound_array_buffer_id_;
902 return true; 551 return true;
903 } 552 }
904 return false; 553 return false;
905 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 554 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
906 if (share_group_->bind_generates_resource()) { 555 if (share_group_->bind_generates_resource()) {
907 *params = bound_element_array_buffer_id_; 556 *params =
557 vertex_array_object_manager_->bound_element_array_buffer();
908 return true; 558 return true;
909 } 559 }
910 return false; 560 return false;
911 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: 561 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM:
912 *params = bound_pixel_unpack_transfer_buffer_id_; 562 *params = bound_pixel_unpack_transfer_buffer_id_;
913 return true; 563 return true;
914 case GL_ACTIVE_TEXTURE: 564 case GL_ACTIVE_TEXTURE:
915 *params = active_texture_unit_ + GL_TEXTURE0; 565 *params = active_texture_unit_ + GL_TEXTURE0;
916 return true; 566 return true;
917 case GL_TEXTURE_BINDING_2D: 567 case GL_TEXTURE_BINDING_2D:
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetMaxValueInBufferCHROMIUM(" 637 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetMaxValueInBufferCHROMIUM("
988 << buffer_id << ", " << count << ", " 638 << buffer_id << ", " << count << ", "
989 << GLES2Util::GetStringGetMaxIndexType(type) 639 << GLES2Util::GetStringGetMaxIndexType(type)
990 << ", " << offset << ")"); 640 << ", " << offset << ")");
991 GLuint result = GetMaxValueInBufferCHROMIUMHelper( 641 GLuint result = GetMaxValueInBufferCHROMIUMHelper(
992 buffer_id, count, type, offset); 642 buffer_id, count, type, offset);
993 GPU_CLIENT_LOG("returned " << result); 643 GPU_CLIENT_LOG("returned " << result);
994 return result; 644 return result;
995 } 645 }
996 646
647 void GLES2Implementation::RestoreElementAndArrayBuffers(bool restore) {
648 if (restore) {
649 RestoreArrayBuffer(restore);
650 // Restore the element array binding.
651 // We only need to restore it if it wasn't a client side array.
652 if (vertex_array_object_manager_->bound_element_array_buffer() == 0) {
653 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
654 }
655 }
656 }
657
658 void GLES2Implementation::RestoreArrayBuffer(bool restore) {
659 if (restore) {
660 // Restore the user's current binding.
661 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
662 }
663 }
664
997 void GLES2Implementation::Clear(GLbitfield mask) { 665 void GLES2Implementation::Clear(GLbitfield mask) {
998 GPU_CLIENT_SINGLE_THREAD_CHECK(); 666 GPU_CLIENT_SINGLE_THREAD_CHECK();
999 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClear(" << mask << ")"); 667 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClear(" << mask << ")");
1000 helper_->Clear(mask); 668 helper_->Clear(mask);
1001 } 669 }
1002 670
1003 void GLES2Implementation::DrawElements( 671 void GLES2Implementation::DrawElements(
1004 GLenum mode, GLsizei count, GLenum type, const void* indices) { 672 GLenum mode, GLsizei count, GLenum type, const void* indices) {
1005 GPU_CLIENT_SINGLE_THREAD_CHECK(); 673 GPU_CLIENT_SINGLE_THREAD_CHECK();
1006 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements(" 674 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements("
1007 << GLES2Util::GetStringDrawMode(mode) << ", " 675 << GLES2Util::GetStringDrawMode(mode) << ", "
1008 << count << ", " 676 << count << ", "
1009 << GLES2Util::GetStringIndexType(type) << ", " 677 << GLES2Util::GetStringIndexType(type) << ", "
1010 << static_cast<const void*>(indices) << ")"); 678 << static_cast<const void*>(indices) << ")");
1011 if (count < 0) { 679 if (count < 0) {
1012 SetGLError(GL_INVALID_VALUE, "glDrawElements", "count less than 0."); 680 SetGLError(GL_INVALID_VALUE, "glDrawElements", "count less than 0.");
1013 return; 681 return;
1014 } 682 }
1015 if (count == 0) { 683 if (count == 0) {
1016 return; 684 return;
1017 } 685 }
1018 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 686 GLuint offset = 0;
1019 bool have_client_side = 687 bool simulated = false;
1020 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); 688 if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers(
1021 GLsizei num_elements = 0; 689 "glDrawElements", this, helper_, count, type, 0, indices,
1022 GLuint offset = ToGLuint(indices); 690 &offset, &simulated)) {
1023 bool success; 691 return;
1024 if (bound_element_array_buffer_id_ == 0) {
1025 // Index buffer is client side array.
1026 // Copy to buffer, scan for highest index.
1027 success = client_side_buffer_helper_->SetupSimulatedIndexBuffer(
1028 this, helper_, count, type, indices, &num_elements);
1029
1030 if(!success) {
1031 SetGLError(GL_INVALID_OPERATION, "glDrawElements", "index too large.");
1032 return;
1033 }
1034
1035 offset = 0;
1036 } else {
1037 // Index buffer is GL buffer. Ask the service for the highest vertex
1038 // that will be accessed. Note: It doesn't matter if another context
1039 // changes the contents of any of the buffers. The service will still
1040 // validate the indices. We just need to know how much to copy across.
1041 if (have_client_side) {
1042 num_elements = GetMaxValueInBufferCHROMIUMHelper(
1043 bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1;
1044 }
1045 }
1046 if (have_client_side) {
1047 client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
1048 this, helper_, num_elements, 0);
1049 } 692 }
1050 helper_->DrawElements(mode, count, type, offset); 693 helper_->DrawElements(mode, count, type, offset);
1051 if (have_client_side) { 694 RestoreElementAndArrayBuffers(simulated);
1052 // Restore the user's current binding.
1053 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
1054 }
1055 if (bound_element_array_buffer_id_ == 0) {
1056 // Restore the element array binding.
1057 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1058 }
1059 #else
1060 helper_->DrawElements(mode, count, type, ToGLuint(indices));
1061 #endif
1062 } 695 }
1063 696
1064 void GLES2Implementation::Flush() { 697 void GLES2Implementation::Flush() {
1065 GPU_CLIENT_SINGLE_THREAD_CHECK(); 698 GPU_CLIENT_SINGLE_THREAD_CHECK();
1066 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()"); 699 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()");
1067 // Insert the cmd to call glFlush 700 // Insert the cmd to call glFlush
1068 helper_->Flush(); 701 helper_->Flush();
1069 // Flush our command buffer 702 // Flush our command buffer
1070 // (tell the service to execute up to the flush cmd.) 703 // (tell the service to execute up to the flush cmd.)
1071 helper_->CommandBufferHelper::Flush(); 704 helper_->CommandBufferHelper::Flush();
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 program, location, kResultBucketId); 859 program, location, kResultBucketId);
1227 helper_->SetBucketSize(kResultBucketId, 0); 860 helper_->SetBucketSize(kResultBucketId, 0);
1228 } 861 }
1229 862
1230 void GLES2Implementation::GetVertexAttribPointerv( 863 void GLES2Implementation::GetVertexAttribPointerv(
1231 GLuint index, GLenum pname, void** ptr) { 864 GLuint index, GLenum pname, void** ptr) {
1232 GPU_CLIENT_SINGLE_THREAD_CHECK(); 865 GPU_CLIENT_SINGLE_THREAD_CHECK();
1233 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribPointer(" 866 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribPointer("
1234 << index << ", " << GLES2Util::GetStringVertexPointer(pname) << ", " 867 << index << ", " << GLES2Util::GetStringVertexPointer(pname) << ", "
1235 << static_cast<void*>(ptr) << ")"); 868 << static_cast<void*>(ptr) << ")");
1236 869 GPU_CLIENT_LOG_CODE_BLOCK(int32 num_results = 1);
1237 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 870 if (!vertex_array_object_manager_->GetAttribPointer(index, pname, ptr)) {
1238 // If it's a client side buffer the client has the data. 871 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv");
1239 if (client_side_buffer_helper_->GetAttribPointer(index, pname, ptr)) { 872 typedef gles2::GetVertexAttribPointerv::Result Result;
1240 return; 873 Result* result = GetResultAs<Result*>();
874 if (!result) {
875 return;
876 }
877 result->SetNumResults(0);
878 helper_->GetVertexAttribPointerv(
879 index, pname, GetResultShmId(), GetResultShmOffset());
880 WaitForCmd();
881 result->CopyResult(ptr);
882 GPU_CLIENT_LOG_CODE_BLOCK(num_results = result->GetNumResults());
1241 } 883 }
1242 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1243
1244 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv");
1245 typedef gles2::GetVertexAttribPointerv::Result Result;
1246 Result* result = GetResultAs<Result*>();
1247 if (!result) {
1248 return;
1249 }
1250 result->SetNumResults(0);
1251 helper_->GetVertexAttribPointerv(
1252 index, pname, GetResultShmId(), GetResultShmOffset());
1253 WaitForCmd();
1254 result->CopyResult(ptr);
1255 GPU_CLIENT_LOG_CODE_BLOCK({ 884 GPU_CLIENT_LOG_CODE_BLOCK({
1256 for (int32 i = 0; i < result->GetNumResults(); ++i) { 885 for (int32 i = 0; i < num_results; ++i) {
1257 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); 886 GPU_CLIENT_LOG(" " << i << ": " << ptr[i]);
1258 } 887 }
1259 }); 888 });
1260 } 889 }
1261 890
1262 bool GLES2Implementation::DeleteProgramHelper(GLuint program) { 891 bool GLES2Implementation::DeleteProgramHelper(GLuint program) {
1263 if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds( 892 if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds(
1264 this, 1, &program, &GLES2Implementation::DeleteProgramStub)) { 893 this, 1, &program, &GLES2Implementation::DeleteProgramStub)) {
1265 SetGLError( 894 SetGLError(
1266 GL_INVALID_VALUE, 895 GL_INVALID_VALUE,
1267 "glDeleteProgram", "id not created by this context."); 896 "glDeleteProgram", "id not created by this context.");
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1461 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, 1090 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
1462 const void* ptr) { 1091 const void* ptr) {
1463 GPU_CLIENT_SINGLE_THREAD_CHECK(); 1092 GPU_CLIENT_SINGLE_THREAD_CHECK();
1464 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribPointer(" 1093 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribPointer("
1465 << index << ", " 1094 << index << ", "
1466 << size << ", " 1095 << size << ", "
1467 << GLES2Util::GetStringVertexAttribType(type) << ", " 1096 << GLES2Util::GetStringVertexAttribType(type) << ", "
1468 << GLES2Util::GetStringBool(normalized) << ", " 1097 << GLES2Util::GetStringBool(normalized) << ", "
1469 << stride << ", " 1098 << stride << ", "
1470 << static_cast<const void*>(ptr) << ")"); 1099 << static_cast<const void*>(ptr) << ")");
1100 // Record the info on the client side.
1101 if (!vertex_array_object_manager_->SetAttribPointer(
1102 bound_array_buffer_id_, index, size, type, normalized, stride, ptr)) {
1103 SetGLError(GL_INVALID_OPERATION, "glVertexAttribPointer",
1104 "client side arrays are not allowed in vertex array objects.");
1105 return;
1106 }
1471 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 1107 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1472 // Record the info on the client side.
1473 client_side_buffer_helper_->SetAttribPointer(
1474 bound_array_buffer_id_, index, size, type, normalized, stride, ptr);
1475 if (bound_array_buffer_id_ != 0) { 1108 if (bound_array_buffer_id_ != 0) {
1476 // Only report NON client side buffers to the service. 1109 // Only report NON client side buffers to the service.
1477 helper_->VertexAttribPointer(index, size, type, normalized, stride, 1110 helper_->VertexAttribPointer(index, size, type, normalized, stride,
1478 ToGLuint(ptr)); 1111 ToGLuint(ptr));
1479 } 1112 }
1480 #else // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 1113 #else // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1481 helper_->VertexAttribPointer(index, size, type, normalized, stride, 1114 helper_->VertexAttribPointer(index, size, type, normalized, stride,
1482 ToGLuint(ptr)); 1115 ToGLuint(ptr));
1483 #endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 1116 #endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1484 } 1117 }
1485 1118
1486 void GLES2Implementation::VertexAttribDivisorANGLE( 1119 void GLES2Implementation::VertexAttribDivisorANGLE(
1487 GLuint index, GLuint divisor) { 1120 GLuint index, GLuint divisor) {
1488 GPU_CLIENT_SINGLE_THREAD_CHECK(); 1121 GPU_CLIENT_SINGLE_THREAD_CHECK();
1489 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE(" 1122 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE("
1490 << index << ", " 1123 << index << ", "
1491 << divisor << ") "); 1124 << divisor << ") ");
1492 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1493 // Record the info on the client side. 1125 // Record the info on the client side.
1494 client_side_buffer_helper_->SetAttribDivisor(index, divisor); 1126 vertex_array_object_manager_->SetAttribDivisor(index, divisor);
1495 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1496 helper_->VertexAttribDivisorANGLE(index, divisor); 1127 helper_->VertexAttribDivisorANGLE(index, divisor);
1497 } 1128 }
1498 1129
1499 void GLES2Implementation::ShaderSource( 1130 void GLES2Implementation::ShaderSource(
1500 GLuint shader, GLsizei count, const char** source, const GLint* length) { 1131 GLuint shader, GLsizei count, const char** source, const GLint* length) {
1501 GPU_CLIENT_SINGLE_THREAD_CHECK(); 1132 GPU_CLIENT_SINGLE_THREAD_CHECK();
1502 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" 1133 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource("
1503 << shader << ", " << count << ", " 1134 << shader << ", " << count << ", "
1504 << static_cast<const void*>(source) << ", " 1135 << static_cast<const void*>(source) << ", "
1505 << static_cast<const void*>(length) << ")"); 1136 << static_cast<const void*>(length) << ")");
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 static_state_.int_state.max_combined_texture_image_units)) { 2100 static_state_.int_state.max_combined_texture_image_units)) {
2470 SetGLErrorInvalidEnum( 2101 SetGLErrorInvalidEnum(
2471 "glActiveTexture", texture, "texture"); 2102 "glActiveTexture", texture, "texture");
2472 return; 2103 return;
2473 } 2104 }
2474 2105
2475 active_texture_unit_ = texture_index; 2106 active_texture_unit_ = texture_index;
2476 helper_->ActiveTexture(texture); 2107 helper_->ActiveTexture(texture);
2477 } 2108 }
2478 2109
2110 void GLES2Implementation::GenBuffersHelper(
2111 GLsizei /* n */, const GLuint* /* buffers */) {
2112 }
2113
2114 void GLES2Implementation::GenFramebuffersHelper(
2115 GLsizei /* n */, const GLuint* /* framebuffers */) {
2116 }
2117
2118 void GLES2Implementation::GenRenderbuffersHelper(
2119 GLsizei /* n */, const GLuint* /* renderbuffers */) {
2120 }
2121
2122 void GLES2Implementation::GenTexturesHelper(
2123 GLsizei /* n */, const GLuint* /* textures */) {
2124 }
2125
2126 void GLES2Implementation::GenVertexArraysOESHelper(
2127 GLsizei n, const GLuint* arrays) {
2128 vertex_array_object_manager_->GenVertexArrays(n, arrays);
2129 }
2130
2131 void GLES2Implementation::GenQueriesEXTHelper(
2132 GLsizei /* n */, const GLuint* /* queries */) {
2133 }
2134
2479 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id 2135 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id
2480 // generates a new resource. On newer versions of OpenGL they don't. The code 2136 // generates a new resource. On newer versions of OpenGL they don't. The code
2481 // related to binding below will need to change if we switch to the new OpenGL 2137 // related to binding below will need to change if we switch to the new OpenGL
2482 // model. Specifically it assumes a bind will succeed which is always true in 2138 // model. Specifically it assumes a bind will succeed which is always true in
2483 // the old model but possibly not true in the new model if another context has 2139 // the old model but possibly not true in the new model if another context has
2484 // deleted the resource. 2140 // deleted the resource.
2485 2141
2486 bool GLES2Implementation::BindBufferHelper( 2142 bool GLES2Implementation::BindBufferHelper(
2487 GLenum target, GLuint buffer) { 2143 GLenum target, GLuint buffer) {
2488 // TODO(gman): See note #1 above. 2144 // TODO(gman): See note #1 above.
2489 bool changed = false; 2145 bool changed = false;
2490 switch (target) { 2146 switch (target) {
2491 case GL_ARRAY_BUFFER: 2147 case GL_ARRAY_BUFFER:
2492 if (bound_array_buffer_id_ != buffer) { 2148 if (bound_array_buffer_id_ != buffer) {
2493 bound_array_buffer_id_ = buffer; 2149 bound_array_buffer_id_ = buffer;
2494 changed = true; 2150 changed = true;
2495 } 2151 }
2496 break; 2152 break;
2497 case GL_ELEMENT_ARRAY_BUFFER: 2153 case GL_ELEMENT_ARRAY_BUFFER:
2498 if (bound_element_array_buffer_id_ != buffer) { 2154 changed = vertex_array_object_manager_->BindElementArray(buffer);
2499 bound_element_array_buffer_id_ = buffer;
2500 changed = true;
2501 }
2502 break; 2155 break;
2503 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: 2156 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM:
2504 bound_pixel_unpack_transfer_buffer_id_ = buffer; 2157 bound_pixel_unpack_transfer_buffer_id_ = buffer;
2505 break; 2158 break;
2506 default: 2159 default:
2507 changed = true; 2160 changed = true;
2508 break; 2161 break;
2509 } 2162 }
2510 // TODO(gman): There's a bug here. If the target is invalid the ID will not be 2163 // TODO(gman): There's a bug here. If the target is invalid the ID will not be
2511 // used even though it's marked it as used here. 2164 // used even though it's marked it as used here.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2580 } 2233 }
2581 // TODO(gman): There's a bug here. If the target is invalid the ID will not be 2234 // TODO(gman): There's a bug here. If the target is invalid the ID will not be
2582 // used. even though it's marked it as used here. 2235 // used. even though it's marked it as used here.
2583 GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind(texture); 2236 GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind(texture);
2584 return changed; 2237 return changed;
2585 } 2238 }
2586 2239
2587 bool GLES2Implementation::BindVertexArrayHelper(GLuint array) { 2240 bool GLES2Implementation::BindVertexArrayHelper(GLuint array) {
2588 // TODO(gman): See note #1 above. 2241 // TODO(gman): See note #1 above.
2589 bool changed = false; 2242 bool changed = false;
2590 if (bound_vertex_array_id_ != array) { 2243 if (!vertex_array_object_manager_->BindVertexArray(array, &changed)) {
2591 bound_vertex_array_id_ = array; 2244 SetGLError(
2592 changed = true; 2245 GL_INVALID_OPERATION, "glBindVertexArrayOES",
2246 "id was not generated with glGenVertexArrayOES");
2593 } 2247 }
2594 GetIdHandler(id_namespaces::kVertexArrays)->MarkAsUsedForBind(array); 2248 // Unlike other BindXXXHelpers we don't call MarkAsUsedForBind
2249 // because unlike other resources VertexArrayObject ids must
2250 // be generated by GenVertexArrays. A random id to Bind will not
2251 // generate a new object.
2595 return changed; 2252 return changed;
2596 } 2253 }
2597 2254
2598 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
2599 bool GLES2Implementation::IsBufferReservedId(GLuint id) { 2255 bool GLES2Implementation::IsBufferReservedId(GLuint id) {
2600 for (size_t ii = 0; ii < arraysize(reserved_ids_); ++ii) { 2256 return vertex_array_object_manager_->IsReservedId(id);
2601 if (id == reserved_ids_[ii]) {
2602 return true;
2603 }
2604 }
2605 return false;
2606 } 2257 }
2607 #else
2608 bool GLES2Implementation::IsBufferReservedId(GLuint /* id */) {
2609 return false;
2610 }
2611 #endif
2612 2258
2613 void GLES2Implementation::DeleteBuffersHelper( 2259 void GLES2Implementation::DeleteBuffersHelper(
2614 GLsizei n, const GLuint* buffers) { 2260 GLsizei n, const GLuint* buffers) {
2615 if (!GetIdHandler(id_namespaces::kBuffers)->FreeIds( 2261 if (!GetIdHandler(id_namespaces::kBuffers)->FreeIds(
2616 this, n, buffers, &GLES2Implementation::DeleteBuffersStub)) { 2262 this, n, buffers, &GLES2Implementation::DeleteBuffersStub)) {
2617 SetGLError( 2263 SetGLError(
2618 GL_INVALID_VALUE, 2264 GL_INVALID_VALUE,
2619 "glDeleteBuffers", "id not created by this context."); 2265 "glDeleteBuffers", "id not created by this context.");
2620 return; 2266 return;
2621 } 2267 }
2622 for (GLsizei ii = 0; ii < n; ++ii) { 2268 for (GLsizei ii = 0; ii < n; ++ii) {
2623 if (buffers[ii] == bound_array_buffer_id_) { 2269 if (buffers[ii] == bound_array_buffer_id_) {
2624 bound_array_buffer_id_ = 0; 2270 bound_array_buffer_id_ = 0;
2625 } 2271 }
2626 if (buffers[ii] == bound_element_array_buffer_id_) { 2272 vertex_array_object_manager_->UnbindBuffer(buffers[ii]);
2627 bound_element_array_buffer_id_ = 0;
2628 }
2629 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) {
2630 bound_pixel_unpack_transfer_buffer_id_ = 0;
2631 }
2632
2633 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); 2273 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]);
2634 if (buffer) { 2274 if (buffer) {
2635 // Free buffer memory, pending the passage of a token. 2275 // Free buffer memory, pending the passage of a token.
2636 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); 2276 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken());
2637 // Remove buffer. 2277 // Remove buffer.
2638 buffer_tracker_->RemoveBuffer(buffers[ii]); 2278 buffer_tracker_->RemoveBuffer(buffers[ii]);
2639 } 2279 }
2280 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) {
2281 bound_pixel_unpack_transfer_buffer_id_ = 0;
2282 }
2640 } 2283 }
2641 } 2284 }
2642 2285
2643 void GLES2Implementation::DeleteBuffersStub( 2286 void GLES2Implementation::DeleteBuffersStub(
2644 GLsizei n, const GLuint* buffers) { 2287 GLsizei n, const GLuint* buffers) {
2645 helper_->DeleteBuffersImmediate(n, buffers); 2288 helper_->DeleteBuffersImmediate(n, buffers);
2646 } 2289 }
2647 2290
2648 2291
2649 void GLES2Implementation::DeleteFramebuffersHelper( 2292 void GLES2Implementation::DeleteFramebuffersHelper(
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2707 } 2350 }
2708 if (textures[ii] == unit.bound_texture_cube_map) { 2351 if (textures[ii] == unit.bound_texture_cube_map) {
2709 unit.bound_texture_cube_map = 0; 2352 unit.bound_texture_cube_map = 0;
2710 } 2353 }
2711 } 2354 }
2712 } 2355 }
2713 } 2356 }
2714 2357
2715 void GLES2Implementation::DeleteVertexArraysOESHelper( 2358 void GLES2Implementation::DeleteVertexArraysOESHelper(
2716 GLsizei n, const GLuint* arrays) { 2359 GLsizei n, const GLuint* arrays) {
2360 vertex_array_object_manager_->DeleteVertexArrays(n, arrays);
2717 if (!GetIdHandler(id_namespaces::kVertexArrays)->FreeIds( 2361 if (!GetIdHandler(id_namespaces::kVertexArrays)->FreeIds(
2718 this, n, arrays, &GLES2Implementation::DeleteVertexArraysOESStub)) { 2362 this, n, arrays, &GLES2Implementation::DeleteVertexArraysOESStub)) {
2719 SetGLError( 2363 SetGLError(
2720 GL_INVALID_VALUE, 2364 GL_INVALID_VALUE,
2721 "glDeleteVertexArraysOES", "id not created by this context."); 2365 "glDeleteVertexArraysOES", "id not created by this context.");
2722 return; 2366 return;
2723 } 2367 }
2724 for (GLsizei ii = 0; ii < n; ++ii) {
2725 if (arrays[ii] == bound_vertex_array_id_) {
2726 bound_vertex_array_id_ = 0;
2727 }
2728 }
2729 } 2368 }
2730 2369
2731 void GLES2Implementation::DeleteVertexArraysOESStub( 2370 void GLES2Implementation::DeleteVertexArraysOESStub(
2732 GLsizei n, const GLuint* arrays) { 2371 GLsizei n, const GLuint* arrays) {
2733 helper_->DeleteVertexArraysOESImmediate(n, arrays); 2372 helper_->DeleteVertexArraysOESImmediate(n, arrays);
2734 } 2373 }
2735 2374
2736 void GLES2Implementation::DeleteTexturesStub( 2375 void GLES2Implementation::DeleteTexturesStub(
2737 GLsizei n, const GLuint* textures) { 2376 GLsizei n, const GLuint* textures) {
2738 helper_->DeleteTexturesImmediate(n, textures); 2377 helper_->DeleteTexturesImmediate(n, textures);
2739 } 2378 }
2740 2379
2741 void GLES2Implementation::DisableVertexAttribArray(GLuint index) { 2380 void GLES2Implementation::DisableVertexAttribArray(GLuint index) {
2742 GPU_CLIENT_SINGLE_THREAD_CHECK(); 2381 GPU_CLIENT_SINGLE_THREAD_CHECK();
2743 GPU_CLIENT_LOG( 2382 GPU_CLIENT_LOG(
2744 "[" << GetLogPrefix() << "] glDisableVertexAttribArray(" << index << ")"); 2383 "[" << GetLogPrefix() << "] glDisableVertexAttribArray(" << index << ")");
2745 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 2384 vertex_array_object_manager_->SetAttribEnable(index, false);
2746 client_side_buffer_helper_->SetAttribEnable(index, false);
2747 #endif
2748 helper_->DisableVertexAttribArray(index); 2385 helper_->DisableVertexAttribArray(index);
2749 } 2386 }
2750 2387
2751 void GLES2Implementation::EnableVertexAttribArray(GLuint index) { 2388 void GLES2Implementation::EnableVertexAttribArray(GLuint index) {
2752 GPU_CLIENT_SINGLE_THREAD_CHECK(); 2389 GPU_CLIENT_SINGLE_THREAD_CHECK();
2753 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableVertexAttribArray(" 2390 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableVertexAttribArray("
2754 << index << ")"); 2391 << index << ")");
2755 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 2392 vertex_array_object_manager_->SetAttribEnable(index, true);
2756 client_side_buffer_helper_->SetAttribEnable(index, true);
2757 #endif
2758 helper_->EnableVertexAttribArray(index); 2393 helper_->EnableVertexAttribArray(index);
2759 } 2394 }
2760 2395
2761 void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) { 2396 void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) {
2762 GPU_CLIENT_SINGLE_THREAD_CHECK(); 2397 GPU_CLIENT_SINGLE_THREAD_CHECK();
2763 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawArrays(" 2398 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawArrays("
2764 << GLES2Util::GetStringDrawMode(mode) << ", " 2399 << GLES2Util::GetStringDrawMode(mode) << ", "
2765 << first << ", " << count << ")"); 2400 << first << ", " << count << ")");
2766 if (count < 0) { 2401 if (count < 0) {
2767 SetGLError(GL_INVALID_VALUE, "glDrawArrays", "count < 0"); 2402 SetGLError(GL_INVALID_VALUE, "glDrawArrays", "count < 0");
2768 return; 2403 return;
2769 } 2404 }
2770 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 2405 bool simulated = false;
2771 bool have_client_side = 2406 if (!vertex_array_object_manager_->SetupSimulatedClientSideBuffers(
2772 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); 2407 "glDrawArrays", this, helper_, first + count, 0, &simulated)) {
2773 if (have_client_side) { 2408 return;
2774 client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
2775 this, helper_, first + count, 0);
2776 } 2409 }
2777 #endif
2778 helper_->DrawArrays(mode, first, count); 2410 helper_->DrawArrays(mode, first, count);
2779 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 2411 RestoreArrayBuffer(simulated);
2780 if (have_client_side) {
2781 // Restore the user's current binding.
2782 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
2783 }
2784 #endif
2785 } 2412 }
2786 2413
2787 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
2788 bool GLES2Implementation::GetVertexAttribHelper(
2789 GLuint index, GLenum pname, uint32* param) {
2790 const ClientSideBufferHelper::VertexAttribInfo* info =
2791 client_side_buffer_helper_->GetAttribInfo(index);
2792 if (!info) {
2793 return false;
2794 }
2795
2796 switch (pname) {
2797 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2798 *param = info->buffer_id();
2799 break;
2800 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2801 *param = info->enabled();
2802 break;
2803 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2804 *param = info->size();
2805 break;
2806 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2807 *param = info->stride();
2808 break;
2809 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2810 *param = info->type();
2811 break;
2812 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2813 *param = info->normalized();
2814 break;
2815 case GL_CURRENT_VERTEX_ATTRIB:
2816 return false; // pass through to service side.
2817 default:
2818 SetGLErrorInvalidEnum("glGetVertexAttrib", pname, "pname");
2819 break;
2820 }
2821 return true;
2822 }
2823 #endif // GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
2824
2825 void GLES2Implementation::GetVertexAttribfv( 2414 void GLES2Implementation::GetVertexAttribfv(
2826 GLuint index, GLenum pname, GLfloat* params) { 2415 GLuint index, GLenum pname, GLfloat* params) {
2827 GPU_CLIENT_SINGLE_THREAD_CHECK(); 2416 GPU_CLIENT_SINGLE_THREAD_CHECK();
2828 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribfv(" 2417 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribfv("
2829 << index << ", " 2418 << index << ", "
2830 << GLES2Util::GetStringVertexAttribute(pname) << ", " 2419 << GLES2Util::GetStringVertexAttribute(pname) << ", "
2831 << static_cast<const void*>(params) << ")"); 2420 << static_cast<const void*>(params) << ")");
2832 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
2833 uint32 value = 0; 2421 uint32 value = 0;
2834 if (GetVertexAttribHelper(index, pname, &value)) { 2422 if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) {
2835 *params = static_cast<float>(value); 2423 *params = static_cast<float>(value);
2836 return; 2424 return;
2837 } 2425 }
2838 #endif
2839 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv"); 2426 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv");
2840 typedef GetVertexAttribfv::Result Result; 2427 typedef GetVertexAttribfv::Result Result;
2841 Result* result = GetResultAs<Result*>(); 2428 Result* result = GetResultAs<Result*>();
2842 if (!result) { 2429 if (!result) {
2843 return; 2430 return;
2844 } 2431 }
2845 result->SetNumResults(0); 2432 result->SetNumResults(0);
2846 helper_->GetVertexAttribfv( 2433 helper_->GetVertexAttribfv(
2847 index, pname, GetResultShmId(), GetResultShmOffset()); 2434 index, pname, GetResultShmId(), GetResultShmOffset());
2848 WaitForCmd(); 2435 WaitForCmd();
2849 result->CopyResult(params); 2436 result->CopyResult(params);
2850 GPU_CLIENT_LOG_CODE_BLOCK({ 2437 GPU_CLIENT_LOG_CODE_BLOCK({
2851 for (int32 i = 0; i < result->GetNumResults(); ++i) { 2438 for (int32 i = 0; i < result->GetNumResults(); ++i) {
2852 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); 2439 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
2853 } 2440 }
2854 }); 2441 });
2855 } 2442 }
2856 2443
2857 void GLES2Implementation::GetVertexAttribiv( 2444 void GLES2Implementation::GetVertexAttribiv(
2858 GLuint index, GLenum pname, GLint* params) { 2445 GLuint index, GLenum pname, GLint* params) {
2859 GPU_CLIENT_SINGLE_THREAD_CHECK(); 2446 GPU_CLIENT_SINGLE_THREAD_CHECK();
2860 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribiv(" 2447 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribiv("
2861 << index << ", " 2448 << index << ", "
2862 << GLES2Util::GetStringVertexAttribute(pname) << ", " 2449 << GLES2Util::GetStringVertexAttribute(pname) << ", "
2863 << static_cast<const void*>(params) << ")"); 2450 << static_cast<const void*>(params) << ")");
2864 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
2865 uint32 value = 0; 2451 uint32 value = 0;
2866 if (GetVertexAttribHelper(index, pname, &value)) { 2452 if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) {
2867 *params = value; 2453 *params = value;
2868 return; 2454 return;
2869 } 2455 }
2870 #endif
2871 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv"); 2456 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv");
2872 typedef GetVertexAttribiv::Result Result; 2457 typedef GetVertexAttribiv::Result Result;
2873 Result* result = GetResultAs<Result*>(); 2458 Result* result = GetResultAs<Result*>();
2874 if (!result) { 2459 if (!result) {
2875 return; 2460 return;
2876 } 2461 }
2877 result->SetNumResults(0); 2462 result->SetNumResults(0);
2878 helper_->GetVertexAttribiv( 2463 helper_->GetVertexAttribiv(
2879 index, pname, GetResultShmId(), GetResultShmOffset()); 2464 index, pname, GetResultShmId(), GetResultShmOffset());
2880 WaitForCmd(); 2465 WaitForCmd();
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
3442 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "count < 0"); 3027 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "count < 0");
3443 return; 3028 return;
3444 } 3029 }
3445 if (primcount < 0) { 3030 if (primcount < 0) {
3446 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "primcount < 0"); 3031 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "primcount < 0");
3447 return; 3032 return;
3448 } 3033 }
3449 if (primcount == 0) { 3034 if (primcount == 0) {
3450 return; 3035 return;
3451 } 3036 }
3452 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 3037 bool simulated = false;
3453 bool have_client_side = 3038 if (!vertex_array_object_manager_->SetupSimulatedClientSideBuffers(
3454 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); 3039 "glDrawArraysInstancedANGLE", this, helper_, first + count, primcount,
3455 if (have_client_side) { 3040 &simulated)) {
3456 client_side_buffer_helper_->SetupSimulatedClientSideBuffers( 3041 return;
3457 this, helper_, first + count, primcount);
3458 } 3042 }
3459 #endif
3460 helper_->DrawArraysInstancedANGLE(mode, first, count, primcount); 3043 helper_->DrawArraysInstancedANGLE(mode, first, count, primcount);
3461 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 3044 RestoreArrayBuffer(simulated);
3462 if (have_client_side) {
3463 // Restore the user's current binding.
3464 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
3465 }
3466 #endif
3467 } 3045 }
3468 3046
3469 void GLES2Implementation::DrawElementsInstancedANGLE( 3047 void GLES2Implementation::DrawElementsInstancedANGLE(
3470 GLenum mode, GLsizei count, GLenum type, const void* indices, 3048 GLenum mode, GLsizei count, GLenum type, const void* indices,
3471 GLsizei primcount) { 3049 GLsizei primcount) {
3472 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3050 GPU_CLIENT_SINGLE_THREAD_CHECK();
3473 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElementsInstancedANGLE(" 3051 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElementsInstancedANGLE("
3474 << GLES2Util::GetStringDrawMode(mode) << ", " 3052 << GLES2Util::GetStringDrawMode(mode) << ", "
3475 << count << ", " 3053 << count << ", "
3476 << GLES2Util::GetStringIndexType(type) << ", " 3054 << GLES2Util::GetStringIndexType(type) << ", "
3477 << static_cast<const void*>(indices) << ", " 3055 << static_cast<const void*>(indices) << ", "
3478 << primcount << ")"); 3056 << primcount << ")");
3479 if (count < 0) { 3057 if (count < 0) {
3480 SetGLError(GL_INVALID_VALUE, 3058 SetGLError(GL_INVALID_VALUE,
3481 "glDrawElementsInstancedANGLE", "count less than 0."); 3059 "glDrawElementsInstancedANGLE", "count less than 0.");
3482 return; 3060 return;
3483 } 3061 }
3484 if (count == 0) { 3062 if (count == 0) {
3485 return; 3063 return;
3486 } 3064 }
3487 if (primcount < 0) { 3065 if (primcount < 0) {
3488 SetGLError(GL_INVALID_VALUE, 3066 SetGLError(GL_INVALID_VALUE,
3489 "glDrawElementsInstancedANGLE", "primcount < 0"); 3067 "glDrawElementsInstancedANGLE", "primcount < 0");
3490 return; 3068 return;
3491 } 3069 }
3492 if (primcount == 0) { 3070 if (primcount == 0) {
3493 return; 3071 return;
3494 } 3072 }
3495 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 3073 GLuint offset = 0;
3496 bool have_client_side = 3074 bool simulated = false;
3497 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); 3075 if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers(
3498 GLsizei num_elements = 0; 3076 "glDrawElementsInstancedANGLE", this, helper_, count, type, primcount,
3499 GLuint offset = ToGLuint(indices); 3077 indices, &offset, &simulated)) {
3500 bool success; 3078 return;
3501 if (bound_element_array_buffer_id_ == 0) {
3502 // Index buffer is client side array.
3503 // Copy to buffer, scan for highest index.
3504 success = client_side_buffer_helper_->SetupSimulatedIndexBuffer(
3505 this, helper_, count, type, indices, &num_elements);
3506
3507 if(!success) {
3508 SetGLError(GL_INVALID_OPERATION, "glDrawElementsInstancedANGLE",
3509 "index too large.");
3510 return;
3511 }
3512
3513 offset = 0;
3514 } else {
3515 // Index buffer is GL buffer. Ask the service for the highest vertex
3516 // that will be accessed. Note: It doesn't matter if another context
3517 // changes the contents of any of the buffers. The service will still
3518 // validate the indices. We just need to know how much to copy across.
3519 if (have_client_side) {
3520 num_elements = GetMaxValueInBufferCHROMIUMHelper(
3521 bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1;
3522 }
3523 }
3524 if (have_client_side) {
3525 client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
3526 this, helper_, num_elements, primcount);
3527 } 3079 }
3528 helper_->DrawElementsInstancedANGLE(mode, count, type, offset, primcount); 3080 helper_->DrawElementsInstancedANGLE(mode, count, type, offset, primcount);
3529 if (have_client_side) { 3081 RestoreElementAndArrayBuffers(simulated);
3530 // Restore the user's current binding.
3531 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
3532 }
3533 if (bound_element_array_buffer_id_ == 0) {
3534 // Restore the element array binding.
3535 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3536 }
3537 #else
3538 helper_->DrawElementsInstancedANGLE(
3539 mode, count, type, ToGLuint(indices), primcount);
3540 #endif
3541 } 3082 }
3542 3083
3543 void GLES2Implementation::GenMailboxCHROMIUM( 3084 void GLES2Implementation::GenMailboxCHROMIUM(
3544 GLbyte* mailbox) { 3085 GLbyte* mailbox) {
3545 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3086 GPU_CLIENT_SINGLE_THREAD_CHECK();
3546 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenMailboxCHROMIUM(" 3087 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenMailboxCHROMIUM("
3547 << static_cast<const void*>(mailbox) << ")"); 3088 << static_cast<const void*>(mailbox) << ")");
3548 TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM"); 3089 TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM");
3549 3090
3550 helper_->GenMailboxCHROMIUM(kResultBucketId); 3091 helper_->GenMailboxCHROMIUM(kResultBucketId);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3659 return true; 3200 return true;
3660 } 3201 }
3661 3202
3662 // Include the auto-generated part of this file. We split this because it means 3203 // Include the auto-generated part of this file. We split this because it means
3663 // we can easily edit the non-auto generated parts right here in this file 3204 // we can easily edit the non-auto generated parts right here in this file
3664 // instead of having to edit some template or the code generator. 3205 // instead of having to edit some template or the code generator.
3665 #include "../client/gles2_implementation_impl_autogen.h" 3206 #include "../client/gles2_implementation_impl_autogen.h"
3666 3207
3667 } // namespace gles2 3208 } // namespace gles2
3668 } // namespace gpu 3209 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/client/gles2_implementation.h ('k') | gpu/command_buffer/client/gles2_implementation_impl_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698