Chromium Code Reviews| 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 |