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

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

Issue 706173005: Enable asynchronous glReadPixels on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add mechanism to propagate service-side glMapBuffer errors + tests. Created 6 years, 1 month 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
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 241056cefd013454dd6b64f840c6bdcea1eff4a2..9e7ff75559a6493bd18f64aab386a76bba80c9bd 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -1323,8 +1323,12 @@ void GLES2Implementation::BufferDataHelper(
if (buffer)
RemoveTransferBuffer(buffer);
- // Create new buffer.
- buffer = buffer_tracker_->CreateBuffer(buffer_id, size);
+ // Create new buffer. For the async readback use case, allocate a few
+ // extra bytes to contain any service-side glMapBuffer errors.
+ const GLsizeiptr metadata_size =
+ target == GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM ?
+ sizeof(cmds::ReadPixels::Result) : 0;
+ buffer = buffer_tracker_->CreateBuffer(buffer_id, size, metadata_size);
DCHECK(buffer);
if (buffer->address() && data)
memcpy(buffer->address(), data, size);
@@ -2249,17 +2253,23 @@ void GLES2Implementation::ReadPixels(
return;
}
- if (bound_pixel_pack_transfer_buffer_id_) {
+ if (bound_pixel_pack_transfer_buffer_id_) { // Asynchronous readback path.
GLuint offset = ToGLuint(pixels);
BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
bound_pixel_pack_transfer_buffer_id_,
"glReadPixels", offset, padded_row_size * height);
- if (buffer && buffer->shm_id() != -1) {
- helper_->ReadPixels(xoffset, yoffset, width, height, format, type,
- buffer->shm_id(), buffer->shm_offset(),
- 0, 0, true);
- CheckGLError();
+ if (!buffer || buffer->shm_id() == -1) {
+ SetGLError(GL_INVALID_OPERATION, "glReadPixels", "invalid buffer.");
+ return;
}
+
+ DCHECK_EQ(buffer->metadata_size(), sizeof(Result));
+ helper_->ReadPixels(
+ xoffset, yoffset, width, height, format, type,
+ buffer->shm_id(), buffer->shm_offset(),
+ buffer->metadata_shm_id(), buffer->metadata_shm_offset(),
+ true);
+ CheckGLError();
return;
}
@@ -2285,38 +2295,37 @@ void GLES2Implementation::ReadPixels(
if (!result) {
return;
}
- *result = 0; // mark as failed.
helper_->ReadPixels(
xoffset, yoffset, width, num_rows, format, type,
buffer.shm_id(), buffer.offset(),
GetResultShmId(), GetResultShmOffset(),
false);
WaitForCmd();
- if (*result != 0) {
- // when doing a y-flip we have to iterate through top-to-bottom chunks
- // of the dst. The service side handles reversing the rows within a
- // chunk.
- int8* rows_dst;
- if (pack_reverse_row_order_) {
- rows_dst = dest + (height - num_rows) * padded_row_size;
- } else {
- rows_dst = dest;
- }
- // We have to copy 1 row at a time to avoid writing pad bytes.
- const int8* src = static_cast<const int8*>(buffer.address());
- for (GLint yy = 0; yy < num_rows; ++yy) {
- memcpy(rows_dst, src, unpadded_row_size);
- rows_dst += padded_row_size;
- src += padded_row_size;
- }
- if (!pack_reverse_row_order_) {
- dest = rows_dst;
- }
- }
- // If it was not marked as successful exit.
- if (*result == 0) {
+ if (*result != GL_NO_ERROR) {
+ SetGLError(*result, "glReadPixels", "Service-side error.");
return;
}
+
+ // when doing a y-flip we have to iterate through top-to-bottom chunks
+ // of the dst. The service side handles reversing the rows within a
+ // chunk.
+ int8* rows_dst;
+ if (pack_reverse_row_order_) {
+ rows_dst = dest + (height - num_rows) * padded_row_size;
+ } else {
+ rows_dst = dest;
+ }
+ // We have to copy 1 row at a time to avoid writing pad bytes.
+ const int8* src = static_cast<const int8*>(buffer.address());
+ for (GLint yy = 0; yy < num_rows; ++yy) {
+ memcpy(rows_dst, src, unpadded_row_size);
+ rows_dst += padded_row_size;
+ src += padded_row_size;
+ }
+ if (!pack_reverse_row_order_) {
+ dest = rows_dst;
+ }
+
yoffset += num_rows;
height -= num_rows;
}
@@ -3676,6 +3685,7 @@ void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) {
GLuint buffer_id;
GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id);
if (!buffer_id) {
+ SetGLError(GL_INVALID_VALUE, "glMapBufferCHROMIUM", "invalid buffer");
return NULL;
}
BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
@@ -3683,6 +3693,17 @@ void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) {
SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer");
return NULL;
}
+
+ if (target == GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM) {
+ DCHECK_EQ(buffer->metadata_size(), sizeof(cmds::ReadPixels::Result));
+ const GLenum error =
+ *(static_cast<cmds::ReadPixels::Result*>(buffer->metadata_address()));
+ if (error != GL_NO_ERROR) {
+ SetGLError(error, "glMapBufferCHROMIUM", "service map buffer error");
+ return NULL;
+ }
+ }
+
if (buffer->mapped()) {
SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped");
return NULL;

Powered by Google App Engine
This is Rietveld 408576698