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

Unified Diff: gpu/command_buffer/client/gles2_implementation.cc

Issue 10012057: Add GL_EXT_unpack_subimage support to command buffer client code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/client/gles2_implementation.cc
===================================================================
--- gpu/command_buffer/client/gles2_implementation.cc (revision 131422)
+++ gpu/command_buffer/client/gles2_implementation.cc (working copy)
@@ -389,6 +389,9 @@
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),
@@ -1229,6 +1232,15 @@
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;
@@ -1501,45 +1513,41 @@
helper_->SetBucketSize(kResultBucketId, 0);
}
-bool GLES2Implementation::CopyRectToBufferFlipped(
+namespace {
+
+void CopyRectToBuffer(
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;
- }
-
+ 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,
@@ -1558,8 +1566,11 @@
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;
}
@@ -1572,6 +1583,28 @@
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()) {
@@ -1579,19 +1612,12 @@
}
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;
}
@@ -1600,8 +1626,8 @@
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(
@@ -1626,16 +1652,42 @@
}
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(
@@ -1651,37 +1703,20 @@
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()) {
@@ -1690,24 +1725,18 @@
}
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;
}
}
@@ -1934,7 +1963,8 @@
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;
@@ -2051,22 +2081,14 @@
int8* dest = reinterpret_cast<int8*>(pixels);
uint32 temp_size;
- if (!GLES2Util::ComputeImageDataSize(
- width, 1, format, type, pack_alignment_, &temp_size)) {
+ 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;
}
- 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) {
- SetGLError(GL_INVALID_VALUE, "glReadPixels: size too large.");
- return;
- }
// Transfer by rows.
// The max rows we can transfer.
while (height) {
@@ -2571,8 +2593,8 @@
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;
« no previous file with comments | « gpu/command_buffer/client/gles2_implementation.h ('k') | gpu/command_buffer/client/gles2_implementation_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698