OLD | NEW |
---|---|
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 "gpu/command_buffer/client/gles2_implementation.h" | 7 #include "gpu/command_buffer/client/gles2_implementation.h" |
8 | 8 |
9 #include <GLES2/gl2.h> | 9 #include <GLES2/gl2.h> |
10 #include <GLES2/gl2ext.h> | 10 #include <GLES2/gl2ext.h> |
11 #include <GLES2/gl2extchromium.h> | 11 #include <GLES2/gl2extchromium.h> |
12 #include <GLES3/gl3.h> | 12 #include <GLES3/gl3.h> |
13 #include <stddef.h> | 13 #include <stddef.h> |
14 #include <stdint.h> | 14 #include <stdint.h> |
15 #include <algorithm> | 15 #include <algorithm> |
16 #include <map> | 16 #include <map> |
17 #include <set> | 17 #include <set> |
18 #include <sstream> | 18 #include <sstream> |
19 #include <string> | 19 #include <string> |
20 #include "base/atomic_sequence_num.h" | 20 #include "base/atomic_sequence_num.h" |
21 #include "base/compiler_specific.h" | 21 #include "base/compiler_specific.h" |
22 #include "base/numerics/safe_math.h" | |
22 #include "base/strings/string_split.h" | 23 #include "base/strings/string_split.h" |
23 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
24 #include "base/sys_info.h" | 25 #include "base/sys_info.h" |
25 #include "base/threading/thread_task_runner_handle.h" | 26 #include "base/threading/thread_task_runner_handle.h" |
26 #include "base/trace_event/memory_allocator_dump.h" | 27 #include "base/trace_event/memory_allocator_dump.h" |
27 #include "base/trace_event/memory_dump_manager.h" | 28 #include "base/trace_event/memory_dump_manager.h" |
28 #include "base/trace_event/process_memory_dump.h" | 29 #include "base/trace_event/process_memory_dump.h" |
29 #include "base/trace_event/trace_event.h" | 30 #include "base/trace_event/trace_event.h" |
30 #include "gpu/command_buffer/client/buffer_tracker.h" | 31 #include "gpu/command_buffer/client/buffer_tracker.h" |
31 #include "gpu/command_buffer/client/gles2_cmd_helper.h" | 32 #include "gpu/command_buffer/client/gles2_cmd_helper.h" |
(...skipping 3008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3040 DCHECK(buffer); | 3041 DCHECK(buffer); |
3041 DCHECK_GE(level, 0); | 3042 DCHECK_GE(level, 0); |
3042 DCHECK_GT(height, 0); | 3043 DCHECK_GT(height, 0); |
3043 DCHECK_GT(width, 0); | 3044 DCHECK_GT(width, 0); |
3044 DCHECK_GE(xoffset, 0); | 3045 DCHECK_GE(xoffset, 0); |
3045 DCHECK_GE(yoffset, 0); | 3046 DCHECK_GE(yoffset, 0); |
3046 | 3047 |
3047 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); | 3048 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); |
3048 // Transfer by rows. | 3049 // Transfer by rows. |
3049 while (height) { | 3050 while (height) { |
3050 unsigned int desired_size = | 3051 base::CheckedNumeric<unsigned int> desired_size = buffer_padded_row_size; |
Zhenyao Mo
2016/09/06 21:52:10
I dig a little further into the code. It seems to
xidachen
2016/09/07 02:09:42
After a closer look, I think you are right. Most c
| |
3051 buffer_padded_row_size * (height - 1) + unpadded_row_size; | 3052 desired_size = desired_size * (height - 1) + unpadded_row_size; |
3052 if (!buffer->valid() || buffer->size() == 0) { | 3053 if (!buffer->valid() || buffer->size() == 0) { |
3053 buffer->Reset(desired_size); | 3054 buffer->Reset(desired_size.ValueOrDefault( |
3055 std::numeric_limits<unsigned int>::max())); | |
3054 if (!buffer->valid()) { | 3056 if (!buffer->valid()) { |
3055 return; | 3057 return; |
3056 } | 3058 } |
3057 } | 3059 } |
3058 | 3060 |
3059 GLint num_rows = ComputeNumRowsThatFitInBuffer( | 3061 GLint num_rows = ComputeNumRowsThatFitInBuffer( |
3060 buffer_padded_row_size, unpadded_row_size, buffer->size(), height); | 3062 buffer_padded_row_size, unpadded_row_size, buffer->size(), height); |
3061 num_rows = std::min(num_rows, height); | 3063 num_rows = std::min(num_rows, height); |
3062 CopyRectToBuffer( | 3064 CopyRectToBuffer( |
3063 source, num_rows, unpadded_row_size, pixels_padded_row_size, | 3065 source, num_rows, unpadded_row_size, pixels_padded_row_size, |
3064 buffer->address(), buffer_padded_row_size); | 3066 buffer->address(), buffer_padded_row_size); |
3065 helper_->TexSubImage2D( | 3067 helper_->TexSubImage2D( |
3066 target, level, xoffset, yoffset, width, num_rows, format, type, | 3068 target, level, xoffset, yoffset, width, num_rows, format, type, |
3067 buffer->shm_id(), buffer->offset(), internal); | 3069 buffer->shm_id(), buffer->offset(), internal); |
3068 buffer->Release(); | 3070 buffer->Release(); |
3069 yoffset += num_rows; | 3071 base::CheckedNumeric<GLint> updated_yoffset = yoffset; |
3070 source += num_rows * pixels_padded_row_size; | 3072 updated_yoffset += num_rows; |
3073 yoffset = updated_yoffset.ValueOrDefault(std::numeric_limits<int>::max()); | |
3074 base::CheckedNumeric<uint32_t> source_offset = pixels_padded_row_size; | |
3075 source_offset *= num_rows; | |
3076 source += source_offset.ValueOrDefault( | |
3077 std::numeric_limits<uint32_t>::max()); | |
3071 height -= num_rows; | 3078 height -= num_rows; |
3072 } | 3079 } |
3073 } | 3080 } |
3074 | 3081 |
3075 void GLES2Implementation::TexSubImage3DImpl(GLenum target, | 3082 void GLES2Implementation::TexSubImage3DImpl(GLenum target, |
3076 GLint level, | 3083 GLint level, |
3077 GLint xoffset, | 3084 GLint xoffset, |
3078 GLint yoffset, | 3085 GLint yoffset, |
3079 GLsizei zoffset, | 3086 GLsizei zoffset, |
3080 GLsizei width, | 3087 GLsizei width, |
3081 GLsizei height, | 3088 GLsizei height, |
3082 GLsizei depth, | 3089 GLsizei depth, |
3083 GLenum format, | 3090 GLenum format, |
3084 GLenum type, | 3091 GLenum type, |
3085 uint32_t unpadded_row_size, | 3092 uint32_t unpadded_row_size, |
3086 const void* pixels, | 3093 const void* pixels, |
3087 uint32_t pixels_padded_row_size, | 3094 uint32_t pixels_padded_row_size, |
3088 GLboolean internal, | 3095 GLboolean internal, |
3089 ScopedTransferBufferPtr* buffer, | 3096 ScopedTransferBufferPtr* buffer, |
3090 uint32_t buffer_padded_row_size) { | 3097 uint32_t buffer_padded_row_size) { |
3091 DCHECK(buffer); | 3098 DCHECK(buffer); |
3092 DCHECK_GE(level, 0); | 3099 DCHECK_GE(level, 0); |
3093 DCHECK_GT(width, 0); | 3100 DCHECK_GT(width, 0); |
3094 DCHECK_GT(height, 0); | 3101 DCHECK_GT(height, 0); |
3095 DCHECK_GT(depth, 0); | 3102 DCHECK_GT(depth, 0); |
3096 DCHECK_GE(xoffset, 0); | 3103 DCHECK_GE(xoffset, 0); |
3097 DCHECK_GE(yoffset, 0); | 3104 DCHECK_GE(yoffset, 0); |
3098 DCHECK_GE(zoffset, 0); | 3105 DCHECK_GE(zoffset, 0); |
3099 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); | 3106 const int8_t* source = reinterpret_cast<const int8_t*>(pixels); |
3100 GLsizei total_rows = height * depth; | 3107 base::CheckedNumeric<GLsizei> checked_total_rows = height; |
3108 checked_total_rows *= depth; | |
3109 GLsizei total_rows = checked_total_rows.ValueOrDefault( | |
3110 std::numeric_limits<int>::max()); | |
3101 GLint row_index = 0, depth_index = 0; | 3111 GLint row_index = 0, depth_index = 0; |
3102 while (total_rows) { | 3112 while (total_rows) { |
3103 // Each time, we either copy one or more images, or copy one or more rows | 3113 // Each time, we either copy one or more images, or copy one or more rows |
3104 // within a single image, depending on the buffer size limit. | 3114 // within a single image, depending on the buffer size limit. |
3105 GLsizei max_rows; | 3115 GLsizei max_rows; |
3106 unsigned int desired_size; | 3116 base::CheckedNumeric<unsigned int> desired_size = buffer_padded_row_size; |
3107 if (row_index > 0) { | 3117 if (row_index > 0) { |
3108 // We are in the middle of an image. Send the remaining of the image. | 3118 // We are in the middle of an image. Send the remaining of the image. |
3109 max_rows = height - row_index; | 3119 max_rows = height - row_index; |
3110 if (total_rows <= height) { | 3120 if (total_rows <= height) { |
3111 // Last image, so last row is unpadded. | 3121 // Last image, so last row is unpadded. |
3112 desired_size = buffer_padded_row_size * (max_rows - 1) + | 3122 desired_size = desired_size * (max_rows - 1) + unpadded_row_size; |
3113 unpadded_row_size; | |
3114 } else { | 3123 } else { |
3115 desired_size = buffer_padded_row_size * max_rows; | 3124 desired_size *= max_rows; |
3116 } | 3125 } |
3117 } else { | 3126 } else { |
3118 // Send all the remaining data if possible. | 3127 // Send all the remaining data if possible. |
3119 max_rows = total_rows; | 3128 max_rows = total_rows; |
3120 desired_size = | 3129 desired_size = desired_size * (max_rows - 1) + unpadded_row_size; |
3121 buffer_padded_row_size * (max_rows - 1) + unpadded_row_size; | |
3122 } | 3130 } |
3123 if (!buffer->valid() || buffer->size() == 0) { | 3131 if (!buffer->valid() || buffer->size() == 0) { |
3124 buffer->Reset(desired_size); | 3132 buffer->Reset(desired_size.ValueOrDefault( |
3133 std::numeric_limits<unsigned int>::max())); | |
3125 if (!buffer->valid()) { | 3134 if (!buffer->valid()) { |
3126 return; | 3135 return; |
3127 } | 3136 } |
3128 } | 3137 } |
3129 GLint num_rows = ComputeNumRowsThatFitInBuffer( | 3138 GLint num_rows = ComputeNumRowsThatFitInBuffer( |
3130 buffer_padded_row_size, unpadded_row_size, buffer->size(), total_rows); | 3139 buffer_padded_row_size, unpadded_row_size, buffer->size(), total_rows); |
3131 num_rows = std::min(num_rows, max_rows); | 3140 num_rows = std::min(num_rows, max_rows); |
3132 GLint num_images = num_rows / height; | 3141 GLint num_images = num_rows / height; |
3133 GLsizei my_height, my_depth; | 3142 GLsizei my_height, my_depth; |
3134 if (num_images > 0) { | 3143 if (num_images > 0) { |
3135 num_rows = num_images * height; | 3144 num_rows = num_images * height; |
3136 my_height = height; | 3145 my_height = height; |
3137 my_depth = num_images; | 3146 my_depth = num_images; |
3138 } else { | 3147 } else { |
3139 my_height = num_rows; | 3148 my_height = num_rows; |
3140 my_depth = 1; | 3149 my_depth = 1; |
3141 } | 3150 } |
3142 | 3151 |
3143 if (num_images > 0) { | 3152 if (num_images > 0) { |
3144 int8_t* buffer_pointer = reinterpret_cast<int8_t*>(buffer->address()); | 3153 int8_t* buffer_pointer = reinterpret_cast<int8_t*>(buffer->address()); |
3145 uint32_t src_height = | 3154 uint32_t src_height = |
3146 unpack_image_height_ > 0 ? unpack_image_height_ : height; | 3155 unpack_image_height_ > 0 ? unpack_image_height_ : height; |
3147 uint32_t image_size_dst = buffer_padded_row_size * height; | 3156 base::CheckedNumeric<uint32_t> checked_image_size_dst |
3148 uint32_t image_size_src = pixels_padded_row_size * src_height; | 3157 = buffer_padded_row_size; |
3158 checked_image_size_dst *= height; | |
3159 uint32_t image_size_dst = checked_image_size_dst.ValueOrDefault( | |
3160 std::numeric_limits<uint32_t>::max()); | |
3161 base::CheckedNumeric<uint32_t> checked_image_size_src | |
3162 = pixels_padded_row_size; | |
3163 checked_image_size_src *= src_height; | |
3164 uint32_t image_size_src = checked_image_size_src.ValueOrDefault( | |
3165 std::numeric_limits<uint32_t>::max()); | |
3149 for (GLint ii = 0; ii < num_images; ++ii) { | 3166 for (GLint ii = 0; ii < num_images; ++ii) { |
3150 CopyRectToBuffer( | 3167 CopyRectToBuffer( |
3151 source + ii * image_size_src, my_height, unpadded_row_size, | 3168 source + ii * image_size_src, my_height, unpadded_row_size, |
3152 pixels_padded_row_size, buffer_pointer + ii * image_size_dst, | 3169 pixels_padded_row_size, buffer_pointer + ii * image_size_dst, |
3153 buffer_padded_row_size); | 3170 buffer_padded_row_size); |
3154 } | 3171 } |
3155 } else { | 3172 } else { |
3156 CopyRectToBuffer( | 3173 CopyRectToBuffer( |
3157 source, my_height, unpadded_row_size, pixels_padded_row_size, | 3174 source, my_height, unpadded_row_size, pixels_padded_row_size, |
3158 buffer->address(), buffer_padded_row_size); | 3175 buffer->address(), buffer_padded_row_size); |
(...skipping 12 matching lines...) Expand all Loading... | |
3171 depth_index += num_images; | 3188 depth_index += num_images; |
3172 num_image_paddings = num_images; | 3189 num_image_paddings = num_images; |
3173 } else { | 3190 } else { |
3174 row_index = (row_index + my_height) % height; | 3191 row_index = (row_index + my_height) % height; |
3175 num_image_paddings = 0; | 3192 num_image_paddings = 0; |
3176 if (my_height > 0 && row_index == 0) { | 3193 if (my_height > 0 && row_index == 0) { |
3177 depth_index++; | 3194 depth_index++; |
3178 num_image_paddings++; | 3195 num_image_paddings++; |
3179 } | 3196 } |
3180 } | 3197 } |
3181 source += num_rows * pixels_padded_row_size; | 3198 base::CheckedNumeric<uint32_t> source_offset = pixels_padded_row_size; |
3199 source_offset *= num_rows; | |
3200 source += source_offset.ValueOrDefault( | |
3201 std::numeric_limits<uint32_t>::max()); | |
3182 if (unpack_image_height_ > height && num_image_paddings > 0) { | 3202 if (unpack_image_height_ > height && num_image_paddings > 0) { |
3183 source += num_image_paddings * (unpack_image_height_ - height) * | 3203 source_offset = source_offset * num_image_paddings * |
3184 pixels_padded_row_size; | 3204 (unpack_image_height_ - height); |
3205 source += source_offset.ValueOrDefault( | |
3206 std::numeric_limits<uint32_t>::max()); | |
3185 } | 3207 } |
3186 } | 3208 } |
3187 } | 3209 } |
3188 } | 3210 } |
3189 | 3211 |
3190 bool GLES2Implementation::GetActiveAttribHelper( | 3212 bool GLES2Implementation::GetActiveAttribHelper( |
3191 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, | 3213 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, |
3192 GLenum* type, char* name) { | 3214 GLenum* type, char* name) { |
3193 // Clear the bucket so if the command fails nothing will be in it. | 3215 // Clear the bucket so if the command fails nothing will be in it. |
3194 helper_->SetBucketSize(kResultBucketId, 0); | 3216 helper_->SetBucketSize(kResultBucketId, 0); |
(...skipping 3700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6895 cached_extensions_.clear(); | 6917 cached_extensions_.clear(); |
6896 } | 6918 } |
6897 | 6919 |
6898 // Include the auto-generated part of this file. We split this because it means | 6920 // Include the auto-generated part of this file. We split this because it means |
6899 // we can easily edit the non-auto generated parts right here in this file | 6921 // we can easily edit the non-auto generated parts right here in this file |
6900 // instead of having to edit some template or the code generator. | 6922 // instead of having to edit some template or the code generator. |
6901 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 6923 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
6902 | 6924 |
6903 } // namespace gles2 | 6925 } // namespace gles2 |
6904 } // namespace gpu | 6926 } // namespace gpu |
OLD | NEW |