OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // A class to emulate GLES2 over command buffers. | 5 // A class to emulate GLES2 over command buffers. |
6 | 6 |
7 #include "../client/gles2_implementation.h" | 7 #include "../client/gles2_implementation.h" |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 #include <queue> | 10 #include <queue> |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
533 int32 transfer_buffer_id, | 533 int32 transfer_buffer_id, |
534 bool share_resources, | 534 bool share_resources, |
535 bool bind_generates_resource) | 535 bool bind_generates_resource) |
536 : helper_(helper), | 536 : helper_(helper), |
537 transfer_buffer_( | 537 transfer_buffer_( |
538 kStartingOffset, | 538 kStartingOffset, |
539 transfer_buffer_size - kStartingOffset, | 539 transfer_buffer_size - kStartingOffset, |
540 helper, | 540 helper, |
541 static_cast<char*>(transfer_buffer) + kStartingOffset), | 541 static_cast<char*>(transfer_buffer) + kStartingOffset), |
542 transfer_buffer_id_(transfer_buffer_id), | 542 transfer_buffer_id_(transfer_buffer_id), |
543 angle_pack_reverse_row_order_status(kUnknownExtensionStatus), | |
543 pack_alignment_(4), | 544 pack_alignment_(4), |
544 unpack_alignment_(4), | 545 unpack_alignment_(4), |
545 unpack_flip_y_(false), | 546 unpack_flip_y_(false), |
547 pack_reverse_row_order_(false), | |
546 active_texture_unit_(0), | 548 active_texture_unit_(0), |
547 bound_framebuffer_(0), | 549 bound_framebuffer_(0), |
548 bound_renderbuffer_(0), | 550 bound_renderbuffer_(0), |
549 bound_array_buffer_id_(0), | 551 bound_array_buffer_id_(0), |
550 bound_element_array_buffer_id_(0), | 552 bound_element_array_buffer_id_(0), |
551 client_side_array_id_(0), | 553 client_side_array_id_(0), |
552 client_side_element_array_id_(0), | 554 client_side_element_array_id_(0), |
553 error_bits_(0), | 555 error_bits_(0), |
554 debug_(false), | 556 debug_(false), |
555 sharing_resources_(share_resources), | 557 sharing_resources_(share_resources), |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
641 | 643 |
642 void GLES2Implementation::FreeUnusedSharedMemory() { | 644 void GLES2Implementation::FreeUnusedSharedMemory() { |
643 mapped_memory_->FreeUnused(); | 645 mapped_memory_->FreeUnused(); |
644 } | 646 } |
645 | 647 |
646 void GLES2Implementation::WaitForCmd() { | 648 void GLES2Implementation::WaitForCmd() { |
647 TRACE_EVENT0("gpu", "GLES2::WaitForCmd"); | 649 TRACE_EVENT0("gpu", "GLES2::WaitForCmd"); |
648 helper_->CommandBufferHelper::Finish(); | 650 helper_->CommandBufferHelper::Finish(); |
649 } | 651 } |
650 | 652 |
653 namespace { | |
654 bool IsExtensionAvailable(GLES2Implementation* gles2, const char ext[]) { | |
655 const char* extensions = reinterpret_cast<const char*>( | |
656 gles2->GetString(GL_EXTENSIONS)); | |
657 int length = strlen(ext); | |
658 while (true) { | |
659 int n = strcspn(extensions, " "); | |
660 if (n == length && 0 == strncmp(ext, extensions, length)) { | |
661 return true; | |
662 } | |
663 if ('\0' == extensions[n]) { | |
664 return false; | |
665 } | |
666 extensions += n+1; | |
667 } | |
668 } | |
669 } | |
670 | |
671 bool GLES2Implementation::IsAnglePackReverseRowOrderAvailable() { | |
672 switch (angle_pack_reverse_row_order_status) { | |
673 case kAvailableExtensionStatus: | |
674 return true; | |
675 case kUnavailableExtensionStatus: | |
676 return false; | |
677 default: | |
678 if (IsExtensionAvailable(this, "GL_ANGLE_pack_reverse_row_order")) { | |
679 angle_pack_reverse_row_order_status = kAvailableExtensionStatus; | |
680 return true; | |
681 } else { | |
682 angle_pack_reverse_row_order_status = kUnavailableExtensionStatus; | |
683 return false; | |
684 } | |
685 } | |
686 } | |
687 | |
651 GLenum GLES2Implementation::GetError() { | 688 GLenum GLES2Implementation::GetError() { |
652 GPU_CLIENT_LOG("[" << this << "] glGetError()"); | 689 GPU_CLIENT_LOG("[" << this << "] glGetError()"); |
653 GLenum err = GetGLError(); | 690 GLenum err = GetGLError(); |
654 GPU_CLIENT_LOG("returned " << GLES2Util::GetStringError(err)); | 691 GPU_CLIENT_LOG("returned " << GLES2Util::GetStringError(err)); |
655 return err; | 692 return err; |
656 } | 693 } |
657 | 694 |
658 GLenum GLES2Implementation::GetGLError() { | 695 GLenum GLES2Implementation::GetGLError() { |
659 TRACE_EVENT0("gpu", "GLES2::GetGLError"); | 696 TRACE_EVENT0("gpu", "GLES2::GetGLError"); |
660 // Check the GL error first, then our wrapped error. | 697 // Check the GL error first, then our wrapped error. |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1214 switch (pname) { | 1251 switch (pname) { |
1215 case GL_PACK_ALIGNMENT: | 1252 case GL_PACK_ALIGNMENT: |
1216 pack_alignment_ = param; | 1253 pack_alignment_ = param; |
1217 break; | 1254 break; |
1218 case GL_UNPACK_ALIGNMENT: | 1255 case GL_UNPACK_ALIGNMENT: |
1219 unpack_alignment_ = param; | 1256 unpack_alignment_ = param; |
1220 break; | 1257 break; |
1221 case GL_UNPACK_FLIP_Y_CHROMIUM: | 1258 case GL_UNPACK_FLIP_Y_CHROMIUM: |
1222 unpack_flip_y_ = (param != 0); | 1259 unpack_flip_y_ = (param != 0); |
1223 return; | 1260 return; |
1261 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: | |
1262 pack_reverse_row_order_ = | |
1263 IsAnglePackReverseRowOrderAvailable() ? (param != 0) : false; | |
1264 break; | |
1224 default: | 1265 default: |
1225 break; | 1266 break; |
1226 } | 1267 } |
1227 helper_->PixelStorei(pname, param); | 1268 helper_->PixelStorei(pname, param); |
1228 } | 1269 } |
1229 | 1270 |
1230 | 1271 |
1231 void GLES2Implementation::VertexAttribPointer( | 1272 void GLES2Implementation::VertexAttribPointer( |
1232 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, | 1273 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, |
1233 const void* ptr) { | 1274 const void* ptr) { |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1968 GLsizeiptr part_size = | 2009 GLsizeiptr part_size = |
1969 unpadded_row_size + padded_row_size * (num_rows - 1); | 2010 unpadded_row_size + padded_row_size * (num_rows - 1); |
1970 void* buffer = transfer_buffer_.Alloc(part_size); | 2011 void* buffer = transfer_buffer_.Alloc(part_size); |
1971 *result = 0; // mark as failed. | 2012 *result = 0; // mark as failed. |
1972 helper_->ReadPixels( | 2013 helper_->ReadPixels( |
1973 xoffset, yoffset, width, num_rows, format, type, | 2014 xoffset, yoffset, width, num_rows, format, type, |
1974 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer), | 2015 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer), |
1975 result_shm_id(), result_shm_offset()); | 2016 result_shm_id(), result_shm_offset()); |
1976 WaitForCmd(); | 2017 WaitForCmd(); |
1977 if (*result != 0) { | 2018 if (*result != 0) { |
2019 // when doing a y-flip we have to iterate through top-to-bottom chunks | |
2020 // of the dst. The service side handles reversing the rows within a | |
2021 // chunk. | |
2022 int8* rows_dst; | |
2023 if (pack_reverse_row_order_) { | |
2024 rows_dst = dest + (height - num_rows) * padded_row_size; | |
2025 } else { | |
2026 rows_dst = dest; | |
2027 } | |
1978 // We have to copy 1 row at a time to avoid writing pad bytes. | 2028 // We have to copy 1 row at a time to avoid writing pad bytes. |
1979 const int8* src = static_cast<const int8*>(buffer); | 2029 const int8* src = static_cast<const int8*>(buffer); |
1980 for (GLint yy = 0; yy < num_rows; ++yy) { | 2030 for (GLint yy = 0; yy < num_rows; ++yy) { |
1981 memcpy(dest, src, unpadded_row_size); | 2031 memcpy(rows_dst, src, unpadded_row_size); |
1982 dest += padded_row_size; | 2032 rows_dst += padded_row_size; |
1983 src += padded_row_size; | 2033 src += padded_row_size; |
1984 } | 2034 } |
2035 if (!pack_reverse_row_order_) { | |
2036 dest = rows_dst; | |
2037 } | |
1985 } | 2038 } |
1986 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); | 2039 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); |
1987 // If it was not marked as successful exit. | 2040 // If it was not marked as successful exit. |
1988 if (*result == 0) { | 2041 if (*result == 0) { |
1989 return; | 2042 return; |
1990 } | 2043 } |
1991 yoffset += num_rows; | 2044 yoffset += num_rows; |
1992 height -= num_rows; | 2045 height -= num_rows; |
1993 } | 2046 } |
1994 } else { | 2047 } else { |
1995 // Transfer by sub rows. Because GL has no maximum texture dimensions. | 2048 // Transfer by sub rows. Because GL has no maximum texture dimensions. |
1996 GLES2Util::ComputeImageDataSize( | 2049 GLES2Util::ComputeImageDataSize( |
1997 1, 1, format, type, pack_alignment_, &temp_size); | 2050 1, 1, format, type, pack_alignment_, &temp_size); |
1998 GLsizeiptr element_size = temp_size; | 2051 GLsizeiptr element_size = temp_size; |
1999 max_size -= max_size % element_size; | 2052 max_size -= max_size % element_size; |
2000 GLint max_sub_row_pixels = max_size / element_size; | 2053 GLint max_sub_row_pixels = max_size / element_size; |
2054 if (pack_reverse_row_order_) { | |
2055 // start at the last row when flipping y. | |
2056 dest = dest + (height - 1) * padded_row_size; | |
2057 } | |
2001 for (; height; --height) { | 2058 for (; height; --height) { |
2002 GLint temp_width = width; | 2059 GLint temp_width = width; |
2003 GLint temp_xoffset = xoffset; | 2060 GLint temp_xoffset = xoffset; |
2004 int8* row_dest = dest; | 2061 int8* row_dest = dest; |
2005 while (temp_width) { | 2062 while (temp_width) { |
2006 GLint num_pixels = std::min(width, max_sub_row_pixels); | 2063 GLint num_pixels = std::min(width, max_sub_row_pixels); |
2007 GLsizeiptr part_size = num_pixels * element_size; | 2064 GLsizeiptr part_size = num_pixels * element_size; |
2008 void* buffer = transfer_buffer_.Alloc(part_size); | 2065 void* buffer = transfer_buffer_.Alloc(part_size); |
2009 *result = 0; // mark as failed. | 2066 *result = 0; // mark as failed. |
2010 helper_->ReadPixels( | 2067 helper_->ReadPixels( |
2011 temp_xoffset, yoffset, temp_width, 1, format, type, | 2068 temp_xoffset, yoffset, temp_width, 1, format, type, |
2012 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer), | 2069 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer), |
2013 result_shm_id(), result_shm_offset()); | 2070 result_shm_id(), result_shm_offset()); |
2014 WaitForCmd(); | 2071 WaitForCmd(); |
2015 if (*result != 0) { | 2072 if (*result != 0) { |
2016 memcpy(row_dest, buffer, part_size); | 2073 memcpy(row_dest, buffer, part_size); |
2017 } | 2074 } |
2018 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); | 2075 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); |
2019 // If it was not marked as successful exit. | 2076 // If it was not marked as successful exit. |
2020 if (*result == 0) { | 2077 if (*result == 0) { |
2021 return; | 2078 return; |
2022 } | 2079 } |
2023 row_dest += part_size; | 2080 row_dest += part_size; |
2024 temp_xoffset += num_pixels; | 2081 temp_xoffset += num_pixels; |
2025 temp_width -= num_pixels; | 2082 temp_width -= num_pixels; |
2026 } | 2083 } |
2027 ++yoffset; | 2084 ++yoffset; |
2028 dest += padded_row_size; | 2085 dest += pack_reverse_row_order_ ? -padded_row_size : padded_row_size; |
2029 } | 2086 } |
2030 } | 2087 } |
2031 } | 2088 } |
2032 | 2089 |
2033 void GLES2Implementation::ActiveTexture(GLenum texture) { | 2090 void GLES2Implementation::ActiveTexture(GLenum texture) { |
2034 GPU_CLIENT_LOG("[" << this << "] glActiveTexture(" | 2091 GPU_CLIENT_LOG("[" << this << "] glActiveTexture(" |
2035 << GLES2Util::GetStringEnum(texture) << ")"); | 2092 << GLES2Util::GetStringEnum(texture) << ")"); |
2036 GLuint texture_index = texture - GL_TEXTURE0; | 2093 GLuint texture_index = texture - GL_TEXTURE0; |
2037 if (texture_index >= | 2094 if (texture_index >= |
2038 static_cast<GLuint>(gl_state_.max_combined_texture_image_units)) { | 2095 static_cast<GLuint>(gl_state_.max_combined_texture_image_units)) { |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2513 GPU_CLIENT_LOG(" returned " << result); | 2570 GPU_CLIENT_LOG(" returned " << result); |
2514 return reinterpret_cast<const GLchar*>(result); | 2571 return reinterpret_cast<const GLchar*>(result); |
2515 } | 2572 } |
2516 | 2573 |
2517 void GLES2Implementation::RequestExtensionCHROMIUM(const char* extension) { | 2574 void GLES2Implementation::RequestExtensionCHROMIUM(const char* extension) { |
2518 GPU_CLIENT_LOG("[" << this << "] glRequestExtensionCHROMIUM(" | 2575 GPU_CLIENT_LOG("[" << this << "] glRequestExtensionCHROMIUM(" |
2519 << extension << ")"); | 2576 << extension << ")"); |
2520 SetBucketAsCString(kResultBucketId, extension); | 2577 SetBucketAsCString(kResultBucketId, extension); |
2521 helper_->RequestExtensionCHROMIUM(kResultBucketId); | 2578 helper_->RequestExtensionCHROMIUM(kResultBucketId); |
2522 helper_->SetBucketSize(kResultBucketId, 0); | 2579 helper_->SetBucketSize(kResultBucketId, 0); |
2580 if (kUnavailableExtensionStatus == angle_pack_reverse_row_order_status && | |
2581 !strcmp(extension, "GL_ANGLE_pack_reverse_row_order")) { | |
2582 angle_pack_reverse_row_order_status = kUnknownExtensionStatus; | |
bsalomon
2011/11/28 14:00:40
I wasn't too sure about this.
| |
2583 } | |
2523 } | 2584 } |
2524 | 2585 |
2525 void GLES2Implementation::RateLimitOffscreenContextCHROMIUM() { | 2586 void GLES2Implementation::RateLimitOffscreenContextCHROMIUM() { |
2526 GPU_CLIENT_LOG("[" << this << "] glRateLimitOffscreenCHROMIUM()"); | 2587 GPU_CLIENT_LOG("[" << this << "] glRateLimitOffscreenCHROMIUM()"); |
2527 // Wait if this would add too many rate limit tokens. | 2588 // Wait if this would add too many rate limit tokens. |
2528 if (rate_limit_tokens_.size() == kMaxSwapBuffers) { | 2589 if (rate_limit_tokens_.size() == kMaxSwapBuffers) { |
2529 helper_->WaitForToken(rate_limit_tokens_.front()); | 2590 helper_->WaitForToken(rate_limit_tokens_.front()); |
2530 rate_limit_tokens_.pop(); | 2591 rate_limit_tokens_.pop(); |
2531 } | 2592 } |
2532 rate_limit_tokens_.push(helper_->InsertToken()); | 2593 rate_limit_tokens_.push(helper_->InsertToken()); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2660 helper_->PostSubBufferCHROMIUM(x, y, width, height); | 2721 helper_->PostSubBufferCHROMIUM(x, y, width, height); |
2661 helper_->CommandBufferHelper::Flush(); | 2722 helper_->CommandBufferHelper::Flush(); |
2662 if (swap_buffers_tokens_.size() > kMaxSwapBuffers + 1) { | 2723 if (swap_buffers_tokens_.size() > kMaxSwapBuffers + 1) { |
2663 helper_->WaitForToken(swap_buffers_tokens_.front()); | 2724 helper_->WaitForToken(swap_buffers_tokens_.front()); |
2664 swap_buffers_tokens_.pop(); | 2725 swap_buffers_tokens_.pop(); |
2665 } | 2726 } |
2666 } | 2727 } |
2667 | 2728 |
2668 } // namespace gles2 | 2729 } // namespace gles2 |
2669 } // namespace gpu | 2730 } // namespace gpu |
OLD | NEW |