Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: gpu/command_buffer/client/gles2_implementation.cc

Issue 2310243002: Supress integer-overflow in TexSubImage2D(3D)Impl (Closed)
Patch Set: one more place Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698