summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/common
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/command_buffer/common')
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils.cc32
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils.h42
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);