OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """code generator for GLES2 command buffers.""" | 6 """code generator for GLES2 command buffers.""" |
7 | 7 |
8 import itertools | 8 import itertools |
9 import os | 9 import os |
10 import os.path | 10 import os.path |
(...skipping 6455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6466 } | 6466 } |
6467 } | 6467 } |
6468 }); | 6468 }); |
6469 """ | 6469 """ |
6470 file.Write(log_code_block % { | 6470 file.Write(log_code_block % { |
6471 'data': data_arg.name, | 6471 'data': data_arg.name, |
6472 'length': length_arg.name if not length_arg == None else '' | 6472 'length': length_arg.name if not length_arg == None else '' |
6473 }) | 6473 }) |
6474 for arg in func.GetOriginalArgs(): | 6474 for arg in func.GetOriginalArgs(): |
6475 arg.WriteClientSideValidationCode(file, func) | 6475 arg.WriteClientSideValidationCode(file, func) |
6476 size_code_block = """ // Compute the total size. | 6476 |
6477 base::CheckedNumeric<size_t> total_size = count; | |
6478 total_size += 1; | |
6479 total_size *= sizeof(GLint); | |
6480 if (!total_size.IsValid()) { | |
6481 SetGLError(GL_INVALID_VALUE, "gl%(func_name)s", "overflow"); | |
6482 return; | |
6483 } | |
6484 size_t header_size = total_size.ValueOrDefault(0); | |
6485 std::vector<GLint> header(count + 1); | |
6486 header[0] = static_cast<GLint>(count); | |
6487 for (GLsizei ii = 0; ii < count; ++ii) { | |
6488 GLint len = 0; | |
6489 if (%(data)s[ii]) {""" | |
6490 if length_arg == None: | |
6491 size_code_block += """ | |
6492 len = static_cast<GLint>(strlen(%(data)s[ii]));""" | |
6493 else: | |
6494 size_code_block += """ | |
6495 len = (%(length)s && %(length)s[ii] >= 0) ? | |
6496 %(length)s[ii] : base::checked_cast<GLint>(strlen(%(data)s[ii]));""" | |
6497 size_code_block += """ | |
6498 } | |
6499 total_size += len; | |
6500 total_size += 1; // NULL at the end of each char array. | |
6501 if (!total_size.IsValid()) { | |
6502 SetGLError(GL_INVALID_VALUE, "gl%(func_name)s", "overflow"); | |
6503 return; | |
6504 } | |
6505 header[ii + 1] = len; | |
6506 } | |
6507 """ | |
6508 file.Write(size_code_block % { | |
6509 'data': data_arg.name, | |
6510 'length': length_arg.name if not length_arg == None else '', | |
6511 'func_name': func.name, | |
6512 }) | |
6513 data_code_block = """ // Pack data into a bucket on the service. | |
6514 helper_->SetBucketSize(kResultBucketId, total_size.ValueOrDefault(0)); | |
6515 size_t offset = 0; | |
6516 for (GLsizei ii = 0; ii <= count; ++ii) { | |
6517 const char* src = (ii == 0) ? reinterpret_cast<const char*>(&header[0]) : | |
6518 %(data)s[ii - 1]; | |
6519 base::CheckedNumeric<size_t> checked_size = (ii == 0) ? header_size : | |
6520 static_cast<size_t>(header[ii]); | |
6521 if (ii > 0) { | |
6522 checked_size += 1; // NULL in the end. | |
6523 } | |
6524 if (!checked_size.IsValid()) { | |
6525 SetGLError(GL_INVALID_VALUE, "gl%(func_name)s", "overflow"); | |
6526 return; | |
6527 } | |
6528 size_t size = checked_size.ValueOrDefault(0); | |
6529 while (size) { | |
6530 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); | |
6531 if (!buffer.valid() || buffer.size() == 0) { | |
6532 SetGLError(GL_OUT_OF_MEMORY, "gl%(func_name)s", "too large"); | |
6533 return; | |
6534 } | |
6535 size_t copy_size = buffer.size(); | |
6536 if (ii > 0 && buffer.size() == size) | |
6537 --copy_size; | |
6538 if (copy_size) | |
6539 memcpy(buffer.address(), src, copy_size); | |
6540 if (copy_size < buffer.size()) { | |
6541 // Append NULL in the end. | |
6542 DCHECK(copy_size + 1 == buffer.size()); | |
6543 char* str = reinterpret_cast<char*>(buffer.address()); | |
6544 str[copy_size] = 0; | |
6545 } | |
6546 helper_->SetBucketData(kResultBucketId, offset, buffer.size(), | |
6547 buffer.shm_id(), buffer.offset()); | |
6548 offset += buffer.size(); | |
6549 src += buffer.size(); | |
6550 size -= buffer.size(); | |
6551 } | |
6552 } | |
6553 DCHECK_EQ(total_size.ValueOrDefault(0), offset); | |
6554 """ | |
6555 file.Write(data_code_block % { | |
6556 'data': data_arg.name, | |
6557 'length': length_arg.name if not length_arg == None else '', | |
6558 'func_name': func.name, | |
6559 }) | |
6560 bucket_args = [] | 6477 bucket_args = [] |
6561 for arg in func.GetOriginalArgs(): | 6478 for arg in func.GetOriginalArgs(): |
6562 if arg.name == 'count' or arg == self.__GetLengthArg(func): | 6479 if arg.name == 'count' or arg == self.__GetLengthArg(func): |
6563 continue | 6480 continue |
6564 if arg == self.__GetDataArg(func): | 6481 if arg == self.__GetDataArg(func): |
6565 bucket_args.append('kResultBucketId') | 6482 bucket_args.append('kResultBucketId') |
6566 else: | 6483 else: |
6567 bucket_args.append(arg.name) | 6484 bucket_args.append(arg.name) |
6568 file.Write(" helper_->%sBucket(%s);\n" % | 6485 code_block = """ |
6569 (func.name, ", ".join(bucket_args))) | 6486 if (!PackStringsToBucket(count, %(data)s, %(length)s, "gl%(func_name)s")) { |
6570 file.Write(" helper_->SetBucketSize(kResultBucketId, 0);"); | 6487 return; |
6571 file.Write(" CheckGLError();\n") | 6488 } |
6572 file.Write("}\n") | 6489 helper_->%(func_name)sBucket(%(bucket_args)s); |
6573 file.Write("\n") | 6490 helper_->SetBucketSize(kResultBucketId, 0); |
6491 CheckGLError(); | |
6492 } | |
6493 | |
6494 """ | |
6495 file.Write(code_block % { | |
6496 'data': data_arg.name, | |
6497 'length': length_arg.name if not length_arg == None else 'NULL', | |
6498 'func_name': func.name, | |
6499 'bucket_args': ', '.join(bucket_args), | |
6500 }) | |
6574 | 6501 |
6575 def WriteGLES2ImplementationUnitTest(self, func, file): | 6502 def WriteGLES2ImplementationUnitTest(self, func, file): |
6576 """Overrriden from TypeHandler.""" | 6503 """Overrriden from TypeHandler.""" |
6577 code = """ | 6504 code = """ |
6578 TEST_F(GLES2ImplementationTest, %(name)s) { | 6505 TEST_F(GLES2ImplementationTest, %(name)s) { |
6579 const uint32 kBucketId = GLES2Implementation::kResultBucketId; | 6506 const uint32 kBucketId = GLES2Implementation::kResultBucketId; |
6580 const char* kString1 = "happy"; | 6507 const char* kString1 = "happy"; |
6581 const char* kString2 = "ending"; | 6508 const char* kString2 = "ending"; |
6582 const size_t kString1Size = ::strlen(kString1) + 1; | 6509 const size_t kString1Size = ::strlen(kString1) + 1; |
6583 const size_t kString2Size = ::strlen(kString2) + 1; | 6510 const size_t kString2Size = ::strlen(kString2) + 1; |
(...skipping 1411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7995 class InputStringArrayBucketArgument(Argument): | 7922 class InputStringArrayBucketArgument(Argument): |
7996 """A string array input argument where the strings are passed in a bucket.""" | 7923 """A string array input argument where the strings are passed in a bucket.""" |
7997 | 7924 |
7998 def __init__(self, name, type): | 7925 def __init__(self, name, type): |
7999 Argument.__init__(self, name + "_bucket_id", "uint32_t") | 7926 Argument.__init__(self, name + "_bucket_id", "uint32_t") |
8000 self._original_name = name | 7927 self._original_name = name |
8001 | 7928 |
8002 def WriteGetCode(self, file): | 7929 def WriteGetCode(self, file): |
8003 """Overridden from Argument.""" | 7930 """Overridden from Argument.""" |
8004 code = """ | 7931 code = """ |
8005 const size_t kMinBucketSize = sizeof(GLint); | |
8006 // Each string has at least |length| in the header and a NUL character. | |
8007 const size_t kMinStringSize = sizeof(GLint) + 1; | |
8008 Bucket* bucket = GetBucket(c.%(name)s); | 7932 Bucket* bucket = GetBucket(c.%(name)s); |
8009 if (!bucket) { | 7933 if (!bucket) { |
8010 return error::kInvalidArguments; | 7934 return error::kInvalidArguments; |
8011 } | 7935 } |
8012 const size_t bucket_size = bucket->size(); | 7936 GLsizei count = 0; |
8013 if (bucket_size < kMinBucketSize) { | 7937 std::vector<char*> strs; |
7938 std::vector<GLint> len; | |
7939 if (!bucket->GetAsStrings(&count, &strs, &len)) { | |
8014 return error::kInvalidArguments; | 7940 return error::kInvalidArguments; |
8015 } | 7941 } |
8016 const char* bucket_data = bucket->GetDataAs<const char*>(0, bucket_size); | 7942 const char** %(original_name)s = |
8017 const GLint* header = reinterpret_cast<const GLint*>(bucket_data); | 7943 strs.size() > 0 ? const_cast<const char**>(&strs[0]) : NULL; |
no sievers
2015/02/06 21:01:38
Can we somehow assert that these are only NULL if
Zhenyao Mo
2015/02/06 21:53:50
This is the same as asserting strs.size() == len.s
| |
8018 GLsizei count = static_cast<GLsizei>(header[0]); | 7944 const GLint* length = |
8019 if (count < 0) { | 7945 len.size() > 0 ? const_cast<const GLint*>(&len[0]) : NULL; |
8020 return error::kInvalidArguments; | 7946 (void)length; |
8021 } | |
8022 const size_t max_count = (bucket_size - kMinBucketSize) / kMinStringSize; | |
8023 if (max_count < static_cast<size_t>(count)) { | |
8024 return error::kInvalidArguments; | |
8025 } | |
8026 const GLint* length = header + 1; | |
8027 scoped_ptr<const char*[]> strs; | |
8028 if (count > 0) | |
8029 strs.reset(new const char*[count]); | |
8030 const char** %(original_name)s = strs.get(); | |
8031 base::CheckedNumeric<size_t> total_size = sizeof(GLint); | |
8032 total_size *= count + 1; // Header size. | |
8033 if (!total_size.IsValid()) | |
8034 return error::kInvalidArguments; | |
8035 for (GLsizei ii = 0; ii < count; ++ii) { | |
8036 %(original_name)s[ii] = bucket_data + total_size.ValueOrDefault(0); | |
8037 total_size += length[ii]; | |
8038 total_size += 1; // NUL char at the end of each char array. | |
8039 if (!total_size.IsValid() || total_size.ValueOrDefault(0) > bucket_size || | |
8040 %(original_name)s[ii][length[ii]] != 0) { | |
8041 return error::kInvalidArguments; | |
8042 } | |
8043 } | |
8044 if (total_size.ValueOrDefault(0) != bucket_size) { | |
8045 return error::kInvalidArguments; | |
8046 } | |
8047 """ | 7947 """ |
8048 file.Write(code % { | 7948 file.Write(code % { |
8049 'name': self.name, | 7949 'name': self.name, |
8050 'original_name': self._original_name, | 7950 'original_name': self._original_name, |
8051 }) | 7951 }) |
8052 | 7952 |
8053 def GetValidArg(self, func): | 7953 def GetValidArg(self, func): |
8054 return "kNameBucketId" | 7954 return "kNameBucketId" |
8055 | 7955 |
8056 def GetValidGLArg(self, func): | 7956 def GetValidGLArg(self, func): |
(...skipping 2074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10131 Format(gen.generated_cpp_filenames) | 10031 Format(gen.generated_cpp_filenames) |
10132 | 10032 |
10133 if gen.errors > 0: | 10033 if gen.errors > 0: |
10134 print "%d errors" % gen.errors | 10034 print "%d errors" % gen.errors |
10135 return 1 | 10035 return 1 |
10136 return 0 | 10036 return 0 |
10137 | 10037 |
10138 | 10038 |
10139 if __name__ == '__main__': | 10039 if __name__ == '__main__': |
10140 sys.exit(main(sys.argv[1:])) | 10040 sys.exit(main(sys.argv[1:])) |
OLD | NEW |