summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorbsalomon@google.com <bsalomon@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-10 17:39:34 +0000
committerbsalomon@google.com <bsalomon@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-10 17:39:34 +0000
commit3458a64a85abdd0d95678565bf7c6d20c67a0e4e (patch)
treef69e05075fd9dc458fc43cc93b64e02066637d35 /gpu
parent6d32cb06edeb614f99568027e06a32c13c6eb6bb (diff)
downloadchromium_src-3458a64a85abdd0d95678565bf7c6d20c67a0e4e.zip
chromium_src-3458a64a85abdd0d95678565bf7c6d20c67a0e4e.tar.gz
chromium_src-3458a64a85abdd0d95678565bf7c6d20c67a0e4e.tar.bz2
Add GL_EXT_unpack_subimage support to command buffer client code.
BUG=121780 Review URL: https://chromiumcodereview.appspot.com/10012057 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131579 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_flipy.txt75
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc230
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h19
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc150
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils.cc37
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils.h15
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_unittest.cc129
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc78
-rw-r--r--gpu/command_buffer/service/texture_manager.cc4
9 files changed, 512 insertions, 225 deletions
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_flipy.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_flipy.txt
index b51f541..7511fc4 100644
--- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_flipy.txt
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_flipy.txt
@@ -8,7 +8,7 @@ Name Strings
Version
- Last Modifed Date: July 22, 2011
+ Last Modifed Date: April 9, 2012
Dependencies
@@ -28,6 +28,77 @@ New Tokens
UNPACK_FLIP_Y_CHROMIUM 0x9240
+Additions to the OpenGL ES 2.0 Specification
+
+ Modifications to Table 3.1 (PixelStore Parameters)
+
+ Add the following entry:
+
+ Parameter Name Type Initial Value Valid Range
+ ============== ==== ============= ===========
+ UNPACK_FLIP_Y_CHROMIUM boolean FALSE {TRUE, FALSE}
+
+ Modifications to 3.6.2 Transfer of Pixel Rectangles, in the Unpacking
+ section:
+
+ Change
+ "If p indicates the location in memory of the first element of the first
+ row, then the first element of the Nth row is indicated by
+ p + Nk (3.9)"
+ to
+ "If p indicates the location in memory of the first element of the first
+ row, then the first element of the Nth row is indicated by
+ p + Nk (3.9)
+ if UNPACK_FLIP_Y is FALSE. Otherwise, the first element of the Nth row
+ is indicated by
+ p - Nk (3.10)
+
+ After the sentence
+
+ "If the number of bits per element is not 1, 2, 4, or 8 times the number
+ of bits in a GL ubyte, then k = nl for all values of a."
+
+ insert:
+
+ "If UNPACK_FLIP_Y_CHROMIUM is FALSE then p is equal to pixels. Otherwise
+ p is pixels + (height - 1)k."
+
+Interactions with GL_EXT_unpack_subimage
+
+ Do not add the sentence "If UNPACK_FLIP_Y_CHROMIUM is FALSE ..." described
+ in this extension. Instead do the following after applying
+ GL_EXT_unpack_subimage:
+
+ Change
+
+ "There is a mechanism for selecting a sub-rectangle of groups
+ from a larger containing rectangle. This mechanism relies on
+ three integer parameters: UNPACK_ROW_LENGTH, UNPACK_SKIP_ROWS,
+ and UNPACK_SKIP_PIXELS. Before obtaining the first group from
+ memory, the pointer supplied to TexImage2D is effectively
+ advanced by (UNPACK_SKIP_PIXELS)n + (UNPACK_SKIP_ROWS)k
+ elements. Then <width> groups are obtained from contiguous
+ elements in memory (without advancing the pointer), after
+ which the pointer is advanced by k elements. <height> sets of
+ <width> groups of values are obtained this way. See figure
+ 3.6."
+
+ to
+
+ "There is a mechanism for selecting a sub-rectangle of groups
+ from a larger containing rectangle. This mechanism relies on
+ three integer parameters: UNPACK_ROW_LENGTH, UNPACK_SKIP_ROWS,
+ and UNPACK_SKIP_PIXELS. IF UNPACK_FLIP_Y_CHROMIUM is FALSE then
+ p, the location of the first element of the first
+ group, is pixels + (UNPACK_SKIP_PIXELS)n + (UNPACK_SKIP_ROWS)k.
+ When UNPACK_FLIP_Y_CHROMIUM is TRUE then p is pixels +
+ (UNPACK_SKIP_PIXELS)n + (UNPACK_SKIP_ROWS + height - 1)k. After
+ p is determined <width> groups are obtained from contiguous
+ elements in memory (without advancing the pointer), after which
+ the pointer is advanced by +/-k elements depending on the value
+ of UNPACK_CHROMIUM_FLIP_Y. <height> sets of <width> groups of
+ values are obtained this way. See figure 3.6."
+
New Procedures and Functions
None.
@@ -43,3 +114,5 @@ New State
Revision History
7/22/2011 Documented the extension
+ 4/09/2012 Added more documentation and described interactions with
+ GL_EXT_unpack_subimage
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 0230f25..4f5d427 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -389,6 +389,9 @@ GLES2Implementation::GLES2Implementation(
pack_alignment_(4),
unpack_alignment_(4),
unpack_flip_y_(false),
+ unpack_row_length_(0),
+ unpack_skip_rows_(0),
+ unpack_skip_pixels_(0),
pack_reverse_row_order_(false),
active_texture_unit_(0),
bound_framebuffer_(0),
@@ -1240,6 +1243,15 @@ void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
case GL_UNPACK_ALIGNMENT:
unpack_alignment_ = param;
break;
+ case GL_UNPACK_ROW_LENGTH:
+ unpack_row_length_ = param;
+ return;
+ case GL_UNPACK_SKIP_ROWS:
+ unpack_skip_rows_ = param;
+ return;
+ case GL_UNPACK_SKIP_PIXELS:
+ unpack_skip_pixels_ = param;
+ return;
case GL_UNPACK_FLIP_Y_CHROMIUM:
unpack_flip_y_ = (param != 0);
return;
@@ -1512,45 +1524,41 @@ void GLES2Implementation::CompressedTexSubImage2D(
helper_->SetBucketSize(kResultBucketId, 0);
}
-bool GLES2Implementation::CopyRectToBufferFlipped(
- const void* pixels,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- void* buffer) {
- if (width == 0 || height == 0) {
- return true;
- }
-
- uint32 temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 1, format, type, unpack_alignment_, &temp_size)) {
- SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large");
- return false;
- }
- GLsizeiptr unpadded_row_size = temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 2, format, type, unpack_alignment_, &temp_size)) {
- SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large");
- return false;
- }
- GLsizeiptr padded_row_size = temp_size - unpadded_row_size;
- if (padded_row_size < 0 || unpadded_row_size < 0) {
- SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large");
- return false;
- }
+namespace {
+void CopyRectToBuffer(
+ const void* pixels,
+ uint32 height,
+ uint32 unpadded_row_size,
+ uint32 pixels_padded_row_size,
+ bool flip_y,
+ void* buffer,
+ uint32 buffer_padded_row_size) {
const int8* source = static_cast<const int8*>(pixels);
- int8* dest = static_cast<int8*>(buffer) + padded_row_size * (height - 1);
- for (; height; --height) {
+ int8* dest = static_cast<int8*>(buffer);
+ if (flip_y || pixels_padded_row_size != buffer_padded_row_size) {
+ if (flip_y) {
+ dest += buffer_padded_row_size * (height - 1);
+ }
+ // the last row is copied unpadded at the end
+ for (; height > 1; --height) {
+ memcpy(dest, source, buffer_padded_row_size);
+ if (flip_y) {
+ dest -= buffer_padded_row_size;
+ } else {
+ dest += buffer_padded_row_size;
+ }
+ source += pixels_padded_row_size;
+ }
memcpy(dest, source, unpadded_row_size);
- dest -= padded_row_size;
- source += padded_row_size;
+ } else {
+ uint32 size = (height - 1) * pixels_padded_row_size + unpadded_row_size;
+ memcpy(dest, source, size);
}
- return true;
}
+} // anonymous namespace
+
void GLES2Implementation::TexImage2D(
GLenum target, GLint level, GLint internalformat, GLsizei width,
GLsizei height, GLint border, GLenum format, GLenum type,
@@ -1569,8 +1577,11 @@ void GLES2Implementation::TexImage2D(
return;
}
uint32 size;
- if (!GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_, &size)) {
+ uint32 unpadded_row_size;
+ uint32 padded_row_size;
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, unpack_alignment_, &size,
+ &unpadded_row_size, &padded_row_size)) {
SetGLError(GL_INVALID_VALUE, "glTexImage2D: image size too large");
return;
}
@@ -1583,6 +1594,28 @@ void GLES2Implementation::TexImage2D(
return;
}
+ // compute the advance bytes per row for the src pixels
+ uint32 src_padded_row_size;
+ if (unpack_row_length_ > 0) {
+ if (!GLES2Util::ComputeImagePaddedRowSize(
+ unpack_row_length_, format, type, unpack_alignment_,
+ &src_padded_row_size)) {
+ SetGLError(GL_INVALID_VALUE, "glTexImage2D: unpack row length too large");
+ return;
+ }
+ } else {
+ src_padded_row_size = padded_row_size;
+ }
+
+ // advance pixels pointer past the skip rows and skip pixels
+ pixels = reinterpret_cast<const int8*>(pixels) +
+ unpack_skip_rows_ * src_padded_row_size;
+ if (unpack_skip_pixels_) {
+ uint32 group_size = GLES2Util::ComputeImageGroupSize(format, type);
+ pixels = reinterpret_cast<const int8*>(pixels) +
+ unpack_skip_pixels_ * group_size;
+ }
+
// Check if we can send it all at once.
ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
if (!buffer.valid()) {
@@ -1590,19 +1623,12 @@ void GLES2Implementation::TexImage2D(
}
if (buffer.size() >= size) {
- bool copy_success = true;
- if (unpack_flip_y_) {
- copy_success = CopyRectToBufferFlipped(
- pixels, width, height, format, type, buffer.address());
- } else {
- memcpy(buffer.address(), pixels, size);
- }
-
- if (copy_success) {
- helper_->TexImage2D(
- target, level, internalformat, width, height, border, format, type,
- buffer.shm_id(), buffer.offset());
- }
+ CopyRectToBuffer(
+ pixels, height, unpadded_row_size, src_padded_row_size, unpack_flip_y_,
+ buffer.address(), padded_row_size);
+ helper_->TexImage2D(
+ target, level, internalformat, width, height, border, format, type,
+ buffer.shm_id(), buffer.offset());
return;
}
@@ -1611,8 +1637,8 @@ void GLES2Implementation::TexImage2D(
target, level, internalformat, width, height, border, format, type,
0, 0);
TexSubImage2DImpl(
- target, level, 0, 0, width, height, format, type, pixels, GL_TRUE,
- &buffer);
+ target, level, 0, 0, width, height, format, type, unpadded_row_size,
+ pixels, src_padded_row_size, GL_TRUE, &buffer, padded_row_size);
}
void GLES2Implementation::TexSubImage2D(
@@ -1637,16 +1663,42 @@ void GLES2Implementation::TexSubImage2D(
}
uint32 temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_, &temp_size)) {
+ uint32 unpadded_row_size;
+ uint32 padded_row_size;
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, unpack_alignment_, &temp_size,
+ &unpadded_row_size, &padded_row_size)) {
SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large");
return;
}
+ // compute the advance bytes per row for the src pixels
+ uint32 src_padded_row_size;
+ if (unpack_row_length_ > 0) {
+ if (!GLES2Util::ComputeImagePaddedRowSize(
+ unpack_row_length_, format, type, unpack_alignment_,
+ &src_padded_row_size)) {
+ SetGLError(GL_INVALID_VALUE, "glTexImage2D: unpack row length too large");
+ return;
+ }
+ } else {
+ src_padded_row_size = padded_row_size;
+ }
+
+ // advance pixels pointer past the skip rows and skip pixels
+ pixels = reinterpret_cast<const int8*>(pixels) +
+ unpack_skip_rows_ * src_padded_row_size;
+ if (unpack_skip_pixels_) {
+ uint32 group_size = GLES2Util::ComputeImageGroupSize(format, type);
+ pixels = reinterpret_cast<const int8*>(pixels) +
+ unpack_skip_pixels_ * group_size;
+ }
+
ScopedTransferBufferPtr buffer(temp_size, helper_, transfer_buffer_);
TexSubImage2DImpl(
- target, level, xoffset, yoffset, width, height, format, type, pixels,
- GL_FALSE, &buffer);
+ target, level, xoffset, yoffset, width, height, format, type,
+ unpadded_row_size, pixels, src_padded_row_size, GL_FALSE, &buffer,
+ padded_row_size);
}
static GLint ComputeNumRowsThatFitInBuffer(
@@ -1662,37 +1714,20 @@ static GLint ComputeNumRowsThatFitInBuffer(
void GLES2Implementation::TexSubImage2DImpl(
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
- GLsizei height, GLenum format, GLenum type, const void* pixels,
- GLboolean internal, ScopedTransferBufferPtr* buffer) {
+ GLsizei height, GLenum format, GLenum type, uint32 unpadded_row_size,
+ const void* pixels, uint32 pixels_padded_row_size, GLboolean internal,
+ ScopedTransferBufferPtr* buffer, uint32 buffer_padded_row_size) {
GPU_DCHECK(buffer);
GPU_DCHECK_GE(level, 0);
GPU_DCHECK_GT(height, 0);
GPU_DCHECK_GT(width, 0);
- const int8* source = static_cast<const int8*>(pixels);
- uint32 temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 1, format, type, unpack_alignment_, &temp_size)) {
- SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large");
- return;
- }
- GLsizeiptr unpadded_row_size = temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 2, format, type, unpack_alignment_, &temp_size)) {
- SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large");
- return;
- }
- GLsizeiptr padded_row_size = temp_size - unpadded_row_size;
- if (padded_row_size < 0 || unpadded_row_size < 0) {
- SetGLError(GL_INVALID_VALUE, "glTexSubImage2D: size to large");
- return;
- }
-
+ const int8* source = reinterpret_cast<const int8*>(pixels);
GLint original_yoffset = yoffset;
// Transfer by rows.
while (height) {
unsigned int desired_size =
- padded_row_size * (height - 1) + unpadded_row_size;
+ buffer_padded_row_size * (height - 1) + unpadded_row_size;
if (!buffer->valid() || buffer->size() == 0) {
buffer->Reset(desired_size);
if (!buffer->valid()) {
@@ -1701,24 +1736,18 @@ void GLES2Implementation::TexSubImage2DImpl(
}
GLint num_rows = ComputeNumRowsThatFitInBuffer(
- padded_row_size, unpadded_row_size, buffer->size());
+ buffer_padded_row_size, unpadded_row_size, buffer->size());
num_rows = std::min(num_rows, height);
- GLint y;
- if (unpack_flip_y_) {
- CopyRectToBufferFlipped(
- source, width, num_rows, format, type, buffer->address());
- y = original_yoffset + height - num_rows;
- } else {
- temp_size = padded_row_size * (num_rows - 1) + unpadded_row_size;
- memcpy(buffer->address(), source, temp_size);
- y = yoffset;
- }
+ CopyRectToBuffer(
+ source, num_rows, unpadded_row_size, pixels_padded_row_size,
+ unpack_flip_y_, buffer->address(), buffer_padded_row_size);
+ GLint y = unpack_flip_y_ ? original_yoffset + height - num_rows : yoffset;
helper_->TexSubImage2D(
target, level, xoffset, y, width, num_rows, format, type,
buffer->shm_id(), buffer->offset(), internal);
buffer->Release();
yoffset += num_rows;
- source += num_rows * padded_row_size;
+ source += num_rows * pixels_padded_row_size;
height -= num_rows;
}
}
@@ -1945,7 +1974,8 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) {
case GL_EXTENSIONS:
str += std::string(str.empty() ? "" : " ") +
"GL_CHROMIUM_map_sub "
- "GL_CHROMIUM_flipy";
+ "GL_CHROMIUM_flipy "
+ "GL_EXT_unpack_subimage";
break;
default:
break;
@@ -2062,19 +2092,11 @@ void GLES2Implementation::ReadPixels(
int8* dest = reinterpret_cast<int8*>(pixels);
uint32 temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 1, format, type, pack_alignment_, &temp_size)) {
- SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large.");
- return;
- }
- GLsizeiptr unpadded_row_size = temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 2, format, type, pack_alignment_, &temp_size)) {
- SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large.");
- return;
- }
- GLsizei padded_row_size = temp_size - unpadded_row_size;
- if (padded_row_size < 0 || unpadded_row_size < 0) {
+ uint32 unpadded_row_size;
+ uint32 padded_row_size;
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, 2, format, type, pack_alignment_, &temp_size, &unpadded_row_size,
+ &padded_row_size)) {
SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large.");
return;
}
@@ -2582,8 +2604,8 @@ void* GLES2Implementation::MapTexSubImage2DCHROMIUM(
return NULL;
}
uint32 size;
- if (!GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_, &size)) {
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, unpack_alignment_, &size, NULL, NULL)) {
SetGLError(
GL_INVALID_VALUE, "MapTexSubImage2DCHROMIUM: image size too large");
return NULL;
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 69e875c..60fd9c7 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -413,13 +413,13 @@ class GLES2_IMPL_EXPORT GLES2Implementation {
GLuint GetMaxValueInBufferCHROMIUMHelper(
GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
- bool CopyRectToBufferFlipped(
- const void* pixels, GLsizei width, GLsizei height, GLenum format,
- GLenum type, void* buffer);
+ // The pixels pointer should already account for unpack skip rows and skip
+ // pixels.
void TexSubImage2DImpl(
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
- GLsizei height, GLenum format, GLenum type, const void* pixels,
- GLboolean internal, ScopedTransferBufferPtr* buffer);
+ GLsizei height, GLenum format, GLenum type, uint32 unpadded_row_size,
+ const void* pixels, uint32 pixels_padded_row_size, GLboolean internal,
+ ScopedTransferBufferPtr* buffer, uint32 buffer_padded_row_size);
// Helpers for query functions.
bool GetHelper(GLenum pname, GLint* params);
@@ -462,6 +462,15 @@ class GLES2_IMPL_EXPORT GLES2Implementation {
// unpack yflip as last set by glPixelstorei
bool unpack_flip_y_;
+ // unpack row length as last set by glPixelStorei
+ GLint unpack_row_length_;
+
+ // unpack skip rows as last set by glPixelStorei
+ GLint unpack_skip_rows_;
+
+ // unpack skip pixels as last set by glPixelStorei
+ GLint unpack_skip_pixels_;
+
// pack reverse row order as last set by glPixelstorei
bool pack_reverse_row_order_;
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index e4a1ebe..4bb5830 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -1836,31 +1836,13 @@ TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
}
-static bool ComputeImageDataSizes(
- int width, int height, int format, int type, int unpack_alignment,
- uint32* size, uint32* unpadded_row_size, uint32* padded_row_size) {
- uint32 temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 1, format, type, unpack_alignment, &temp_size)) {
- return false;
- }
- *unpadded_row_size = temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 2, format, type, unpack_alignment, &temp_size)) {
- return false;
- }
- *padded_row_size = temp_size - *unpadded_row_size;
- return GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment, size);
-}
-
static bool CheckRect(
int width, int height, GLenum format, GLenum type, int alignment,
bool flip_y, const uint8* r1, const uint8* r2) {
uint32 size = 0;
uint32 unpadded_row_size = 0;
uint32 padded_row_size = 0;
- if (!ComputeImageDataSizes(
+ if (!GLES2Util::ComputeImageDataSizes(
width, height, format, type, alignment, &size, &unpadded_row_size,
&padded_row_size)) {
return false;
@@ -1965,17 +1947,17 @@ TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
uint32 size = 0;
uint32 unpadded_row_size = 0;
uint32 padded_row_size = 0;
- ASSERT_TRUE(ComputeImageDataSizes(
+ ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
&size, &unpadded_row_size, &padded_row_size));
const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
- ASSERT_TRUE(GLES2Util::ComputeImageDataSize(
+ ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
- &size));
+ &size, NULL, NULL));
uint32 half_size = 0;
- ASSERT_TRUE(GLES2Util::ComputeImageDataSize(
+ ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
- &half_size));
+ &half_size, NULL, NULL));
scoped_array<uint8> pixels(new uint8[size]);
for (uint32 ii = 0; ii < size; ++ii) {
@@ -2073,9 +2055,9 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
};
uint32 sub_2_high_size = 0;
- ASSERT_TRUE(GLES2Util::ComputeImageDataSize(
+ ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
- &sub_2_high_size));
+ &sub_2_high_size, NULL, NULL));
ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size);
ExpectedMemoryInfo mem2 = GetExpectedMemory(sub_2_high_size);
@@ -2117,6 +2099,119 @@ TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
mem2.ptr));
}
+TEST_F(GLES2ImplementationTest, SubImageUnpack) {
+ static const GLint unpack_alignments[] = { 1, 2, 4, 8 };
+
+ static const GLenum kFormat = GL_RGB;
+ static const GLenum kType = GL_UNSIGNED_BYTE;
+ static const GLint kLevel = 0;
+ static const GLint kBorder = 0;
+ // We're testing using the unpack params to pull a subimage out of a larger
+ // source of pixels. Here we specify the subimage by its border rows /
+ // columns.
+ static const GLint kSrcWidth = 33;
+ static const GLint kSrcSubImageX0 = 11;
+ static const GLint kSrcSubImageX1 = 20;
+ static const GLint kSrcSubImageY0 = 18;
+ static const GLint kSrcSubImageY1 = 23;
+ static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
+ static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;
+
+ // these are only used in the texsubimage tests
+ static const GLint kTexWidth = 1023;
+ static const GLint kTexHeight = 511;
+ static const GLint kTexSubXOffset = 419;
+ static const GLint kTexSubYOffset = 103;
+
+ struct {
+ PixelStorei pixel_store_i;
+ TexImage2D tex_image_2d;
+ } texImageExpected;
+
+ struct {
+ PixelStorei pixel_store_i;
+ TexImage2D tex_image_2d;
+ TexSubImage2D tex_sub_image_2d;
+ } texSubImageExpected;
+
+ uint32 src_size;
+ ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kSrcWidth, kSrcSubImageY1, kFormat, kType, 8, &src_size, NULL, NULL));
+ scoped_array<uint8> src_pixels;
+ src_pixels.reset(new uint8[src_size]);
+ for (size_t i = 0; i < src_size; ++i) {
+ src_pixels[i] = static_cast<int8>(i);
+ }
+
+ for (int sub = 0; sub < 2; ++sub) {
+ for (int flip_y = 0; flip_y < 2; ++flip_y) {
+ for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
+ GLint alignment = unpack_alignments[a];
+ uint32 size;
+ uint32 unpadded_row_size;
+ uint32 padded_row_size;
+ ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, alignment,
+ &size, &unpadded_row_size, &padded_row_size));
+ ASSERT_TRUE(size <= MaxTransferBufferSize());
+ ExpectedMemoryInfo mem = GetExpectedMemory(size);
+
+ const void* commands = GetPut();
+ gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
+ gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, kSrcWidth);
+ gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS, kSrcSubImageX0);
+ gl_->PixelStorei(GL_UNPACK_SKIP_ROWS, kSrcSubImageY0);
+ gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
+ if (sub) {
+ gl_->TexImage2D(
+ GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
+ kFormat, kType, NULL);
+ gl_->TexSubImage2D(
+ GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
+ kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType,
+ src_pixels.get());
+ texSubImageExpected.pixel_store_i.Init(
+ GL_UNPACK_ALIGNMENT, alignment);
+ texSubImageExpected.tex_image_2d.Init(
+ GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
+ kFormat, kType, 0, 0);
+ texSubImageExpected.tex_sub_image_2d.Init(
+ GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
+ kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id,
+ mem.offset, GL_FALSE);
+ EXPECT_EQ(0, memcmp(
+ &texSubImageExpected, commands, sizeof(texSubImageExpected)));
+ } else {
+ gl_->TexImage2D(
+ GL_TEXTURE_2D, kLevel, kFormat,
+ kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType,
+ src_pixels.get());
+ texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
+ texImageExpected.tex_image_2d.Init(
+ GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth,
+ kSrcSubImageHeight, kBorder, kFormat, kType, mem.id, mem.offset);
+ EXPECT_EQ(0, memcmp(
+ &texImageExpected, commands, sizeof(texImageExpected)));
+ }
+ uint32 src_padded_row_size;
+ ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
+ kSrcWidth, kFormat, kType, alignment, &src_padded_row_size));
+ uint32 bytes_per_group = GLES2Util::ComputeImageGroupSize(
+ kFormat, kType);
+ for (int y = 0; y < kSrcSubImageHeight; ++y) {
+ GLint src_sub_y = flip_y ? kSrcSubImageHeight - y - 1 : y;
+ const uint8* src_row = src_pixels.get() +
+ (kSrcSubImageY0 + src_sub_y) * src_padded_row_size +
+ bytes_per_group * kSrcSubImageX0;
+ const uint8* dst_row = mem.ptr + y * padded_row_size;
+ EXPECT_EQ(0, memcmp(src_row, dst_row, unpadded_row_size));
+ }
+ ClearCommands();
+ }
+ }
+ }
+}
+
// Binds can not be cached with bind_generates_resource = false because
// our id might not be valid. More specifically if you bind on contextA then
// delete on contextB the resource is still bound on contextA but GetInterger
@@ -2181,7 +2276,8 @@ TEST_F(GLES2ImplementationTest, GetString) {
const Str7 kString = {"foobar"};
// GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
// GLES2Implementation.
- const char* expected_str = "foobar GL_CHROMIUM_map_sub GL_CHROMIUM_flipy";
+ const char* expected_str =
+ "foobar GL_CHROMIUM_map_sub GL_CHROMIUM_flipy GL_EXT_unpack_subimage";
const char kBad = 0x12;
struct Cmds {
cmd::SetBucketSize set_bucket_size1;
diff --git a/gpu/command_buffer/common/gles2_cmd_utils.cc b/gpu/command_buffer/common/gles2_cmd_utils.cc
index aa4abe1..9891268 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils.cc
+++ b/gpu/command_buffer/common/gles2_cmd_utils.cc
@@ -373,12 +373,31 @@ int BytesPerElement(int type) {
} // anonymous namespace
+uint32 GLES2Util::ComputeImageGroupSize(int format, int type) {
+ return BytesPerElement(type) * ElementsPerGroup(format, type);
+}
+
+bool GLES2Util::ComputeImagePaddedRowSize(
+ int width, int format, int type, int unpack_alignment,
+ uint32* padded_row_size) {
+ uint32 bytes_per_group = ComputeImageGroupSize(format, type);
+ uint32 unpadded_row_size;
+ if (!SafeMultiplyUint32(width, bytes_per_group, &unpadded_row_size)) {
+ return false;
+ }
+ uint32 temp;
+ if (!SafeAddUint32(unpadded_row_size, unpack_alignment - 1, &temp)) {
+ return false;
+ }
+ *padded_row_size = (temp / unpack_alignment) * unpack_alignment;
+ return true;
+}
+
// Returns the amount of data glTexImage2D or glTexSubImage2D will access.
-bool GLES2Util::ComputeImageDataSize(
+bool GLES2Util::ComputeImageDataSizes(
int width, int height, int format, int type, int unpack_alignment,
- uint32* size) {
- uint32 bytes_per_group =
- BytesPerElement(type) * ElementsPerGroup(format, type);
+ uint32* size, uint32* ret_unpadded_row_size, uint32* ret_padded_row_size) {
+ uint32 bytes_per_group = ComputeImageGroupSize(format, type);
uint32 row_size;
if (!SafeMultiplyUint32(width, bytes_per_group, &row_size)) {
return false;
@@ -397,11 +416,21 @@ bool GLES2Util::ComputeImageDataSize(
if (!SafeAddUint32(size_of_all_but_last_row, row_size, size)) {
return false;
}
+ if (ret_padded_row_size) {
+ *ret_padded_row_size = padded_row_size;
+ }
} else {
if (!SafeMultiplyUint32(height, row_size, size)) {
return false;
}
+ if (ret_padded_row_size) {
+ *ret_padded_row_size = row_size;
+ }
+ }
+ if (ret_unpadded_row_size) {
+ *ret_unpadded_row_size = row_size;
}
+
return true;
}
diff --git a/gpu/command_buffer/common/gles2_cmd_utils.h b/gpu/command_buffer/common/gles2_cmd_utils.h
index fd014a1..c4fe663 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils.h
@@ -103,10 +103,21 @@ class GLES2_UTILS_EXPORT GLES2Util {
// function is called. If 0 is returned the id is invalid.
int GLGetNumValuesReturned(int id) const;
+ // Computes the size of a single group of elements from a format and type pair
+ static uint32 ComputeImageGroupSize(int format, int type);
+
+ // Computes the size of an image row including alignment padding
+ static bool ComputeImagePaddedRowSize(
+ int width, int format, int type, int unpack_alignment,
+ uint32* padded_row_size);
+
// Computes the size of image data for TexImage2D and TexSubImage2D.
- static bool ComputeImageDataSize(
+ // Optionally the unpadded and padded row sizes can be returned. If height < 2
+ // then the padded_row_size will be the same as the unpadded_row_size since
+ // padding is not necessary.
+ static bool ComputeImageDataSizes(
int width, int height, int format, int type, int unpack_alignment,
- uint32* size);
+ uint32* size, uint32* unpadded_row_size, uint32* padded_row_size);
static size_t RenderbufferBytesPerPixel(int format);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc b/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc
index cf5a0ee..277461a 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc
+++ b/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc
@@ -34,77 +34,134 @@ TEST_F(GLES2UtilTest, GLGetNumValuesReturned) {
EXPECT_EQ(2, util_.num_shader_binary_formats());
}
-TEST_F(GLES2UtilTest, ComputeImageDataSizeFormats) {
+TEST_F(GLES2UtilTest, ComputeImageDataSizesFormats) {
const uint32 kWidth = 16;
const uint32 kHeight = 12;
uint32 size;
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 1, &size));
+ uint32 unpadded_row_size;
+ uint32 padded_row_size;
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size,
+ &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 3, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 1, &size));
+ EXPECT_EQ(kWidth * 3, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size,
+ &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 4, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, &size));
+ EXPECT_EQ(kWidth * 4, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, &size,
+ &unpadded_row_size, &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 1, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, &size));
+ EXPECT_EQ(kWidth * 1, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, &size,
+ &unpadded_row_size, &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 2, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 1, &size));
+ EXPECT_EQ(kWidth * 2, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 1, &size,
+ &unpadded_row_size, &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 4, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_ALPHA, GL_UNSIGNED_BYTE, 1, &size));
+ EXPECT_EQ(kWidth * 4, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_ALPHA, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size,
+ &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 1, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 1, &size));
+ EXPECT_EQ(kWidth * 1, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 1, &size,
+ &unpadded_row_size, &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 2, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
+ EXPECT_EQ(kWidth * 2, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
kWidth, kHeight, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, 1,
- &size));
+ &size, &unpadded_row_size,
+ &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 4, size);
+ EXPECT_EQ(kWidth * 4, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
}
TEST_F(GLES2UtilTest, ComputeImageDataSizeTypes) {
const uint32 kWidth = 16;
const uint32 kHeight = 12;
uint32 size;
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 1, &size));
+ uint32 unpadded_row_size;
+ uint32 padded_row_size;
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size,
+ &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 4, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 1, &size));
+ EXPECT_EQ(kWidth * 4, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 1, &size,
+ &unpadded_row_size, &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 2, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 1, &size));
+ EXPECT_EQ(kWidth * 2, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 1, &size,
+ &unpadded_row_size, &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 2, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 1, &size));
+ EXPECT_EQ(kWidth * 2, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 1, &size,
+ &unpadded_row_size, &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 2, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 1, &size));
+ EXPECT_EQ(kWidth * 2, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 1, &size,
+ &unpadded_row_size, &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 4, size);
+ EXPECT_EQ(kWidth * 4, padded_row_size);
+ EXPECT_EQ(padded_row_size, unpadded_row_size);
}
-TEST_F(GLES2UtilTest, ComputeImageDataSizeUnpackAlignment) {
+TEST_F(GLES2UtilTest, ComputeImageDataSizesUnpackAlignment) {
const uint32 kWidth = 19;
const uint32 kHeight = 12;
uint32 size;
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 1, &size));
+ uint32 unpadded_row_size;
+ uint32 padded_row_size;
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size,
+ &padded_row_size));
EXPECT_EQ(kWidth * kHeight * 3, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 2, &size));
+ EXPECT_EQ(kWidth * 3, unpadded_row_size);
+ EXPECT_EQ(kWidth * 3, padded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 2, &size, &unpadded_row_size,
+ &padded_row_size));
EXPECT_EQ((kWidth * 3 + 1) * (kHeight - 1) +
kWidth * 3, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 4, &size));
+ EXPECT_EQ(kWidth * 3, unpadded_row_size);
+ EXPECT_EQ(kWidth * 3 + 1, padded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 4, &size, &unpadded_row_size,
+ &padded_row_size));
EXPECT_EQ((kWidth * 3 + 3) * (kHeight - 1) +
kWidth * 3, size);
- EXPECT_TRUE(GLES2Util::ComputeImageDataSize(
- kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 8, &size));
+ EXPECT_EQ(kWidth * 3, unpadded_row_size);
+ EXPECT_EQ(kWidth * 3 + 3, padded_row_size);
+ EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
+ kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 8, &size, &unpadded_row_size,
+ &padded_row_size));
EXPECT_EQ((kWidth * 3 + 7) * (kHeight - 1) +
kWidth * 3, size);
+ EXPECT_EQ(kWidth * 3, unpadded_row_size);
+ EXPECT_EQ(kWidth * 3 + 7, padded_row_size);
}
TEST_F(GLES2UtilTest, RenderbufferBytesPerPixel) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 0a90ec2..45f5aa7 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1657,8 +1657,9 @@ bool Texture::AllocateStorage(const gfx::Size& size, GLenum format) {
bool success = glGetError() == GL_NO_ERROR;
if (success) {
uint32 image_size = 0;
- GLES2Util::ComputeImageDataSize(
- size.width(), size.height(), format, GL_UNSIGNED_BYTE, 4, &image_size);
+ GLES2Util::ComputeImageDataSizes(
+ size.width(), size.height(), format, GL_UNSIGNED_BYTE, 4, &image_size,
+ NULL, NULL);
estimated_size_ = image_size;
decoder_->UpdateBackbufferMemoryAccounting();
}
@@ -5971,8 +5972,8 @@ error::Error GLES2DecoderImpl::HandleReadPixels(
}
typedef gles2::ReadPixels::Result Result;
uint32 pixels_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, height, format, type, pack_alignment_, &pixels_size)) {
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, pack_alignment_, &pixels_size, NULL, NULL)) {
return error::kOutOfBounds;
}
void* pixels = GetSharedMemoryAs<void*>(
@@ -6017,27 +6018,20 @@ error::Error GLES2DecoderImpl::HandleReadPixels(
// The user requested an out of range area. Get the results 1 line
// at a time.
uint32 temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 1, format, type, pack_alignment_, &temp_size)) {
- SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range");
- return error::kNoError;
- }
- GLsizei unpadded_row_size = temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 2, format, type, pack_alignment_, &temp_size)) {
- SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range");
- return error::kNoError;
- }
- GLsizei padded_row_size = temp_size - unpadded_row_size;
- if (padded_row_size < 0 || unpadded_row_size < 0) {
+ uint32 unpadded_row_size;
+ uint32 padded_row_size;
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, 2, format, type, pack_alignment_, &temp_size,
+ &unpadded_row_size, &padded_row_size)) {
SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range");
return error::kNoError;
}
GLint dest_x_offset = std::max(-x, 0);
uint32 dest_row_offset;
- if (!GLES2Util::ComputeImageDataSize(
- dest_x_offset, 1, format, type, pack_alignment_, &dest_row_offset)) {
+ if (!GLES2Util::ComputeImageDataSizes(
+ dest_x_offset, 1, format, type, pack_alignment_, &dest_row_offset, NULL,
+ NULL)) {
SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range");
return error::kNoError;
}
@@ -6072,19 +6066,12 @@ error::Error GLES2DecoderImpl::HandleReadPixels(
if ((channels_exist & 0x0008) == 0) {
// Set the alpha to 255 because some drivers are buggy in this regard.
uint32 temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 1, format, type, pack_alignment_, &temp_size)) {
- SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range");
- return error::kNoError;
- }
- GLsizei unpadded_row_size = temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 2, format, type, pack_alignment_, &temp_size)) {
- SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range");
- return error::kNoError;
- }
- GLsizei padded_row_size = temp_size - unpadded_row_size;
- if (padded_row_size < 0 || unpadded_row_size < 0) {
+
+ uint32 unpadded_row_size;
+ uint32 padded_row_size;
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, 2, format, type, pack_alignment_, &temp_size,
+ &unpadded_row_size, &padded_row_size)) {
SetGLError(GL_INVALID_VALUE, "glReadPixels: dimensions out of range");
return error::kNoError;
}
@@ -6463,8 +6450,9 @@ bool GLES2DecoderImpl::ClearLevel(
bool is_texture_immutable) {
// Assumes the size has already been checked.
uint32 pixels_size = 0;
- if (!GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_, &pixels_size)) {
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, unpack_alignment_, &pixels_size, NULL,
+ NULL)) {
return false;
}
scoped_array<char> zero(new char[pixels_size]);
@@ -6771,8 +6759,9 @@ error::Error GLES2DecoderImpl::HandleTexImage2D(
uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
uint32 pixels_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_, &pixels_size)) {
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, unpack_alignment_, &pixels_size, NULL,
+ NULL)) {
return error::kOutOfBounds;
}
const void* pixels = NULL;
@@ -6799,8 +6788,8 @@ error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
GLenum format = static_cast<GLenum>(c.format);
GLenum type = static_cast<GLenum>(c.type);
uint32 size;
- if (!GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_, &size)) {
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, unpack_alignment_, &size, NULL, NULL)) {
return error::kOutOfBounds;
}
const void* pixels = GetImmediateDataAs<const void*>(
@@ -7026,8 +7015,9 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D(
copyHeight != height) {
// some part was clipped so clear the sub rect.
uint32 pixels_size = 0;
- if (!GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_, &pixels_size)) {
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, unpack_alignment_, &pixels_size, NULL,
+ NULL)) {
SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D: dimensions too large");
return;
}
@@ -7134,8 +7124,8 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2D(
GLenum format = static_cast<GLenum>(c.format);
GLenum type = static_cast<GLenum>(c.type);
uint32 data_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_, &data_size)) {
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, unpack_alignment_, &data_size, NULL, NULL)) {
return error::kOutOfBounds;
}
const void* pixels = GetSharedMemoryAs<const void*>(
@@ -7183,8 +7173,8 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
GLenum format = static_cast<GLenum>(c.format);
GLenum type = static_cast<GLenum>(c.type);
uint32 data_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_, &data_size)) {
+ if (!GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, unpack_alignment_, &data_size, NULL, NULL)) {
return error::kOutOfBounds;
}
const void* pixels = GetImmediateDataAs<const void*>(
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 26f4787..055c2ab 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -265,8 +265,8 @@ void TextureManager::TextureInfo::SetLevelInfo(
info.type = type;
estimated_size_ -= info.estimated_size;
- GLES2Util::ComputeImageDataSize(
- width, height, format, type, 4, &info.estimated_size);
+ GLES2Util::ComputeImageDataSizes(
+ width, height, format, type, 4, &info.estimated_size, NULL, NULL);
estimated_size_ += info.estimated_size;
if (!info.cleared) {