diff options
Diffstat (limited to 'gpu/command_buffer/common')
-rw-r--r-- | gpu/command_buffer/common/gles2_cmd_utils.cc | 32 | ||||
-rw-r--r-- | gpu/command_buffer/common/gles2_cmd_utils.h | 42 |
2 files changed, 65 insertions, 9 deletions
diff --git a/gpu/command_buffer/common/gles2_cmd_utils.cc b/gpu/command_buffer/common/gles2_cmd_utils.cc index e0fc8e6..7587dd8 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.cc +++ b/gpu/command_buffer/common/gles2_cmd_utils.cc @@ -341,17 +341,35 @@ int BytesPerElement(int type) { } // anonymous namespace // Returns the amount of data glTexImage2D or glTexSubImage2D will access. -uint32 GLES2Util::ComputeImageDataSize( - int width, int height, int format, int type, int unpack_alignment) { +bool GLES2Util::ComputeImageDataSize( + int width, int height, int format, int type, int unpack_alignment, + uint32* size) { uint32 bytes_per_group = BytesPerElement(type) * ElementsPerGroup(format, type); - uint32 row_size = width * bytes_per_group; + uint32 row_size; + if (!SafeMultiplyUint32(width, bytes_per_group, &row_size)) { + return false; + } if (height > 1) { - uint32 padded_row_size = ((row_size + unpack_alignment - 1) / - unpack_alignment) * unpack_alignment; - return (height - 1) * padded_row_size + row_size; + uint32 temp; + if (!SafeAddUint32(row_size, unpack_alignment - 1, &temp)) { + return false; + } + uint32 padded_row_size = (temp / unpack_alignment) * unpack_alignment; + uint32 size_of_all_but_last_row; + if (!SafeMultiplyUint32((height - 1), padded_row_size, + &size_of_all_but_last_row)) { + return false; + } + if (!SafeAddUint32(size_of_all_but_last_row, row_size, size)) { + return false; + } + } else { + if (!SafeMultiplyUint32(height, row_size, size)) { + return false; + } } - return height * row_size; + return true; } uint32 GLES2Util::GetGLDataTypeSizeForUniforms(int type) { diff --git a/gpu/command_buffer/common/gles2_cmd_utils.h b/gpu/command_buffer/common/gles2_cmd_utils.h index 99b17e5..c5cd792 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.h +++ b/gpu/command_buffer/common/gles2_cmd_utils.h @@ -14,6 +14,43 @@ namespace gpu { namespace gles2 { +// Does a multiply and checks for overflow. If the multiply did not overflow +// returns true. +template <typename T> +inline bool SafeMultiply(T a, T b, T* dst) { + *dst = 0; + if (b == 0) { + return true; + } + T v = a * b; + if (v / b != a) { + return false; + } + *dst = v; + return true; +} + +// A wrapper for SafeMultiply to remove the need to cast. +inline bool SafeMultiplyUint32(uint32 a, uint32 b, uint32* dst) { + return SafeMultiply(a, b, dst); +} + +// Does an add checking for overflow. If there was no overflow returns true. +template <typename T> +inline bool SafeAdd(T a, T b, T* dst) { + *dst = 0; + if (a + b < a) { + return false; + } + *dst = a + b; + return true; +} + +// A wrapper for SafeAdd to remove the need to cast. +inline bool SafeAddUint32(uint32 a, uint32 b, uint32* dst) { + return SafeAdd(a, b, dst); +} + // Utilties for GLES2 support. class GLES2Util { public: @@ -27,8 +64,9 @@ class GLES2Util { int GLGetNumValuesReturned(int id) const; // Computes the size of image data for TexImage2D and TexSubImage2D. - static uint32 ComputeImageDataSize( - int width, int height, int format, int type, int unpack_alignment); + static bool ComputeImageDataSize( + int width, int height, int format, int type, int unpack_alignment, + uint32* size); static uint32 GetGLDataTypeSizeForUniforms(int type); |