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