Chromium Code Reviews
[email protected] (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 unpack_alignment_(4), 85 unpack_alignment_(4),
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 bound_array_buffer_id_(0), 94 bound_array_buffer_id_(0),
442 bound_element_array_buffer_id_(0),
443 bound_pixel_unpack_transfer_buffer_id_(0), 95 bound_pixel_unpack_transfer_buffer_id_(0),
444 client_side_array_id_(0),
445 client_side_element_array_id_(0),
446 bound_vertex_array_id_(0),
447 error_bits_(0), 96 error_bits_(0),
448 debug_(false), 97 debug_(false),
449 use_count_(0), 98 use_count_(0),
450 current_query_(NULL), 99 current_query_(NULL),
451 error_message_callback_(NULL) { 100 error_message_callback_(NULL) {
452 GPU_DCHECK(helper); 101 GPU_DCHECK(helper);
453 GPU_DCHECK(transfer_buffer); 102 GPU_DCHECK(transfer_buffer);
454 103
455 char temp[128]; 104 char temp[128];
456 sprintf(temp, "%p", static_cast<void*>(this)); 105 sprintf(temp, "%p", static_cast<void*>(this));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 texture_units_.reset( 165 texture_units_.reset(
517 new TextureUnit[ 166 new TextureUnit[
518 static_state_.int_state.max_combined_texture_image_units]); 167 static_state_.int_state.max_combined_texture_image_units]);
519 168
520 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); 169 query_tracker_.reset(new QueryTracker(mapped_memory_.get()));
521 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); 170 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get()));
522 171
523 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 172 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
524 GetIdHandler(id_namespaces::kBuffers)->MakeIds( 173 GetIdHandler(id_namespaces::kBuffers)->MakeIds(
525 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); 174 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]);
175 #endif
526 176
527 client_side_buffer_helper_.reset(new ClientSideBufferHelper( 177 vertex_array_object_manager_.reset(new VertexArrayObjectManager(
528 static_state_.int_state.max_vertex_attribs, 178 static_state_.int_state.max_vertex_attribs,
529 reserved_ids_[0], 179 reserved_ids_[0],
530 reserved_ids_[1])); 180 reserved_ids_[1]));
531 #endif
532 181
533 return true; 182 return true;
534 } 183 }
535 184
536 GLES2Implementation::~GLES2Implementation() { 185 GLES2Implementation::~GLES2Implementation() {
537 // Make sure the queries are finished otherwise we'll delete the 186 // Make sure the queries are finished otherwise we'll delete the
538 // shared memory (mapped_memory_) which will free the memory used 187 // shared memory (mapped_memory_) which will free the memory used
539 // by the queries. The GPU process when validating that memory is still 188 // by the queries. The GPU process when validating that memory is still
540 // shared will fail and abort (ie, it will stop running). 189 // shared will fail and abort (ie, it will stop running).
541 Finish(); 190 Finish();
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 *params = static_state_.int_state.num_shader_binary_formats; 545 *params = static_state_.int_state.num_shader_binary_formats;
897 return true; 546 return true;
898 case GL_ARRAY_BUFFER_BINDING: 547 case GL_ARRAY_BUFFER_BINDING:
899 if (share_group_->bind_generates_resource()) { 548 if (share_group_->bind_generates_resource()) {
900 *params = bound_array_buffer_id_; 549 *params = bound_array_buffer_id_;
901 return true; 550 return true;
902 } 551 }
903 return false; 552 return false;
904 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 553 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
905 if (share_group_->bind_generates_resource()) { 554 if (share_group_->bind_generates_resource()) {
906 *params = bound_element_array_buffer_id_; 555 *params =
556 vertex_array_object_manager_->bound_element_array_buffer();
907 return true; 557 return true;
908 } 558 }
909 return false; 559 return false;
910 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: 560 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM:
911 *params = bound_pixel_unpack_transfer_buffer_id_; 561 *params = bound_pixel_unpack_transfer_buffer_id_;
912 return true; 562 return true;
913 case GL_ACTIVE_TEXTURE: 563 case GL_ACTIVE_TEXTURE:
914 *params = active_texture_unit_ + GL_TEXTURE0; 564 *params = active_texture_unit_ + GL_TEXTURE0;
915 return true; 565 return true;
916 case GL_TEXTURE_BINDING_2D: 566 case GL_TEXTURE_BINDING_2D:
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetMaxValueInBufferCHROMIUM(" 636 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetMaxValueInBufferCHROMIUM("
987 << buffer_id << ", " << count << ", " 637 << buffer_id << ", " << count << ", "
988 << GLES2Util::GetStringGetMaxIndexType(type) 638 << GLES2Util::GetStringGetMaxIndexType(type)
989 << ", " << offset << ")"); 639 << ", " << offset << ")");
990 GLuint result = GetMaxValueInBufferCHROMIUMHelper( 640 GLuint result = GetMaxValueInBufferCHROMIUMHelper(
991 buffer_id, count, type, offset); 641 buffer_id, count, type, offset);
992 GPU_CLIENT_LOG("returned " << result); 642 GPU_CLIENT_LOG("returned " << result);
993 return result; 643 return result;
994 } 644 }
995 645
646 void GLES2Implementation::RestoreElementAndArrayBuffers(bool restore) {
647 if (restore) {
648 RestoreArrayBuffer(restore);
649 // Restore the element array binding.
650 // We only need to restore it if it wasn't a client side array.
651 if (vertex_array_object_manager_->bound_element_array_buffer() == 0) {
652 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
653 }
654 }
655 }
656
657 void GLES2Implementation::RestoreArrayBuffer(bool restore) {
658 if (restore) {
659 // Restore the user's current binding.
660 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
661 }
662 }
663
996 void GLES2Implementation::Clear(GLbitfield mask) { 664 void GLES2Implementation::Clear(GLbitfield mask) {
997 GPU_CLIENT_SINGLE_THREAD_CHECK(); 665 GPU_CLIENT_SINGLE_THREAD_CHECK();
998 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClear(" << mask << ")"); 666 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClear(" << mask << ")");
999 helper_->Clear(mask); 667 helper_->Clear(mask);
1000 } 668 }
1001 669
1002 void GLES2Implementation::DrawElements( 670 void GLES2Implementation::DrawElements(
1003 GLenum mode, GLsizei count, GLenum type, const void* indices) { 671 GLenum mode, GLsizei count, GLenum type, const void* indices) {
1004 GPU_CLIENT_SINGLE_THREAD_CHECK(); 672 GPU_CLIENT_SINGLE_THREAD_CHECK();
1005 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements(" 673 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements("
1006 << GLES2Util::GetStringDrawMode(mode) << ", " 674 << GLES2Util::GetStringDrawMode(mode) << ", "
1007 << count << ", " 675 << count << ", "
1008 << GLES2Util::GetStringIndexType(type) << ", " 676 << GLES2Util::GetStringIndexType(type) << ", "
1009 << static_cast<const void*>(indices) << ")"); 677 << static_cast<const void*>(indices) << ")");
1010 if (count < 0) { 678 if (count < 0) {
1011 SetGLError(GL_INVALID_VALUE, "glDrawElements", "count less than 0."); 679 SetGLError(GL_INVALID_VALUE, "glDrawElements", "count less than 0.");
1012 return; 680 return;
1013 } 681 }
1014 if (count == 0) { 682 if (count == 0) {
1015 return; 683 return;
1016 } 684 }
1017 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 685 GLuint offset = 0;
1018 bool have_client_side = 686 bool simulated = false;
1019 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); 687 if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers(
1020 GLsizei num_elements = 0; 688 "glDrawElements", this, helper_, count, type, 0, indices,
1021 GLuint offset = ToGLuint(indices); 689 &offset, &simulated)) {
1022 bool success; 690 return;
1023 if (bound_element_array_buffer_id_ == 0) {
1024 // Index buffer is client side array.
1025 // Copy to buffer, scan for highest index.
1026 success = client_side_buffer_helper_->SetupSimulatedIndexBuffer(
1027 this, helper_, count, type, indices, &num_elements);
1028
1029 if(!success) {
1030 SetGLError(GL_INVALID_OPERATION, "glDrawElements", "index too large.");
1031 return;
1032 }
1033
1034 offset = 0;
1035 } else {
1036 // Index buffer is GL buffer. Ask the service for the highest vertex
1037 // that will be accessed. Note: It doesn't matter if another context
1038 // changes the contents of any of the buffers. The service will still
1039 // validate the indices. We just need to know how much to copy across.
1040 if (have_client_side) {
1041 num_elements = GetMaxValueInBufferCHROMIUMHelper(
1042 bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1;
1043 }
1044 }
1045 if (have_client_side) {
1046 client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
1047 this, helper_, num_elements, 0);
1048 } 691 }
1049 helper_->DrawElements(mode, count, type, offset); 692 helper_->DrawElements(mode, count, type, offset);
1050 if (have_client_side) { 693 RestoreElementAndArrayBuffers(simulated);
1051 // Restore the user's current binding.
1052 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
1053 }
1054 if (bound_element_array_buffer_id_ == 0) {
1055 // Restore the element array binding.
1056 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1057 }
1058 #else
1059 helper_->DrawElements(mode, count, type, ToGLuint(indices));
1060 #endif
1061 } 694 }
1062 695
1063 void GLES2Implementation::Flush() { 696 void GLES2Implementation::Flush() {
1064 GPU_CLIENT_SINGLE_THREAD_CHECK(); 697 GPU_CLIENT_SINGLE_THREAD_CHECK();
1065 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()"); 698 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()");
1066 // Insert the cmd to call glFlush 699 // Insert the cmd to call glFlush
1067 helper_->Flush(); 700 helper_->Flush();
1068 // Flush our command buffer 701 // Flush our command buffer
1069 // (tell the service to execute up to the flush cmd.) 702 // (tell the service to execute up to the flush cmd.)
1070 helper_->CommandBufferHelper::Flush(); 703 helper_->CommandBufferHelper::Flush();
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) 872 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM)
1240 helper_->BindBuffer(target, buffer); 873 helper_->BindBuffer(target, buffer);
1241 } 874 }
1242 875
1243 void GLES2Implementation::GetVertexAttribPointerv( 876 void GLES2Implementation::GetVertexAttribPointerv(
1244 GLuint index, GLenum pname, void** ptr) { 877 GLuint index, GLenum pname, void** ptr) {
1245 GPU_CLIENT_SINGLE_THREAD_CHECK(); 878 GPU_CLIENT_SINGLE_THREAD_CHECK();
1246 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribPointer(" 879 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribPointer("
1247 << index << ", " << GLES2Util::GetStringVertexPointer(pname) << ", " 880 << index << ", " << GLES2Util::GetStringVertexPointer(pname) << ", "
1248 << static_cast<void*>(ptr) << ")"); 881 << static_cast<void*>(ptr) << ")");
1249 882 if (!vertex_array_object_manager_->GetAttribPointer(index, pname, ptr)) {
1250 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 883 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv");
1251 // If it's a client side buffer the client has the data. 884 typedef gles2::GetVertexAttribPointerv::Result Result;
1252 if (client_side_buffer_helper_->GetAttribPointer(index, pname, ptr)) { 885 Result* result = GetResultAs<Result*>();
1253 return; 886 if (!result) {
887 return;
888 }
889 result->SetNumResults(0);
890 helper_->GetVertexAttribPointerv(
891 index, pname, GetResultShmId(), GetResultShmOffset());
892 WaitForCmd();
893 result->CopyResult(ptr);
1254 } 894 }
1255 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1256
1257 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv");
1258 typedef gles2::GetVertexAttribPointerv::Result Result;
1259 Result* result = GetResultAs<Result*>();
1260 if (!result) {
1261 return;
1262 }
1263 result->SetNumResults(0);
1264 helper_->GetVertexAttribPointerv(
1265 index, pname, GetResultShmId(), GetResultShmOffset());
1266 WaitForCmd();
1267 result->CopyResult(ptr);
1268 GPU_CLIENT_LOG_CODE_BLOCK({ 895 GPU_CLIENT_LOG_CODE_BLOCK({
1269 for (int32 i = 0; i < result->GetNumResults(); ++i) { 896 for (int32 i = 0; i < 1; ++i) {
bajones 2012/11/26 18:01:06 Is this a debugging change that should have been r
greggman 2012/11/28 08:18:57 Done.
1270 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); 897 GPU_CLIENT_LOG(" " << i << ": " << ptr[i]);
1271 } 898 }
1272 }); 899 });
1273 } 900 }
1274 901
1275 bool GLES2Implementation::DeleteProgramHelper(GLuint program) { 902 bool GLES2Implementation::DeleteProgramHelper(GLuint program) {
1276 if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds( 903 if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds(
1277 this, 1, &program, &GLES2Implementation::DeleteProgramStub)) { 904 this, 1, &program, &GLES2Implementation::DeleteProgramStub)) {
1278 SetGLError( 905 SetGLError(
1279 GL_INVALID_VALUE, 906 GL_INVALID_VALUE,
1280 "glDeleteProgram", "id not created by this context."); 907 "glDeleteProgram", "id not created by this context.");
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, 1089 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
1463 const void* ptr) { 1090 const void* ptr) {
1464 GPU_CLIENT_SINGLE_THREAD_CHECK(); 1091 GPU_CLIENT_SINGLE_THREAD_CHECK();
1465 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribPointer(" 1092 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribPointer("
1466 << index << ", " 1093 << index << ", "
1467 << size << ", " 1094 << size << ", "
1468 << GLES2Util::GetStringVertexAttribType(type) << ", " 1095 << GLES2Util::GetStringVertexAttribType(type) << ", "
1469 << GLES2Util::GetStringBool(normalized) << ", " 1096 << GLES2Util::GetStringBool(normalized) << ", "
1470 << stride << ", " 1097 << stride << ", "
1471 << static_cast<const void*>(ptr) << ")"); 1098 << static_cast<const void*>(ptr) << ")");
1099 // Record the info on the client side.
1100 if (!vertex_array_object_manager_->SetAttribPointer(
1101 bound_array_buffer_id_, index, size, type, normalized, stride, ptr)) {
1102 SetGLError(GL_INVALID_OPERATION, "glVertexAttribPointer",
1103 "client side arrays are not allowed in vertex array objects.");
1104 return;
1105 }
1472 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 1106 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1473 // Record the info on the client side.
1474 client_side_buffer_helper_->SetAttribPointer(
1475 bound_array_buffer_id_, index, size, type, normalized, stride, ptr);
1476 if (bound_array_buffer_id_ != 0) { 1107 if (bound_array_buffer_id_ != 0) {
1477 // Only report NON client side buffers to the service. 1108 // Only report NON client side buffers to the service.
1478 helper_->VertexAttribPointer(index, size, type, normalized, stride, 1109 helper_->VertexAttribPointer(index, size, type, normalized, stride,
1479 ToGLuint(ptr)); 1110 ToGLuint(ptr));
1480 } 1111 }
1481 #else // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 1112 #else // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1482 helper_->VertexAttribPointer(index, size, type, normalized, stride, 1113 helper_->VertexAttribPointer(index, size, type, normalized, stride,
1483 ToGLuint(ptr)); 1114 ToGLuint(ptr));
1484 #endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 1115 #endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1485 } 1116 }
1486 1117
1487 void GLES2Implementation::VertexAttribDivisorANGLE( 1118 void GLES2Implementation::VertexAttribDivisorANGLE(
1488 GLuint index, GLuint divisor) { 1119 GLuint index, GLuint divisor) {
1489 GPU_CLIENT_SINGLE_THREAD_CHECK(); 1120 GPU_CLIENT_SINGLE_THREAD_CHECK();
1490 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE(" 1121 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE("
1491 << index << ", " 1122 << index << ", "
1492 << divisor << ") "); 1123 << divisor << ") ");
1493 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1494 // Record the info on the client side. 1124 // Record the info on the client side.
1495 client_side_buffer_helper_->SetAttribDivisor(index, divisor); 1125 vertex_array_object_manager_->SetAttribDivisor(index, divisor);
1496 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1497 helper_->VertexAttribDivisorANGLE(index, divisor); 1126 helper_->VertexAttribDivisorANGLE(index, divisor);
1498 } 1127 }
1499 1128
1500 void GLES2Implementation::ShaderSource( 1129 void GLES2Implementation::ShaderSource(
1501 GLuint shader, GLsizei count, const char** source, const GLint* length) { 1130 GLuint shader, GLsizei count, const char** source, const GLint* length) {
1502 GPU_CLIENT_SINGLE_THREAD_CHECK(); 1131 GPU_CLIENT_SINGLE_THREAD_CHECK();
1503 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" 1132 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource("
1504 << shader << ", " << count << ", " 1133 << shader << ", " << count << ", "
1505 << static_cast<const void*>(source) << ", " 1134 << static_cast<const void*>(source) << ", "
1506 << static_cast<const void*>(length) << ")"); 1135 << static_cast<const void*>(length) << ")");
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after
2470 static_state_.int_state.max_combined_texture_image_units)) { 2099 static_state_.int_state.max_combined_texture_image_units)) {
2471 SetGLErrorInvalidEnum( 2100 SetGLErrorInvalidEnum(
2472 "glActiveTexture", texture, "texture"); 2101 "glActiveTexture", texture, "texture");
2473 return; 2102 return;
2474 } 2103 }
2475 2104
2476 active_texture_unit_ = texture_index; 2105 active_texture_unit_ = texture_index;
2477 helper_->ActiveTexture(texture); 2106 helper_->ActiveTexture(texture);
2478 } 2107 }
2479 2108
2109 void GLES2Implementation::GenBuffersHelper(
2110 GLsizei /* n */, const GLuint* /* buffers */) {
2111 }
2112
2113 void GLES2Implementation::GenFramebuffersHelper(
2114 GLsizei /* n */, const GLuint* /* framebuffers */) {
2115 }
2116
2117 void GLES2Implementation::GenRenderbuffersHelper(
2118 GLsizei /* n */, const GLuint* /* renderbuffers */) {
2119 }
2120
2121 void GLES2Implementation::GenTexturesHelper(
2122 GLsizei /* n */, const GLuint* /* textures */) {
2123 }
2124
2125 void GLES2Implementation::GenVertexArraysOESHelper(
2126 GLsizei n, const GLuint* arrays) {
2127 vertex_array_object_manager_->GenVertexArrays(n, arrays);
2128 }
2129
2130 void GLES2Implementation::GenQueriesEXTHelper(
2131 GLsizei /* n */, const GLuint* /* queries */) {
2132 }
2133
2480 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id 2134 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id
2481 // generates a new resource. On newer versions of OpenGL they don't. The code 2135 // generates a new resource. On newer versions of OpenGL they don't. The code
2482 // related to binding below will need to change if we switch to the new OpenGL 2136 // related to binding below will need to change if we switch to the new OpenGL
2483 // model. Specifically it assumes a bind will succeed which is always true in 2137 // model. Specifically it assumes a bind will succeed which is always true in
2484 // the old model but possibly not true in the new model if another context has 2138 // the old model but possibly not true in the new model if another context has
2485 // deleted the resource. 2139 // deleted the resource.
2486 2140
2487 void GLES2Implementation::BindBufferHelper( 2141 void GLES2Implementation::BindBufferHelper(
2488 GLenum target, GLuint buffer) { 2142 GLenum target, GLuint buffer) {
2489 // TODO(gman): See note #1 above. 2143 // TODO(gman): See note #1 above.
2490 switch (target) { 2144 switch (target) {
2491 case GL_ARRAY_BUFFER: 2145 case GL_ARRAY_BUFFER:
2492 bound_array_buffer_id_ = buffer; 2146 bound_array_buffer_id_ = buffer;
2493 break; 2147 break;
2494 case GL_ELEMENT_ARRAY_BUFFER: 2148 case GL_ELEMENT_ARRAY_BUFFER:
2495 bound_element_array_buffer_id_ = buffer; 2149 vertex_array_object_manager_->BindElementArray(buffer);
2496 break; 2150 break;
2497 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: 2151 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM:
2498 bound_pixel_unpack_transfer_buffer_id_ = buffer; 2152 bound_pixel_unpack_transfer_buffer_id_ = buffer;
2499 break; 2153 break;
2500 default: 2154 default:
2501 break; 2155 break;
2502 } 2156 }
2503 // TODO(gman): There's a bug here. If the target is invalid the ID will not be 2157 // TODO(gman): There's a bug here. If the target is invalid the ID will not be
2504 // used even though it's marked it as used here. 2158 // used even though it's marked it as used here.
2505 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); 2159 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2548 default: 2202 default:
2549 break; 2203 break;
2550 } 2204 }
2551 // TODO(gman): There's a bug here. If the target is invalid the ID will not be 2205 // TODO(gman): There's a bug here. If the target is invalid the ID will not be
2552 // used. even though it's marked it as used here. 2206 // used. even though it's marked it as used here.
2553 GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind(texture); 2207 GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind(texture);
2554 } 2208 }
2555 2209
2556 void GLES2Implementation::BindVertexArrayHelper(GLuint array) { 2210 void GLES2Implementation::BindVertexArrayHelper(GLuint array) {
2557 // TODO(gman): See note #1 above. 2211 // TODO(gman): See note #1 above.
2558 bound_vertex_array_id_ = array; 2212 bool changed = false;
2559 2213 if (!vertex_array_object_manager_->BindVertexArray(array, &changed)) {
2560 GetIdHandler(id_namespaces::kVertexArrays)->MarkAsUsedForBind(array); 2214 SetGLError(
2215 GL_INVALID_OPERATION, "glBindVertexArrayOES",
2216 "id was not generated with glGenVertexArrayOES");
2217 }
2561 } 2218 }
2562 2219
2563 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
2564 bool GLES2Implementation::IsBufferReservedId(GLuint id) { 2220 bool GLES2Implementation::IsBufferReservedId(GLuint id) {
2565 for (size_t ii = 0; ii < arraysize(reserved_ids_); ++ii) { 2221 return vertex_array_object_manager_->IsReservedId(id);
2566 if (id == reserved_ids_[ii]) {
2567 return true;
2568 }
2569 }
2570 return false;
2571 } 2222 }
2572 #else
2573 bool GLES2Implementation::IsBufferReservedId(GLuint /* id */) {
2574 return false;
2575 }
2576 #endif
2577 2223
2578 void GLES2Implementation::DeleteBuffersHelper( 2224 void GLES2Implementation::DeleteBuffersHelper(
2579 GLsizei n, const GLuint* buffers) { 2225 GLsizei n, const GLuint* buffers) {
2580 if (!GetIdHandler(id_namespaces::kBuffers)->FreeIds( 2226 if (!GetIdHandler(id_namespaces::kBuffers)->FreeIds(
2581 this, n, buffers, &GLES2Implementation::DeleteBuffersStub)) { 2227 this, n, buffers, &GLES2Implementation::DeleteBuffersStub)) {
2582 SetGLError( 2228 SetGLError(
2583 GL_INVALID_VALUE, 2229 GL_INVALID_VALUE,
2584 "glDeleteBuffers", "id not created by this context."); 2230 "glDeleteBuffers", "id not created by this context.");
2585 return; 2231 return;
2586 } 2232 }
2587 for (GLsizei ii = 0; ii < n; ++ii) { 2233 for (GLsizei ii = 0; ii < n; ++ii) {
2588 if (buffers[ii] == bound_array_buffer_id_) { 2234 if (buffers[ii] == bound_array_buffer_id_) {
2589 bound_array_buffer_id_ = 0; 2235 bound_array_buffer_id_ = 0;
2590 } 2236 }
2591 if (buffers[ii] == bound_element_array_buffer_id_) { 2237 vertex_array_object_manager_->UnbindBuffer(buffers[ii]);
2592 bound_element_array_buffer_id_ = 0;
2593 }
2594 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) {
2595 bound_pixel_unpack_transfer_buffer_id_ = 0;
2596 }
2597
2598 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); 2238 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]);
2599 if (buffer) { 2239 if (buffer) {
2600 // Free buffer memory, pending the passage of a token. 2240 // Free buffer memory, pending the passage of a token.
2601 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); 2241 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken());
2602 // Remove buffer. 2242 // Remove buffer.
2603 buffer_tracker_->RemoveBuffer(buffers[ii]); 2243 buffer_tracker_->RemoveBuffer(buffers[ii]);
2604 } 2244 }
2245 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) {
2246 bound_pixel_unpack_transfer_buffer_id_ = 0;
2247 }
2605 } 2248 }
2606 } 2249 }
2607 2250
2608 void GLES2Implementation::DeleteBuffersStub( 2251 void GLES2Implementation::DeleteBuffersStub(
2609 GLsizei n, const GLuint* buffers) { 2252 GLsizei n, const GLuint* buffers) {
2610 helper_->DeleteBuffersImmediate(n, buffers); 2253 helper_->DeleteBuffersImmediate(n, buffers);
2611 } 2254 }
2612 2255
2613 2256
2614 void GLES2Implementation::DeleteFramebuffersHelper( 2257 void GLES2Implementation::DeleteFramebuffersHelper(
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2672 } 2315 }
2673 if (textures[ii] == unit.bound_texture_cube_map) { 2316 if (textures[ii] == unit.bound_texture_cube_map) {
2674 unit.bound_texture_cube_map = 0; 2317 unit.bound_texture_cube_map = 0;
2675 } 2318 }
2676 } 2319 }
2677 } 2320 }
2678 } 2321 }
2679 2322
2680 void GLES2Implementation::DeleteVertexArraysOESHelper( 2323 void GLES2Implementation::DeleteVertexArraysOESHelper(
2681 GLsizei n, const GLuint* arrays) { 2324 GLsizei n, const GLuint* arrays) {
2325 vertex_array_object_manager_->DeleteVertexArrays(n, arrays);
2682 if (!GetIdHandler(id_namespaces::kVertexArrays)->FreeIds( 2326 if (!GetIdHandler(id_namespaces::kVertexArrays)->FreeIds(
2683 this, n, arrays, &GLES2Implementation::DeleteVertexArraysOESStub)) { 2327 this, n, arrays, &GLES2Implementation::DeleteVertexArraysOESStub)) {
2684 SetGLError( 2328 SetGLError(
2685 GL_INVALID_VALUE, 2329 GL_INVALID_VALUE,
2686 "glDeleteVertexArraysOES", "id not created by this context."); 2330 "glDeleteVertexArraysOES", "id not created by this context.");
2687 return; 2331 return;
2688 } 2332 }
2689 for (GLsizei ii = 0; ii < n; ++ii) {
2690 if (arrays[ii] == bound_vertex_array_id_) {
2691 bound_vertex_array_id_ = 0;
2692 }
2693 }
2694 } 2333 }
2695 2334
2696 void GLES2Implementation::DeleteVertexArraysOESStub( 2335 void GLES2Implementation::DeleteVertexArraysOESStub(
2697 GLsizei n, const GLuint* arrays) { 2336 GLsizei n, const GLuint* arrays) {
2698 helper_->DeleteVertexArraysOESImmediate(n, arrays); 2337 helper_->DeleteVertexArraysOESImmediate(n, arrays);
2699 } 2338 }
2700 2339
2701 void GLES2Implementation::DeleteTexturesStub( 2340 void GLES2Implementation::DeleteTexturesStub(
2702 GLsizei n, const GLuint* textures) { 2341 GLsizei n, const GLuint* textures) {
2703 helper_->DeleteTexturesImmediate(n, textures); 2342 helper_->DeleteTexturesImmediate(n, textures);
2704 } 2343 }
2705 2344
2706 void GLES2Implementation::DisableVertexAttribArray(GLuint index) { 2345 void GLES2Implementation::DisableVertexAttribArray(GLuint index) {
2707 GPU_CLIENT_SINGLE_THREAD_CHECK(); 2346 GPU_CLIENT_SINGLE_THREAD_CHECK();
2708 GPU_CLIENT_LOG( 2347 GPU_CLIENT_LOG(
2709 "[" << GetLogPrefix() << "] glDisableVertexAttribArray(" << index << ")"); 2348 "[" << GetLogPrefix() << "] glDisableVertexAttribArray(" << index << ")");
2710 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 2349 vertex_array_object_manager_->SetAttribEnable(index, false);
2711 client_side_buffer_helper_->SetAttribEnable(index, false);
2712 #endif
2713 helper_->DisableVertexAttribArray(index); 2350 helper_->DisableVertexAttribArray(index);
2714 } 2351 }
2715 2352
2716 void GLES2Implementation::EnableVertexAttribArray(GLuint index) { 2353 void GLES2Implementation::EnableVertexAttribArray(GLuint index) {
2717 GPU_CLIENT_SINGLE_THREAD_CHECK(); 2354 GPU_CLIENT_SINGLE_THREAD_CHECK();
2718 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableVertexAttribArray(" 2355 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableVertexAttribArray("
2719 << index << ")"); 2356 << index << ")");
2720 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 2357 vertex_array_object_manager_->SetAttribEnable(index, true);
2721 client_side_buffer_helper_->SetAttribEnable(index, true);
2722 #endif
2723 helper_->EnableVertexAttribArray(index); 2358 helper_->EnableVertexAttribArray(index);
2724 } 2359 }
2725 2360
2726 void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) { 2361 void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) {
2727 GPU_CLIENT_SINGLE_THREAD_CHECK(); 2362 GPU_CLIENT_SINGLE_THREAD_CHECK();
2728 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawArrays(" 2363 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawArrays("
2729 << GLES2Util::GetStringDrawMode(mode) << ", " 2364 << GLES2Util::GetStringDrawMode(mode) << ", "
2730 << first << ", " << count << ")"); 2365 << first << ", " << count << ")");
2731 if (count < 0) { 2366 if (count < 0) {
2732 SetGLError(GL_INVALID_VALUE, "glDrawArrays", "count < 0"); 2367 SetGLError(GL_INVALID_VALUE, "glDrawArrays", "count < 0");
2733 return; 2368 return;
2734 } 2369 }
2735 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 2370 bool simulated = false;
2736 bool have_client_side = 2371 if (!vertex_array_object_manager_->SetupSimulatedClientSideBuffers(
2737 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); 2372 "glDrawArrays", this, helper_, first + count, 0, &simulated)) {
2738 if (have_client_side) { 2373 return;
2739 client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
2740 this, helper_, first + count, 0);
2741 } 2374 }
2742 #endif
2743 helper_->DrawArrays(mode, first, count); 2375 helper_->DrawArrays(mode, first, count);
2744 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 2376 RestoreArrayBuffer(simulated);
2745 if (have_client_side) {
2746 // Restore the user's current binding.
2747 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
2748 }
2749 #endif
2750 } 2377 }
2751 2378
2752 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
2753 bool GLES2Implementation::GetVertexAttribHelper(
2754 GLuint index, GLenum pname, uint32* param) {
2755 const ClientSideBufferHelper::VertexAttribInfo* info =
2756 client_side_buffer_helper_->GetAttribInfo(index);
2757 if (!info) {
2758 return false;
2759 }
2760
2761 switch (pname) {
2762 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2763 *param = info->buffer_id();
2764 break;
2765 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2766 *param = info->enabled();
2767 break;
2768 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2769 *param = info->size();
2770 break;
2771 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2772 *param = info->stride();
2773 break;
2774 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2775 *param = info->type();
2776 break;
2777 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2778 *param = info->normalized();
2779 break;
2780 case GL_CURRENT_VERTEX_ATTRIB:
2781 return false; // pass through to service side.
2782 default:
2783 SetGLErrorInvalidEnum("glGetVertexAttrib", pname, "pname");
2784 break;
2785 }
2786 return true;
2787 }
2788 #endif // GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
2789
2790 void GLES2Implementation::GetVertexAttribfv( 2379 void GLES2Implementation::GetVertexAttribfv(
2791 GLuint index, GLenum pname, GLfloat* params) { 2380 GLuint index, GLenum pname, GLfloat* params) {
2792 GPU_CLIENT_SINGLE_THREAD_CHECK(); 2381 GPU_CLIENT_SINGLE_THREAD_CHECK();
2793 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribfv(" 2382 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribfv("
2794 << index << ", " 2383 << index << ", "
2795 << GLES2Util::GetStringVertexAttribute(pname) << ", " 2384 << GLES2Util::GetStringVertexAttribute(pname) << ", "
2796 << static_cast<const void*>(params) << ")"); 2385 << static_cast<const void*>(params) << ")");
2797 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
2798 uint32 value = 0; 2386 uint32 value = 0;
2799 if (GetVertexAttribHelper(index, pname, &value)) { 2387 if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) {
2800 *params = static_cast<float>(value); 2388 *params = static_cast<float>(value);
2801 return; 2389 return;
2802 } 2390 }
2803 #endif
2804 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv"); 2391 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv");
2805 typedef GetVertexAttribfv::Result Result; 2392 typedef GetVertexAttribfv::Result Result;
2806 Result* result = GetResultAs<Result*>(); 2393 Result* result = GetResultAs<Result*>();
2807 if (!result) { 2394 if (!result) {
2808 return; 2395 return;
2809 } 2396 }
2810 result->SetNumResults(0); 2397 result->SetNumResults(0);
2811 helper_->GetVertexAttribfv( 2398 helper_->GetVertexAttribfv(
2812 index, pname, GetResultShmId(), GetResultShmOffset()); 2399 index, pname, GetResultShmId(), GetResultShmOffset());
2813 WaitForCmd(); 2400 WaitForCmd();
2814 result->CopyResult(params); 2401 result->CopyResult(params);
2815 GPU_CLIENT_LOG_CODE_BLOCK({ 2402 GPU_CLIENT_LOG_CODE_BLOCK({
2816 for (int32 i = 0; i < result->GetNumResults(); ++i) { 2403 for (int32 i = 0; i < result->GetNumResults(); ++i) {
2817 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); 2404 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
2818 } 2405 }
2819 }); 2406 });
2820 } 2407 }
2821 2408
2822 void GLES2Implementation::GetVertexAttribiv( 2409 void GLES2Implementation::GetVertexAttribiv(
2823 GLuint index, GLenum pname, GLint* params) { 2410 GLuint index, GLenum pname, GLint* params) {
2824 GPU_CLIENT_SINGLE_THREAD_CHECK(); 2411 GPU_CLIENT_SINGLE_THREAD_CHECK();
2825 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribiv(" 2412 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribiv("
2826 << index << ", " 2413 << index << ", "
2827 << GLES2Util::GetStringVertexAttribute(pname) << ", " 2414 << GLES2Util::GetStringVertexAttribute(pname) << ", "
2828 << static_cast<const void*>(params) << ")"); 2415 << static_cast<const void*>(params) << ")");
2829 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
2830 uint32 value = 0; 2416 uint32 value = 0;
2831 if (GetVertexAttribHelper(index, pname, &value)) { 2417 if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) {
2832 *params = value; 2418 *params = value;
2833 return; 2419 return;
2834 } 2420 }
2835 #endif
2836 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv"); 2421 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv");
2837 typedef GetVertexAttribiv::Result Result; 2422 typedef GetVertexAttribiv::Result Result;
2838 Result* result = GetResultAs<Result*>(); 2423 Result* result = GetResultAs<Result*>();
2839 if (!result) { 2424 if (!result) {
2840 return; 2425 return;
2841 } 2426 }
2842 result->SetNumResults(0); 2427 result->SetNumResults(0);
2843 helper_->GetVertexAttribiv( 2428 helper_->GetVertexAttribiv(
2844 index, pname, GetResultShmId(), GetResultShmOffset()); 2429 index, pname, GetResultShmId(), GetResultShmOffset());
2845 WaitForCmd(); 2430 WaitForCmd();
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
3407 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "count < 0"); 2992 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "count < 0");
3408 return; 2993 return;
3409 } 2994 }
3410 if (primcount < 0) { 2995 if (primcount < 0) {
3411 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "primcount < 0"); 2996 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "primcount < 0");
3412 return; 2997 return;
3413 } 2998 }
3414 if (primcount == 0) { 2999 if (primcount == 0) {
3415 return; 3000 return;
3416 } 3001 }
3417 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 3002 bool simulated = false;
3418 bool have_client_side = 3003 if (!vertex_array_object_manager_->SetupSimulatedClientSideBuffers(
3419 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); 3004 "glDrawArraysInstancedANGLE", this, helper_, first + count, primcount,
3420 if (have_client_side) { 3005 &simulated)) {
3421 client_side_buffer_helper_->SetupSimulatedClientSideBuffers( 3006 return;
3422 this, helper_, first + count, primcount);
3423 } 3007 }
3424 #endif
3425 helper_->DrawArraysInstancedANGLE(mode, first, count, primcount); 3008 helper_->DrawArraysInstancedANGLE(mode, first, count, primcount);
3426 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 3009 RestoreArrayBuffer(simulated);
3427 if (have_client_side) {
3428 // Restore the user's current binding.
3429 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
3430 }
3431 #endif
3432 } 3010 }
3433 3011
3434 void GLES2Implementation::DrawElementsInstancedANGLE( 3012 void GLES2Implementation::DrawElementsInstancedANGLE(
3435 GLenum mode, GLsizei count, GLenum type, const void* indices, 3013 GLenum mode, GLsizei count, GLenum type, const void* indices,
3436 GLsizei primcount) { 3014 GLsizei primcount) {
3437 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3015 GPU_CLIENT_SINGLE_THREAD_CHECK();
3438 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElementsInstancedANGLE(" 3016 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElementsInstancedANGLE("
3439 << GLES2Util::GetStringDrawMode(mode) << ", " 3017 << GLES2Util::GetStringDrawMode(mode) << ", "
3440 << count << ", " 3018 << count << ", "
3441 << GLES2Util::GetStringIndexType(type) << ", " 3019 << GLES2Util::GetStringIndexType(type) << ", "
3442 << static_cast<const void*>(indices) << ", " 3020 << static_cast<const void*>(indices) << ", "
3443 << primcount << ")"); 3021 << primcount << ")");
3444 if (count < 0) { 3022 if (count < 0) {
3445 SetGLError(GL_INVALID_VALUE, 3023 SetGLError(GL_INVALID_VALUE,
3446 "glDrawElementsInstancedANGLE", "count less than 0."); 3024 "glDrawElementsInstancedANGLE", "count less than 0.");
3447 return; 3025 return;
3448 } 3026 }
3449 if (count == 0) { 3027 if (count == 0) {
3450 return; 3028 return;
3451 } 3029 }
3452 if (primcount < 0) { 3030 if (primcount < 0) {
3453 SetGLError(GL_INVALID_VALUE, 3031 SetGLError(GL_INVALID_VALUE,
3454 "glDrawElementsInstancedANGLE", "primcount < 0"); 3032 "glDrawElementsInstancedANGLE", "primcount < 0");
3455 return; 3033 return;
3456 } 3034 }
3457 if (primcount == 0) { 3035 if (primcount == 0) {
3458 return; 3036 return;
3459 } 3037 }
3460 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 3038 GLuint offset = 0;
3461 bool have_client_side = 3039 bool simulated = false;
3462 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); 3040 if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers(
3463 GLsizei num_elements = 0; 3041 "glDrawElementsInstancedANGLE", this, helper_, count, type, primcount,
3464 GLuint offset = ToGLuint(indices); 3042 indices, &offset, &simulated)) {
3465 bool success; 3043 return;
3466 if (bound_element_array_buffer_id_ == 0) {
3467 // Index buffer is client side array.
3468 // Copy to buffer, scan for highest index.
3469 success = client_side_buffer_helper_->SetupSimulatedIndexBuffer(
3470 this, helper_, count, type, indices, &num_elements);
3471
3472 if(!success) {
3473 SetGLError(GL_INVALID_OPERATION, "glDrawElementsInstancedANGLE",
3474 "index too large.");
3475 return;
3476 }
3477
3478 offset = 0;
3479 } else {
3480 // Index buffer is GL buffer. Ask the service for the highest vertex
3481 // that will be accessed. Note: It doesn't matter if another context
3482 // changes the contents of any of the buffers. The service will still
3483 // validate the indices. We just need to know how much to copy across.
3484 if (have_client_side) {
3485 num_elements = GetMaxValueInBufferCHROMIUMHelper(
3486 bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1;
3487 }
3488 }
3489 if (have_client_side) {
3490 client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
3491 this, helper_, num_elements, primcount);
3492 } 3044 }
3493 helper_->DrawElementsInstancedANGLE(mode, count, type, offset, primcount); 3045 helper_->DrawElementsInstancedANGLE(mode, count, type, offset, primcount);
3494 if (have_client_side) { 3046 RestoreElementAndArrayBuffers(simulated);
3495 // Restore the user's current binding.
3496 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
3497 }
3498 if (bound_element_array_buffer_id_ == 0) {
3499 // Restore the element array binding.
3500 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3501 }
3502 #else
3503 helper_->DrawElementsInstancedANGLE(
3504 mode, count, type, ToGLuint(indices), primcount);
3505 #endif
3506 } 3047 }
3507 3048
3508 void GLES2Implementation::GenMailboxCHROMIUM( 3049 void GLES2Implementation::GenMailboxCHROMIUM(
3509 GLbyte* mailbox) { 3050 GLbyte* mailbox) {
3510 GPU_CLIENT_SINGLE_THREAD_CHECK(); 3051 GPU_CLIENT_SINGLE_THREAD_CHECK();
3511 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenMailboxCHROMIUM(" 3052 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenMailboxCHROMIUM("
3512 << static_cast<const void*>(mailbox) << ")"); 3053 << static_cast<const void*>(mailbox) << ")");
3513 TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM"); 3054 TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM");
3514 3055
3515 helper_->GenMailboxCHROMIUM(kResultBucketId); 3056 helper_->GenMailboxCHROMIUM(kResultBucketId);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3624 return true; 3165 return true;
3625 } 3166 }
3626 3167
3627 // Include the auto-generated part of this file. We split this because it means 3168 // Include the auto-generated part of this file. We split this because it means
3628 // we can easily edit the non-auto generated parts right here in this file 3169 // we can easily edit the non-auto generated parts right here in this file
3629 // instead of having to edit some template or the code generator. 3170 // instead of having to edit some template or the code generator.
3630 #include "../client/gles2_implementation_impl_autogen.h" 3171 #include "../client/gles2_implementation_impl_autogen.h"
3631 3172
3632 } // namespace gles2 3173 } // namespace gles2
3633 } // namespace gpu 3174 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698