Chromium Code Reviews| Index: gpu/command_buffer/client/gles2_implementation.cc |
| =================================================================== |
| --- gpu/command_buffer/client/gles2_implementation.cc (revision 110991) |
| +++ gpu/command_buffer/client/gles2_implementation.cc (working copy) |
| @@ -540,9 +540,11 @@ |
| helper, |
| static_cast<char*>(transfer_buffer) + kStartingOffset), |
| transfer_buffer_id_(transfer_buffer_id), |
| + angle_pack_reverse_row_order_status(kUnknownExtensionStatus), |
| pack_alignment_(4), |
| unpack_alignment_(4), |
| unpack_flip_y_(false), |
| + pack_reverse_row_order_(false), |
| active_texture_unit_(0), |
| bound_framebuffer_(0), |
| bound_renderbuffer_(0), |
| @@ -648,6 +650,41 @@ |
| helper_->CommandBufferHelper::Finish(); |
| } |
| +namespace { |
| +bool IsExtensionAvailable(GLES2Implementation* gles2, const char ext[]) { |
| + const char* extensions = reinterpret_cast<const char*>( |
| + gles2->GetString(GL_EXTENSIONS)); |
| + int length = strlen(ext); |
| + while (true) { |
| + int n = strcspn(extensions, " "); |
| + if (n == length && 0 == strncmp(ext, extensions, length)) { |
| + return true; |
| + } |
| + if ('\0' == extensions[n]) { |
| + return false; |
| + } |
| + extensions += n+1; |
| + } |
| +} |
| +} |
| + |
| +bool GLES2Implementation::IsAnglePackReverseRowOrderAvailable() { |
| + switch (angle_pack_reverse_row_order_status) { |
| + case kAvailableExtensionStatus: |
| + return true; |
| + case kUnavailableExtensionStatus: |
| + return false; |
| + default: |
| + if (IsExtensionAvailable(this, "GL_ANGLE_pack_reverse_row_order")) { |
| + angle_pack_reverse_row_order_status = kAvailableExtensionStatus; |
| + return true; |
| + } else { |
| + angle_pack_reverse_row_order_status = kUnavailableExtensionStatus; |
| + return false; |
| + } |
| + } |
| +} |
| + |
| GLenum GLES2Implementation::GetError() { |
| GPU_CLIENT_LOG("[" << this << "] glGetError()"); |
| GLenum err = GetGLError(); |
| @@ -1221,6 +1258,10 @@ |
| case GL_UNPACK_FLIP_Y_CHROMIUM: |
| unpack_flip_y_ = (param != 0); |
| return; |
| + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: |
| + pack_reverse_row_order_ = |
| + IsAnglePackReverseRowOrderAvailable() ? (param != 0) : false; |
| + break; |
| default: |
| break; |
| } |
| @@ -1975,13 +2016,25 @@ |
| result_shm_id(), result_shm_offset()); |
| 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); |
| for (GLint yy = 0; yy < num_rows; ++yy) { |
| - memcpy(dest, src, unpadded_row_size); |
| - dest += padded_row_size; |
| + memcpy(rows_dst, src, unpadded_row_size); |
| + rows_dst += padded_row_size; |
| src += padded_row_size; |
| } |
| + if (!pack_reverse_row_order_) { |
| + dest = rows_dst; |
| + } |
| } |
| transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); |
| // If it was not marked as successful exit. |
| @@ -1998,6 +2051,10 @@ |
| GLsizeiptr element_size = temp_size; |
| max_size -= max_size % element_size; |
| GLint max_sub_row_pixels = max_size / element_size; |
| + if (pack_reverse_row_order_) { |
| + // start at the last row when flipping y. |
| + dest = dest + (height - 1) * padded_row_size; |
| + } |
| for (; height; --height) { |
| GLint temp_width = width; |
| GLint temp_xoffset = xoffset; |
| @@ -2025,7 +2082,7 @@ |
| temp_width -= num_pixels; |
| } |
| ++yoffset; |
| - dest += padded_row_size; |
| + dest += pack_reverse_row_order_ ? -padded_row_size : padded_row_size; |
| } |
| } |
| } |
| @@ -2520,6 +2577,10 @@ |
| SetBucketAsCString(kResultBucketId, extension); |
| helper_->RequestExtensionCHROMIUM(kResultBucketId); |
| helper_->SetBucketSize(kResultBucketId, 0); |
| + if (kUnavailableExtensionStatus == angle_pack_reverse_row_order_status && |
| + !strcmp(extension, "GL_ANGLE_pack_reverse_row_order")) { |
| + angle_pack_reverse_row_order_status = kUnknownExtensionStatus; |
|
bsalomon
2011/11/28 14:00:40
I wasn't too sure about this.
|
| + } |
| } |
| void GLES2Implementation::RateLimitOffscreenContextCHROMIUM() { |