Home | History | Annotate | Download | only in common
      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 defines the GLES2 command buffer commands.
      6 
      7 #ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H_
      8 #define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H_
      9 
     10 
     11 #include <KHR/khrplatform.h>
     12 
     13 #include <stdint.h>
     14 #include <string.h>
     15 
     16 #include "base/atomicops.h"
     17 #include "base/logging.h"
     18 #include "base/macros.h"
     19 #include "gpu/command_buffer/common/bitfield_helpers.h"
     20 #include "gpu/command_buffer/common/cmd_buffer_common.h"
     21 #include "gpu/command_buffer/common/gles2_cmd_ids.h"
     22 
     23 // GL types are forward declared to avoid including the GL headers. The problem
     24 // is determining which GL headers to include from code that is common to the
     25 // client and service sides (GLES2 or one of several GL implementations).
     26 typedef unsigned int GLenum;
     27 typedef unsigned int GLbitfield;
     28 typedef unsigned int GLuint;
     29 typedef int GLint;
     30 typedef int GLsizei;
     31 typedef unsigned char GLboolean;
     32 typedef signed char GLbyte;
     33 typedef short GLshort;
     34 typedef unsigned char GLubyte;
     35 typedef unsigned short GLushort;
     36 typedef unsigned long GLulong;
     37 typedef float GLfloat;
     38 typedef float GLclampf;
     39 typedef double GLdouble;
     40 typedef double GLclampd;
     41 typedef void GLvoid;
     42 typedef khronos_intptr_t GLintptr;
     43 typedef khronos_ssize_t  GLsizeiptr;
     44 
     45 namespace gpu {
     46 namespace gles2 {
     47 
     48 // Command buffer is GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT byte aligned.
     49 #pragma pack(push, GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT)
     50 
     51 namespace id_namespaces {
     52 
     53 // These are used when contexts share resources.
     54 enum IdNamespaces {
     55   kBuffers,
     56   kFramebuffers,
     57   kProgramsAndShaders,
     58   kRenderbuffers,
     59   kTextures,
     60   kQueries,
     61   kVertexArrays,
     62   kNumIdNamespaces
     63 };
     64 
     65 // These numbers must not change
     66 COMPILE_ASSERT(kBuffers == 0, kBuffers_is_not_0);
     67 COMPILE_ASSERT(kFramebuffers == 1, kFramebuffers_is_not_1);
     68 COMPILE_ASSERT(kProgramsAndShaders == 2, kProgramsAndShaders_is_not_2);
     69 COMPILE_ASSERT(kRenderbuffers == 3, kRenderbuffers_is_not_3);
     70 COMPILE_ASSERT(kTextures == 4, kTextures_is_not_4);
     71 
     72 }  // namespace id_namespaces
     73 
     74 // Used for some glGetXXX commands that return a result through a pointer. We
     75 // need to know if the command succeeded or not and the size of the result. If
     76 // the command failed its result size will 0.
     77 template <typename T>
     78 struct SizedResult {
     79   typedef T Type;
     80 
     81   T* GetData() {
     82     return static_cast<T*>(static_cast<void*>(&data));
     83   }
     84 
     85   // Returns the total size in bytes of the SizedResult for a given number of
     86   // results including the size field.
     87   static size_t ComputeSize(size_t num_results) {
     88     return sizeof(T) * num_results + sizeof(uint32_t);  // NOLINT
     89   }
     90 
     91   // Returns the total size in bytes of the SizedResult for a given size of
     92   // results.
     93   static size_t ComputeSizeFromBytes(size_t size_of_result_in_bytes) {
     94     return size_of_result_in_bytes + sizeof(uint32_t);  // NOLINT
     95   }
     96 
     97   // Returns the maximum number of results for a given buffer size.
     98   static uint32_t ComputeMaxResults(size_t size_of_buffer) {
     99     return (size_of_buffer >= sizeof(uint32_t)) ?
    100         ((size_of_buffer - sizeof(uint32_t)) / sizeof(T)) : 0;  // NOLINT
    101   }
    102 
    103   // Set the size for a given number of results.
    104   void SetNumResults(size_t num_results) {
    105     size = sizeof(T) * num_results;  // NOLINT
    106   }
    107 
    108   // Get the number of elements in the result
    109   int32_t GetNumResults() const {
    110     return size / sizeof(T);  // NOLINT
    111   }
    112 
    113   // Copy the result.
    114   void CopyResult(void* dst) const {
    115     memcpy(dst, &data, size);
    116   }
    117 
    118   uint32_t size;  // in bytes.
    119   int32_t data;  // this is just here to get an offset.
    120 };
    121 
    122 COMPILE_ASSERT(sizeof(SizedResult<int8_t>) == 8, SizedResult_size_not_8);
    123 COMPILE_ASSERT(offsetof(SizedResult<int8_t>, size) == 0,
    124                OffsetOf_SizedResult_size_not_0);
    125 COMPILE_ASSERT(offsetof(SizedResult<int8_t>, data) == 4,
    126                OffsetOf_SizedResult_data_not_4);
    127 
    128 // The data for one attrib or uniform from GetProgramInfoCHROMIUM.
    129 struct ProgramInput {
    130   uint32_t type;             // The type (GL_VEC3, GL_MAT3, GL_SAMPLER_2D, etc.
    131   int32_t size;              // The size (how big the array is for uniforms)
    132   uint32_t location_offset;  // offset from ProgramInfoHeader to 'size'
    133                              // locations for uniforms, 1 for attribs.
    134   uint32_t name_offset;      // offset from ProgrmaInfoHeader to start of name.
    135   uint32_t name_length;      // length of the name.
    136 };
    137 
    138 // The format of the bucket filled out by GetProgramInfoCHROMIUM
    139 struct ProgramInfoHeader {
    140   uint32_t link_status;
    141   uint32_t num_attribs;
    142   uint32_t num_uniforms;
    143   // ProgramInput inputs[num_attribs + num_uniforms];
    144 };
    145 
    146 // The format of QuerySync used by EXT_occlusion_query_boolean
    147 struct QuerySync {
    148   void Reset() {
    149     process_count = 0;
    150     result = 0;
    151   }
    152 
    153   base::subtle::Atomic32 process_count;
    154   uint64_t result;
    155 };
    156 
    157 struct AsyncUploadSync {
    158   void Reset() {
    159     base::subtle::Release_Store(&async_upload_token, 0);
    160   }
    161 
    162   void SetAsyncUploadToken(uint32_t token) {
    163     DCHECK_NE(token, 0u);
    164     base::subtle::Release_Store(&async_upload_token, token);
    165   }
    166 
    167   bool HasAsyncUploadTokenPassed(uint32_t token) {
    168     DCHECK_NE(token, 0u);
    169     uint32_t current_token = base::subtle::Acquire_Load(&async_upload_token);
    170     return (current_token - token < 0x80000000);
    171   }
    172 
    173   base::subtle::Atomic32 async_upload_token;
    174 };
    175 
    176 COMPILE_ASSERT(sizeof(ProgramInput) == 20, ProgramInput_size_not_20);
    177 COMPILE_ASSERT(offsetof(ProgramInput, type) == 0,
    178                OffsetOf_ProgramInput_type_not_0);
    179 COMPILE_ASSERT(offsetof(ProgramInput, size) == 4,
    180                OffsetOf_ProgramInput_size_not_4);
    181 COMPILE_ASSERT(offsetof(ProgramInput, location_offset) == 8,
    182                OffsetOf_ProgramInput_location_offset_not_8);
    183 COMPILE_ASSERT(offsetof(ProgramInput, name_offset) == 12,
    184                OffsetOf_ProgramInput_name_offset_not_12);
    185 COMPILE_ASSERT(offsetof(ProgramInput, name_length) == 16,
    186                OffsetOf_ProgramInput_name_length_not_16);
    187 
    188 COMPILE_ASSERT(sizeof(ProgramInfoHeader) == 12, ProgramInfoHeader_size_not_12);
    189 COMPILE_ASSERT(offsetof(ProgramInfoHeader, link_status) == 0,
    190                OffsetOf_ProgramInfoHeader_link_status_not_0);
    191 COMPILE_ASSERT(offsetof(ProgramInfoHeader, num_attribs) == 4,
    192                OffsetOf_ProgramInfoHeader_num_attribs_not_4);
    193 COMPILE_ASSERT(offsetof(ProgramInfoHeader, num_uniforms) == 8,
    194                OffsetOf_ProgramInfoHeader_num_uniforms_not_8);
    195 
    196 namespace cmds {
    197 
    198 #include "../common/gles2_cmd_format_autogen.h"
    199 
    200 // These are hand written commands.
    201 // TODO(gman): Attempt to make these auto-generated.
    202 struct GetAttribLocation {
    203   typedef GetAttribLocation ValueType;
    204   static const CommandId kCmdId = kGetAttribLocation;
    205   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
    206   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    207 
    208   typedef GLint Result;
    209 
    210   static uint32 ComputeSize() {
    211     return static_cast<uint32>(sizeof(ValueType));  // NOLINT
    212   }
    213 
    214   void SetHeader() {
    215     header.SetCmd<ValueType>();
    216   }
    217 
    218   void Init(
    219       GLuint _program, uint32 _name_bucket_id,
    220       uint32 _location_shm_id, uint32 _location_shm_offset) {
    221     SetHeader();
    222     program = _program;
    223     name_bucket_id = _name_bucket_id;
    224     location_shm_id = _location_shm_id;
    225     location_shm_offset = _location_shm_offset;
    226   }
    227 
    228   void* Set(
    229       void* cmd, GLuint _program, uint32 _name_bucket_id,
    230       uint32 _location_shm_id, uint32 _location_shm_offset) {
    231     static_cast<ValueType*>(
    232         cmd)->Init(
    233             _program, _name_bucket_id, _location_shm_id,
    234             _location_shm_offset);
    235     return NextCmdAddress<ValueType>(cmd);
    236   }
    237 
    238   CommandHeader header;
    239   uint32 program;
    240   uint32 name_bucket_id;
    241   uint32 location_shm_id;
    242   uint32 location_shm_offset;
    243 };
    244 
    245 COMPILE_ASSERT(sizeof(GetAttribLocation) == 20,
    246                Sizeof_GetAttribLocation_is_not_24);
    247 COMPILE_ASSERT(offsetof(GetAttribLocation, header) == 0,
    248                OffsetOf_GetAttribLocation_header_not_0);
    249 COMPILE_ASSERT(offsetof(GetAttribLocation, program) == 4,
    250                OffsetOf_GetAttribLocation_program_not_4);
    251 COMPILE_ASSERT(offsetof(GetAttribLocation, name_bucket_id) == 8,
    252                OffsetOf_GetAttribLocation_name_bucket_id_not_8);
    253 COMPILE_ASSERT(offsetof(GetAttribLocation, location_shm_id) == 12,
    254                OffsetOf_GetAttribLocation_location_shm_id_not_12);
    255 COMPILE_ASSERT(offsetof(GetAttribLocation, location_shm_offset) == 16,
    256                OffsetOf_GetAttribLocation_location_shm_offset_not_16);
    257 
    258 struct GetUniformLocation {
    259   typedef GetUniformLocation ValueType;
    260   static const CommandId kCmdId = kGetUniformLocation;
    261   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
    262   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    263 
    264   typedef GLint Result;
    265 
    266   static uint32 ComputeSize() {
    267     return static_cast<uint32>(sizeof(ValueType));  // NOLINT
    268   }
    269 
    270   void SetHeader() {
    271     header.SetCmd<ValueType>();
    272   }
    273 
    274   void Init(
    275       GLuint _program, uint32 _name_bucket_id,
    276       uint32 _location_shm_id, uint32 _location_shm_offset) {
    277     SetHeader();
    278     program = _program;
    279     name_bucket_id = _name_bucket_id;
    280     location_shm_id = _location_shm_id;
    281     location_shm_offset = _location_shm_offset;
    282   }
    283 
    284   void* Set(
    285       void* cmd, GLuint _program, uint32 _name_bucket_id,
    286       uint32 _location_shm_id, uint32 _location_shm_offset) {
    287     static_cast<ValueType*>(
    288         cmd)->Init(
    289             _program, _name_bucket_id, _location_shm_id,
    290             _location_shm_offset);
    291     return NextCmdAddress<ValueType>(cmd);
    292   }
    293 
    294   CommandHeader header;
    295   uint32 program;
    296   uint32 name_bucket_id;
    297   uint32 location_shm_id;
    298   uint32 location_shm_offset;
    299 };
    300 
    301 COMPILE_ASSERT(sizeof(GetUniformLocation) == 20,
    302                Sizeof_GetUniformLocation_is_not_24);
    303 COMPILE_ASSERT(offsetof(GetUniformLocation, header) == 0,
    304                OffsetOf_GetUniformLocation_header_not_0);
    305 COMPILE_ASSERT(offsetof(GetUniformLocation, program) == 4,
    306                OffsetOf_GetUniformLocation_program_not_4);
    307 COMPILE_ASSERT(offsetof(GetUniformLocation, name_bucket_id) == 8,
    308                OffsetOf_GetUniformLocation_name_bucket_id_not_8);
    309 COMPILE_ASSERT(offsetof(GetUniformLocation, location_shm_id) == 12,
    310                OffsetOf_GetUniformLocation_location_shm_id_not_12);
    311 COMPILE_ASSERT(offsetof(GetUniformLocation, location_shm_offset) == 16,
    312                OffsetOf_GetUniformLocation_location_shm_offset_not_16);
    313 
    314 struct GenMailboxCHROMIUM {
    315   typedef GenMailboxCHROMIUM ValueType;
    316   static const CommandId kCmdId = kGenMailboxCHROMIUM;
    317   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
    318   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    319   CommandHeader header;
    320 };
    321 
    322 struct InsertSyncPointCHROMIUM {
    323   typedef InsertSyncPointCHROMIUM ValueType;
    324   static const CommandId kCmdId = kInsertSyncPointCHROMIUM;
    325   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
    326   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    327   CommandHeader header;
    328 };
    329 
    330 struct CreateAndConsumeTextureCHROMIUMImmediate {
    331   typedef CreateAndConsumeTextureCHROMIUMImmediate ValueType;
    332   static const CommandId kCmdId = kCreateAndConsumeTextureCHROMIUMImmediate;
    333   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
    334   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
    335 
    336   static uint32_t ComputeDataSize() {
    337     return static_cast<uint32_t>(sizeof(GLbyte) * 64);  // NOLINT
    338   }
    339 
    340   static uint32_t ComputeSize() {
    341     return static_cast<uint32_t>(sizeof(ValueType) +
    342                                  ComputeDataSize());  // NOLINT
    343   }
    344 
    345   void SetHeader(uint32_t size_in_bytes) {
    346     header.SetCmdByTotalSize<ValueType>(size_in_bytes);
    347   }
    348 
    349   void Init(GLenum _target, uint32_t _client_id, const GLbyte* _mailbox) {
    350     SetHeader(ComputeSize());
    351     target = _target;
    352     client_id = _client_id;
    353     memcpy(ImmediateDataAddress(this), _mailbox, ComputeDataSize());
    354   }
    355 
    356   void* Set(void* cmd,
    357             GLenum _target,
    358             uint32_t _client_id,
    359             const GLbyte* _mailbox) {
    360     static_cast<ValueType*>(cmd)->Init(_target, _client_id, _mailbox);
    361     const uint32_t size = ComputeSize();
    362     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
    363   }
    364 
    365   gpu::CommandHeader header;
    366   uint32_t target;
    367   uint32_t client_id;
    368 };
    369 
    370 COMPILE_ASSERT(sizeof(CreateAndConsumeTextureCHROMIUMImmediate) == 12,
    371                Sizeof_CreateAndConsumeTextureCHROMIUMImmediate_is_not_12);
    372 COMPILE_ASSERT(offsetof(CreateAndConsumeTextureCHROMIUMImmediate, header) == 0,
    373                OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_header_not_0);
    374 COMPILE_ASSERT(offsetof(CreateAndConsumeTextureCHROMIUMImmediate, target) == 4,
    375                OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_target_not_4);
    376 COMPILE_ASSERT(
    377     offsetof(CreateAndConsumeTextureCHROMIUMImmediate, client_id) == 8,
    378     OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_client_id_not_8);
    379 
    380 
    381 #pragma pack(pop)
    382 
    383 }  // namespace cmd
    384 }  // namespace gles2
    385 }  // namespace gpu
    386 
    387 #endif  // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H_
    388