Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / common / gles2_cmd_utils.cc
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
3 // found in the LICENSE file.
4
5 // This file is here so other GLES2 related files can have a common set of
6 // includes where appropriate.
7
8 #include <sstream>
9 #include <GLES2/gl2.h>
10 #include <GLES2/gl2ext.h>
11 #include <GLES2/gl2extchromium.h>
12
13 #include "gpu/command_buffer/common/gles2_cmd_format.h"
14 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
15
16 namespace gpu {
17 namespace gles2 {
18
19 namespace gl_error_bit {
20 enum GLErrorBit {
21   kNoError = 0,
22   kInvalidEnum = (1 << 0),
23   kInvalidValue = (1 << 1),
24   kInvalidOperation = (1 << 2),
25   kOutOfMemory = (1 << 3),
26   kInvalidFrameBufferOperation = (1 << 4),
27   kContextLost = (1 << 5)
28 };
29 }
30
31 int GLES2Util::GLGetNumValuesReturned(int id) const {
32   switch (id) {
33     // -- glGetBooleanv, glGetFloatv, glGetIntergerv
34     case GL_ACTIVE_TEXTURE:
35       return 1;
36     case GL_ALIASED_LINE_WIDTH_RANGE:
37       return 2;
38     case GL_ALIASED_POINT_SIZE_RANGE:
39       return 2;
40     case GL_ALPHA_BITS:
41       return 1;
42     case GL_ARRAY_BUFFER_BINDING:
43       return 1;
44     case GL_BLEND:
45       return 1;
46     case GL_BLEND_COLOR:
47       return 4;
48     case GL_BLEND_DST_ALPHA:
49       return 1;
50     case GL_BLEND_DST_RGB:
51       return 1;
52     case GL_BLEND_EQUATION_ALPHA:
53       return 1;
54     case GL_BLEND_EQUATION_RGB:
55       return 1;
56     case GL_BLEND_SRC_ALPHA:
57       return 1;
58     case GL_BLEND_SRC_RGB:
59       return 1;
60     case GL_BLUE_BITS:
61       return 1;
62     case GL_COLOR_CLEAR_VALUE:
63       return 4;
64     case GL_COLOR_WRITEMASK:
65       return 4;
66     case GL_COMPRESSED_TEXTURE_FORMATS:
67       return num_compressed_texture_formats_;
68     case GL_CULL_FACE:
69       return 1;
70     case GL_CULL_FACE_MODE:
71       return 1;
72     case GL_CURRENT_PROGRAM:
73       return 1;
74     case GL_DEPTH_BITS:
75       return 1;
76     case GL_DEPTH_CLEAR_VALUE:
77       return 1;
78     case GL_DEPTH_FUNC:
79       return 1;
80     case GL_DEPTH_RANGE:
81       return 2;
82     case GL_DEPTH_TEST:
83       return 1;
84     case GL_DEPTH_WRITEMASK:
85       return 1;
86     case GL_DITHER:
87       return 1;
88     case GL_ELEMENT_ARRAY_BUFFER_BINDING:
89       return 1;
90     case GL_FRAMEBUFFER_BINDING:
91       return 1;
92     case GL_FRONT_FACE:
93       return 1;
94     case GL_GENERATE_MIPMAP_HINT:
95       return 1;
96     case GL_GREEN_BITS:
97       return 1;
98     case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
99       return 1;
100     case GL_IMPLEMENTATION_COLOR_READ_TYPE:
101       return 1;
102     case GL_LINE_WIDTH:
103       return 1;
104     case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
105       return 1;
106     case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
107       return 1;
108     case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
109       return 1;
110     case GL_MAX_RENDERBUFFER_SIZE:
111       return 1;
112     case GL_MAX_TEXTURE_IMAGE_UNITS:
113       return 1;
114     case GL_MAX_TEXTURE_SIZE:
115       return 1;
116     case GL_MAX_VARYING_VECTORS:
117       return 1;
118     case GL_MAX_VERTEX_ATTRIBS:
119       return 1;
120     case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
121       return 1;
122     case GL_MAX_VERTEX_UNIFORM_VECTORS:
123       return 1;
124     case GL_MAX_VIEWPORT_DIMS:
125       return 2;
126     case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
127       return 1;
128     case GL_NUM_SHADER_BINARY_FORMATS:
129       return 1;
130     case GL_PACK_ALIGNMENT:
131       return 1;
132     case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
133       return 1;
134     case GL_POLYGON_OFFSET_FACTOR:
135       return 1;
136     case GL_POLYGON_OFFSET_FILL:
137       return 1;
138     case GL_POLYGON_OFFSET_UNITS:
139       return 1;
140     case GL_RED_BITS:
141       return 1;
142     case GL_RENDERBUFFER_BINDING:
143       return 1;
144     case GL_SAMPLE_BUFFERS:
145       return 1;
146     case GL_SAMPLE_COVERAGE_INVERT:
147       return 1;
148     case GL_SAMPLE_COVERAGE_VALUE:
149       return 1;
150     case GL_SAMPLES:
151       return 1;
152     case GL_SCISSOR_BOX:
153       return 4;
154     case GL_SCISSOR_TEST:
155       return 1;
156     case GL_SHADER_BINARY_FORMATS:
157       return num_shader_binary_formats_;
158     case GL_SHADER_COMPILER:
159       return 1;
160     case GL_STENCIL_BACK_FAIL:
161       return 1;
162     case GL_STENCIL_BACK_FUNC:
163       return 1;
164     case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
165       return 1;
166     case GL_STENCIL_BACK_PASS_DEPTH_PASS:
167       return 1;
168     case GL_STENCIL_BACK_REF:
169       return 1;
170     case GL_STENCIL_BACK_VALUE_MASK:
171       return 1;
172     case GL_STENCIL_BACK_WRITEMASK:
173       return 1;
174     case GL_STENCIL_BITS:
175       return 1;
176     case GL_STENCIL_CLEAR_VALUE:
177       return 1;
178     case GL_STENCIL_FAIL:
179       return 1;
180     case GL_STENCIL_FUNC:
181       return 1;
182     case GL_STENCIL_PASS_DEPTH_FAIL:
183       return 1;
184     case GL_STENCIL_PASS_DEPTH_PASS:
185       return 1;
186     case GL_STENCIL_REF:
187       return 1;
188     case GL_STENCIL_TEST:
189       return 1;
190     case GL_STENCIL_VALUE_MASK:
191       return 1;
192     case GL_STENCIL_WRITEMASK:
193       return 1;
194     case GL_SUBPIXEL_BITS:
195       return 1;
196     case GL_TEXTURE_BINDING_2D:
197       return 1;
198     case GL_TEXTURE_BINDING_CUBE_MAP:
199       return 1;
200     case GL_TEXTURE_BINDING_EXTERNAL_OES:
201       return 1;
202     case GL_TEXTURE_BINDING_RECTANGLE_ARB:
203       return 1;
204     case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
205       return 1;
206     case GL_UNPACK_ALIGNMENT:
207       return 1;
208     case GL_VIEWPORT:
209       return 4;
210     // -- glGetBooleanv, glGetFloatv, glGetIntergerv with
211     //    GL_CHROMIUM_framebuffer_multisample
212     case GL_MAX_SAMPLES_EXT:
213       return 1;
214     case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
215       return 1;
216
217     // -- glGetBufferParameteriv
218     case GL_BUFFER_SIZE:
219       return 1;
220     case GL_BUFFER_USAGE:
221       return 1;
222
223     // -- glGetFramebufferAttachmentParameteriv
224     case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
225       return 1;
226     case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
227       return 1;
228     case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
229       return 1;
230     case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
231       return 1;
232     // -- glGetFramebufferAttachmentParameteriv with
233     //    GL_EXT_multisampled_render_to_texture
234     case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
235       return 1;
236     // -- glGetFramebufferAttachmentParameteriv with
237     //    GL_EXT_sRGB
238     case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
239       return 1;
240
241     // -- glGetProgramiv
242     case GL_DELETE_STATUS:
243       return 1;
244     case GL_LINK_STATUS:
245       return 1;
246     case GL_VALIDATE_STATUS:
247       return 1;
248     case GL_INFO_LOG_LENGTH:
249       return 1;
250     case GL_ATTACHED_SHADERS:
251       return 1;
252     case GL_ACTIVE_ATTRIBUTES:
253       return 1;
254     case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
255       return 1;
256     case GL_ACTIVE_UNIFORMS:
257       return 1;
258     case GL_ACTIVE_UNIFORM_MAX_LENGTH:
259       return 1;
260
261
262     // -- glGetRenderbufferAttachmentParameteriv
263     case GL_RENDERBUFFER_WIDTH:
264       return 1;
265     case GL_RENDERBUFFER_HEIGHT:
266       return 1;
267     case GL_RENDERBUFFER_INTERNAL_FORMAT:
268       return 1;
269     case GL_RENDERBUFFER_RED_SIZE:
270       return 1;
271     case GL_RENDERBUFFER_GREEN_SIZE:
272       return 1;
273     case GL_RENDERBUFFER_BLUE_SIZE:
274       return 1;
275     case GL_RENDERBUFFER_ALPHA_SIZE:
276       return 1;
277     case GL_RENDERBUFFER_DEPTH_SIZE:
278       return 1;
279     case GL_RENDERBUFFER_STENCIL_SIZE:
280       return 1;
281     // -- glGetRenderbufferAttachmentParameteriv with
282     //    GL_EXT_multisampled_render_to_texture
283     case GL_RENDERBUFFER_SAMPLES_EXT:
284       return 1;
285
286     // -- glGetShaderiv
287     case GL_SHADER_TYPE:
288       return 1;
289     // Already defined under glGetFramebufferAttachemntParameteriv.
290     // case GL_DELETE_STATUS:
291     //   return 1;
292     case GL_COMPILE_STATUS:
293       return 1;
294     // Already defined under glGetFramebufferAttachemntParameteriv.
295     // case GL_INFO_LOG_LENGTH:
296     //   return 1;
297     case GL_SHADER_SOURCE_LENGTH:
298       return 1;
299     case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
300       return 1;
301
302     // -- glGetTexParameterfv, glGetTexParameteriv
303     case GL_TEXTURE_MAG_FILTER:
304       return 1;
305     case GL_TEXTURE_MIN_FILTER:
306       return 1;
307     case GL_TEXTURE_WRAP_S:
308       return 1;
309     case GL_TEXTURE_WRAP_T:
310       return 1;
311     case GL_TEXTURE_MAX_ANISOTROPY_EXT:
312       return 1;
313
314     // -- glGetVertexAttribfv, glGetVertexAttribiv
315     case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
316       return 1;
317     case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
318       return 1;
319     case GL_VERTEX_ATTRIB_ARRAY_SIZE:
320       return 1;
321     case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
322       return 1;
323     case GL_VERTEX_ATTRIB_ARRAY_TYPE:
324       return 1;
325     case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
326       return 1;
327     case GL_CURRENT_VERTEX_ATTRIB:
328       return 4;
329
330     // -- glHint with GL_OES_standard_derivatives
331     case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
332       return 1;
333
334     // Chromium internal bind_generates_resource query
335     case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
336       return 1;
337
338     // bad enum
339     default:
340       return 0;
341   }
342 }
343
344 namespace {
345
346 // Return the number of elements per group of a specified format.
347 int ElementsPerGroup(int format, int type) {
348   switch (type) {
349     case GL_UNSIGNED_SHORT_5_6_5:
350     case GL_UNSIGNED_SHORT_4_4_4_4:
351     case GL_UNSIGNED_SHORT_5_5_5_1:
352     case GL_UNSIGNED_INT_24_8_OES:
353        return 1;
354     default:
355        break;
356     }
357
358     switch (format) {
359     case GL_RGB:
360     case GL_SRGB_EXT:
361        return 3;
362     case GL_LUMINANCE_ALPHA:
363        return 2;
364     case GL_RGBA:
365     case GL_BGRA_EXT:
366     case GL_SRGB_ALPHA_EXT:
367        return 4;
368     case GL_ALPHA:
369     case GL_LUMINANCE:
370     case GL_DEPTH_COMPONENT:
371     case GL_DEPTH_COMPONENT24_OES:
372     case GL_DEPTH_COMPONENT32_OES:
373     case GL_DEPTH_COMPONENT16:
374     case GL_DEPTH24_STENCIL8_OES:
375     case GL_DEPTH_STENCIL_OES:
376        return 1;
377     default:
378        return 0;
379   }
380 }
381
382 // Return the number of bytes per element, based on the element type.
383 int BytesPerElement(int type) {
384   switch (type) {
385     case GL_FLOAT:
386     case GL_UNSIGNED_INT_24_8_OES:
387     case GL_UNSIGNED_INT:
388       return 4;
389     case GL_HALF_FLOAT_OES:
390     case GL_UNSIGNED_SHORT:
391     case GL_SHORT:
392     case GL_UNSIGNED_SHORT_5_6_5:
393     case GL_UNSIGNED_SHORT_4_4_4_4:
394     case GL_UNSIGNED_SHORT_5_5_5_1:
395        return 2;
396     case GL_UNSIGNED_BYTE:
397     case GL_BYTE:
398        return 1;
399     default:
400        return 0;
401   }
402 }
403
404 }  // anonymous namespace
405
406 uint32 GLES2Util::ComputeImageGroupSize(int format, int type) {
407   return BytesPerElement(type) * ElementsPerGroup(format, type);
408 }
409
410 bool GLES2Util::ComputeImagePaddedRowSize(
411         int width, int format, int type, int unpack_alignment,
412         uint32* padded_row_size) {
413   uint32 bytes_per_group = ComputeImageGroupSize(format, type);
414   uint32 unpadded_row_size;
415   if (!SafeMultiplyUint32(width, bytes_per_group, &unpadded_row_size)) {
416     return false;
417   }
418   uint32 temp;
419   if (!SafeAddUint32(unpadded_row_size, unpack_alignment - 1, &temp)) {
420       return false;
421   }
422   *padded_row_size = (temp / unpack_alignment) * unpack_alignment;
423   return true;
424 }
425
426 // Returns the amount of data glTexImage2D or glTexSubImage2D will access.
427 bool GLES2Util::ComputeImageDataSizes(
428     int width, int height, int format, int type, int unpack_alignment,
429     uint32* size, uint32* ret_unpadded_row_size, uint32* ret_padded_row_size) {
430   uint32 bytes_per_group = ComputeImageGroupSize(format, type);
431   uint32 row_size;
432   if (!SafeMultiplyUint32(width, bytes_per_group, &row_size)) {
433     return false;
434   }
435   if (height > 1) {
436     uint32 temp;
437     if (!SafeAddUint32(row_size, unpack_alignment - 1, &temp)) {
438       return false;
439     }
440     uint32 padded_row_size = (temp / unpack_alignment) * unpack_alignment;
441     uint32 size_of_all_but_last_row;
442     if (!SafeMultiplyUint32((height - 1), padded_row_size,
443                             &size_of_all_but_last_row)) {
444       return false;
445     }
446     if (!SafeAddUint32(size_of_all_but_last_row, row_size, size)) {
447       return false;
448     }
449     if (ret_padded_row_size) {
450       *ret_padded_row_size = padded_row_size;
451     }
452   } else {
453     if (!SafeMultiplyUint32(height, row_size, size)) {
454       return false;
455     }
456     if (ret_padded_row_size) {
457       *ret_padded_row_size = row_size;
458     }
459   }
460   if (ret_unpadded_row_size) {
461     *ret_unpadded_row_size = row_size;
462   }
463
464   return true;
465 }
466
467 size_t GLES2Util::RenderbufferBytesPerPixel(int format) {
468   switch (format) {
469     case GL_STENCIL_INDEX8:
470       return 1;
471     case GL_RGBA4:
472     case GL_RGB565:
473     case GL_RGB5_A1:
474     case GL_DEPTH_COMPONENT16:
475       return 2;
476     case GL_RGB:
477     case GL_RGBA:
478     case GL_DEPTH24_STENCIL8_OES:
479     case GL_RGB8_OES:
480     case GL_RGBA8_OES:
481     case GL_DEPTH_COMPONENT24_OES:
482       return 4;
483     default:
484       return 0;
485   }
486 }
487
488 uint32 GLES2Util::GetGLDataTypeSizeForUniforms(int type) {
489   switch (type) {
490     case GL_FLOAT:
491       return sizeof(GLfloat);              // NOLINT
492     case GL_FLOAT_VEC2:
493       return sizeof(GLfloat) * 2;          // NOLINT
494     case GL_FLOAT_VEC3:
495       return sizeof(GLfloat) * 3;          // NOLINT
496     case GL_FLOAT_VEC4:
497       return sizeof(GLfloat) * 4;          // NOLINT
498     case GL_INT:
499       return sizeof(GLint);                // NOLINT
500     case GL_INT_VEC2:
501       return sizeof(GLint) * 2;            // NOLINT
502     case GL_INT_VEC3:
503       return sizeof(GLint) * 3;            // NOLINT
504     case GL_INT_VEC4:
505       return sizeof(GLint) * 4;            // NOLINT
506     case GL_BOOL:
507       return sizeof(GLint);                // NOLINT
508     case GL_BOOL_VEC2:
509       return sizeof(GLint) * 2;            // NOLINT
510     case GL_BOOL_VEC3:
511       return sizeof(GLint) * 3;            // NOLINT
512     case GL_BOOL_VEC4:
513       return sizeof(GLint) * 4;            // NOLINT
514     case GL_FLOAT_MAT2:
515       return sizeof(GLfloat) * 2 * 2;      // NOLINT
516     case GL_FLOAT_MAT3:
517       return sizeof(GLfloat) * 3 * 3;      // NOLINT
518     case GL_FLOAT_MAT4:
519       return sizeof(GLfloat) * 4 * 4;      // NOLINT
520     case GL_SAMPLER_2D:
521       return sizeof(GLint);                // NOLINT
522     case GL_SAMPLER_2D_RECT_ARB:
523       return sizeof(GLint);                // NOLINT
524     case GL_SAMPLER_CUBE:
525       return sizeof(GLint);                // NOLINT
526     case GL_SAMPLER_EXTERNAL_OES:
527       return sizeof(GLint);                // NOLINT
528     default:
529       return 0;
530   }
531 }
532
533 size_t GLES2Util::GetGLTypeSizeForTexturesAndBuffers(uint32 type) {
534   switch (type) {
535     case GL_BYTE:
536       return sizeof(GLbyte);  // NOLINT
537     case GL_UNSIGNED_BYTE:
538       return sizeof(GLubyte);  // NOLINT
539     case GL_SHORT:
540       return sizeof(GLshort);  // NOLINT
541     case GL_UNSIGNED_SHORT:
542       return sizeof(GLushort);  // NOLINT
543     case GL_INT:
544       return sizeof(GLint);  // NOLINT
545     case GL_UNSIGNED_INT:
546       return sizeof(GLuint);  // NOLINT
547     case GL_FLOAT:
548       return sizeof(GLfloat);  // NOLINT
549     case GL_FIXED:
550       return sizeof(GLfixed);  // NOLINT
551     default:
552       return 0;
553   }
554 }
555
556 uint32 GLES2Util::GLErrorToErrorBit(uint32 error) {
557   switch (error) {
558     case GL_INVALID_ENUM:
559       return gl_error_bit::kInvalidEnum;
560     case GL_INVALID_VALUE:
561       return gl_error_bit::kInvalidValue;
562     case GL_INVALID_OPERATION:
563       return gl_error_bit::kInvalidOperation;
564     case GL_OUT_OF_MEMORY:
565       return gl_error_bit::kOutOfMemory;
566     case GL_INVALID_FRAMEBUFFER_OPERATION:
567       return gl_error_bit::kInvalidFrameBufferOperation;
568     case GL_CONTEXT_LOST_KHR:
569       return gl_error_bit::kContextLost;
570     default:
571       NOTREACHED();
572       return gl_error_bit::kNoError;
573   }
574 }
575
576 uint32 GLES2Util::GLErrorBitToGLError(uint32 error_bit) {
577   switch (error_bit) {
578     case gl_error_bit::kInvalidEnum:
579       return GL_INVALID_ENUM;
580     case gl_error_bit::kInvalidValue:
581       return GL_INVALID_VALUE;
582     case gl_error_bit::kInvalidOperation:
583       return GL_INVALID_OPERATION;
584     case gl_error_bit::kOutOfMemory:
585       return GL_OUT_OF_MEMORY;
586     case gl_error_bit::kInvalidFrameBufferOperation:
587       return GL_INVALID_FRAMEBUFFER_OPERATION;
588     case gl_error_bit::kContextLost:
589       return GL_CONTEXT_LOST_KHR;
590     default:
591       NOTREACHED();
592       return GL_NO_ERROR;
593   }
594 }
595
596 uint32 GLES2Util::IndexToGLFaceTarget(int index) {
597   static uint32 faces[] = {
598     GL_TEXTURE_CUBE_MAP_POSITIVE_X,
599     GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
600     GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
601     GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
602     GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
603     GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
604   };
605   return faces[index];
606 }
607
608 size_t GLES2Util::GLTargetToFaceIndex(uint32 target) {
609   switch (target) {
610     case GL_TEXTURE_2D:
611     case GL_TEXTURE_EXTERNAL_OES:
612     case GL_TEXTURE_RECTANGLE_ARB:
613       return 0;
614     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
615       return 0;
616     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
617       return 1;
618     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
619       return 2;
620     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
621       return 3;
622     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
623       return 4;
624     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
625       return 5;
626     default:
627       NOTREACHED();
628       return 0;
629   }
630 }
631
632 uint32 GLES2Util::GetPreferredGLReadPixelsFormat(uint32 internal_format) {
633   switch (internal_format) {
634     case GL_RGB16F_EXT:
635     case GL_RGB32F_EXT:
636       return GL_RGB;
637     case GL_RGBA16F_EXT:
638     case GL_RGBA32F_EXT:
639       return GL_RGBA;
640     default:
641       return GL_RGBA;
642   }
643 }
644
645 uint32 GLES2Util::GetPreferredGLReadPixelsType(
646     uint32 internal_format, uint32 texture_type) {
647   switch (internal_format) {
648     case GL_RGBA32F_EXT:
649     case GL_RGB32F_EXT:
650       return GL_FLOAT;
651     case GL_RGBA16F_EXT:
652     case GL_RGB16F_EXT:
653       return GL_HALF_FLOAT_OES;
654     case GL_RGBA:
655     case GL_RGB:
656       // Unsized internal format, check the type
657       switch (texture_type) {
658         case GL_FLOAT:
659         case GL_HALF_FLOAT_OES:
660           return GL_FLOAT;
661         default:
662           return GL_UNSIGNED_BYTE;
663       }
664     default:
665       return GL_UNSIGNED_BYTE;
666   }
667 }
668
669 uint32 GLES2Util::GetChannelsForFormat(int format) {
670   switch (format) {
671     case GL_ALPHA:
672     case GL_ALPHA16F_EXT:
673     case GL_ALPHA32F_EXT:
674       return kAlpha;
675     case GL_LUMINANCE:
676       return kRGB;
677     case GL_LUMINANCE_ALPHA:
678       return kRGBA;
679     case GL_RGB:
680     case GL_RGB8_OES:
681     case GL_RGB565:
682     case GL_RGB16F_EXT:
683     case GL_RGB32F_EXT:
684     case GL_SRGB_EXT:
685       return kRGB;
686     case GL_BGRA_EXT:
687     case GL_BGRA8_EXT:
688     case GL_RGBA16F_EXT:
689     case GL_RGBA32F_EXT:
690     case GL_RGBA:
691     case GL_RGBA8_OES:
692     case GL_RGBA4:
693     case GL_RGB5_A1:
694     case GL_SRGB_ALPHA_EXT:
695     case GL_SRGB8_ALPHA8_EXT:
696       return kRGBA;
697     case GL_DEPTH_COMPONENT32_OES:
698     case GL_DEPTH_COMPONENT24_OES:
699     case GL_DEPTH_COMPONENT16:
700     case GL_DEPTH_COMPONENT:
701       return kDepth;
702     case GL_STENCIL_INDEX8:
703       return kStencil;
704     case GL_DEPTH_STENCIL_OES:
705     case GL_DEPTH24_STENCIL8_OES:
706       return kDepth | kStencil;
707     default:
708       return 0x0000;
709   }
710 }
711
712 uint32 GLES2Util::GetChannelsNeededForAttachmentType(
713     int type, uint32 max_color_attachments) {
714   switch (type) {
715     case GL_DEPTH_ATTACHMENT:
716       return kDepth;
717     case GL_STENCIL_ATTACHMENT:
718       return kStencil;
719     default:
720       if (type >= GL_COLOR_ATTACHMENT0 &&
721           type < static_cast<int>(
722               GL_COLOR_ATTACHMENT0 + max_color_attachments)) {
723         return kRGBA;
724       }
725       return 0x0000;
726   }
727 }
728
729 std::string GLES2Util::GetStringEnum(uint32 value) {
730   const EnumToString* entry = enum_to_string_table_;
731   const EnumToString* end = entry + enum_to_string_table_len_;
732   for (;entry < end; ++entry) {
733     if (value == entry->value) {
734       return entry->name;
735     }
736   }
737   std::stringstream ss;
738   ss.fill('0');
739   ss.width(value < 0x10000 ? 4 : 8);
740   ss << std::hex << value;
741   return "0x" + ss.str();
742 }
743
744 std::string GLES2Util::GetStringError(uint32 value) {
745   static EnumToString string_table[] = {
746     { GL_NONE, "GL_NONE" },
747   };
748   return GLES2Util::GetQualifiedEnumString(
749       string_table, arraysize(string_table), value);
750 }
751
752 std::string GLES2Util::GetStringBool(uint32 value) {
753   return value ? "GL_TRUE" : "GL_FALSE";
754 }
755
756 std::string GLES2Util::GetQualifiedEnumString(
757     const EnumToString* table, size_t count, uint32 value) {
758   for (const EnumToString* end = table + count; table < end; ++table) {
759     if (table->value == value) {
760       return table->name;
761     }
762   }
763   return GetStringEnum(value);
764 }
765
766 bool GLES2Util::ParseUniformName(
767     const std::string& name,
768     size_t* array_pos,
769     int* element_index,
770     bool* getting_array) {
771   bool getting_array_location = false;
772   size_t open_pos = std::string::npos;
773   int index = 0;
774   if (name[name.size() - 1] == ']') {
775     if (name.size() < 3) {
776       return false;
777     }
778     open_pos = name.find_last_of('[');
779     if (open_pos == std::string::npos ||
780         open_pos >= name.size() - 2) {
781       return false;
782     }
783     size_t last = name.size() - 1;
784     for (size_t pos = open_pos + 1; pos < last; ++pos) {
785       int8 digit = name[pos] - '0';
786       if (digit < 0 || digit > 9) {
787         return false;
788       }
789       index = index * 10 + digit;
790     }
791     getting_array_location = true;
792   }
793   *getting_array = getting_array_location;
794   *element_index = index;
795   *array_pos = open_pos;
796   return true;
797 }
798
799 namespace {
800
801 // WebGraphicsContext3DCommandBufferImpl configuration attributes. Those in
802 // the 16-bit range are the same as used by EGL. Those outside the 16-bit range
803 // are unique to Chromium. Attributes are matched using a closest fit algorithm.
804
805 // From <EGL/egl.h>.
806 const int32 kAlphaSize       = 0x3021;  // EGL_ALPHA_SIZE
807 const int32 kBlueSize        = 0x3022;  // EGL_BLUE_SIZE
808 const int32 kGreenSize       = 0x3023;  // EGL_GREEN_SIZE
809 const int32 kRedSize         = 0x3024;  // EGL_RED_SIZE
810 const int32 kDepthSize       = 0x3025;  // EGL_DEPTH_SIZE
811 const int32 kStencilSize     = 0x3026;  // EGL_STENCIL_SIZE
812 const int32 kSamples         = 0x3031;  // EGL_SAMPLES
813 const int32 kSampleBuffers   = 0x3032;  // EGL_SAMPLE_BUFFERS
814 const int32 kNone            = 0x3038;  // EGL_NONE
815 const int32 kSwapBehavior    = 0x3093;  // EGL_SWAP_BEHAVIOR
816 const int32 kBufferPreserved = 0x3094;  // EGL_BUFFER_PRESERVED
817 const int32 kBufferDestroyed = 0x3095;  // EGL_BUFFER_DESTROYED
818
819 // Chromium only.
820 const int32 kBindGeneratesResource = 0x10000;
821 const int32 kFailIfMajorPerfCaveat = 0x10001;
822 const int32 kLoseContextWhenOutOfMemory = 0x10002;
823
824 }  // namespace
825
826 ContextCreationAttribHelper::ContextCreationAttribHelper()
827     : alpha_size(-1),
828       blue_size(-1),
829       green_size(-1),
830       red_size(-1),
831       depth_size(-1),
832       stencil_size(-1),
833       samples(-1),
834       sample_buffers(-1),
835       buffer_preserved(true),
836       bind_generates_resource(true),
837       fail_if_major_perf_caveat(false),
838       lose_context_when_out_of_memory(false) {}
839
840 void ContextCreationAttribHelper::Serialize(std::vector<int32>* attribs) const {
841   if (alpha_size != -1) {
842     attribs->push_back(kAlphaSize);
843     attribs->push_back(alpha_size);
844   }
845   if (blue_size != -1) {
846     attribs->push_back(kBlueSize);
847     attribs->push_back(blue_size);
848   }
849   if (green_size != -1) {
850     attribs->push_back(kGreenSize);
851     attribs->push_back(green_size);
852   }
853   if (red_size != -1) {
854     attribs->push_back(kRedSize);
855     attribs->push_back(red_size);
856   }
857   if (depth_size != -1) {
858     attribs->push_back(kDepthSize);
859     attribs->push_back(depth_size);
860   }
861   if (stencil_size != -1) {
862     attribs->push_back(kStencilSize);
863     attribs->push_back(stencil_size);
864   }
865   if (samples != -1) {
866     attribs->push_back(kSamples);
867     attribs->push_back(samples);
868   }
869   if (sample_buffers != -1) {
870     attribs->push_back(kSampleBuffers);
871     attribs->push_back(sample_buffers);
872   }
873   attribs->push_back(kSwapBehavior);
874   attribs->push_back(buffer_preserved ? kBufferPreserved : kBufferDestroyed);
875   attribs->push_back(kBindGeneratesResource);
876   attribs->push_back(bind_generates_resource ? 1 : 0);
877   attribs->push_back(kFailIfMajorPerfCaveat);
878   attribs->push_back(fail_if_major_perf_caveat ? 1 : 0);
879   attribs->push_back(kLoseContextWhenOutOfMemory);
880   attribs->push_back(lose_context_when_out_of_memory ? 1 : 0);
881   attribs->push_back(kNone);
882 }
883
884 bool ContextCreationAttribHelper::Parse(const std::vector<int32>& attribs) {
885   for (size_t i = 0; i < attribs.size(); i += 2) {
886     const int32 attrib = attribs[i];
887     if (i + 1 >= attribs.size()) {
888       if (attrib == kNone) {
889         return true;
890       }
891
892       DLOG(ERROR) << "Missing value after context creation attribute: "
893                   << attrib;
894       return false;
895     }
896
897     const int32 value = attribs[i+1];
898     switch (attrib) {
899       case kAlphaSize:
900         alpha_size = value;
901         break;
902       case kBlueSize:
903         blue_size = value;
904         break;
905       case kGreenSize:
906         green_size = value;
907         break;
908       case kRedSize:
909         red_size = value;
910         break;
911       case kDepthSize:
912         depth_size = value;
913         break;
914       case kStencilSize:
915         stencil_size = value;
916         break;
917       case kSamples:
918         samples = value;
919         break;
920       case kSampleBuffers:
921         sample_buffers = value;
922         break;
923       case kSwapBehavior:
924         buffer_preserved = value == kBufferPreserved;
925         break;
926       case kBindGeneratesResource:
927         bind_generates_resource = value != 0;
928         break;
929       case kFailIfMajorPerfCaveat:
930         fail_if_major_perf_caveat = value != 0;
931         break;
932       case kLoseContextWhenOutOfMemory:
933         lose_context_when_out_of_memory = value != 0;
934         break;
935       case kNone:
936         // Terminate list, even if more attributes.
937         return true;
938       default:
939         DLOG(ERROR) << "Invalid context creation attribute: " << attrib;
940         return false;
941     }
942   }
943
944   return true;
945 }
946
947 #include "gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h"
948
949 }  // namespace gles2
950 }  // namespace gpu
951