OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
11 #include <queue> | 11 #include <queue> |
12 #include <set> | 12 #include <set> |
13 #include <limits> | 13 #include <limits> |
14 #include <stdio.h> | 14 #include <stdio.h> |
15 #include <string.h> | 15 #include <string.h> |
16 #include <GLES2/gl2ext.h> | 16 #include <GLES2/gl2ext.h> |
| 17 #include "../client/buffer_tracker.h" |
17 #include "../client/mapped_memory.h" | 18 #include "../client/mapped_memory.h" |
18 #include "../client/program_info_manager.h" | 19 #include "../client/program_info_manager.h" |
19 #include "../client/query_tracker.h" | 20 #include "../client/query_tracker.h" |
20 #include "../client/transfer_buffer.h" | 21 #include "../client/transfer_buffer.h" |
21 #include "../common/gles2_cmd_utils.h" | 22 #include "../common/gles2_cmd_utils.h" |
22 #include "../common/trace_event.h" | 23 #include "../common/trace_event.h" |
23 | 24 |
24 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 25 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
25 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS | 26 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS |
26 #endif | 27 #endif |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 unpack_flip_y_(false), | 433 unpack_flip_y_(false), |
433 unpack_row_length_(0), | 434 unpack_row_length_(0), |
434 unpack_skip_rows_(0), | 435 unpack_skip_rows_(0), |
435 unpack_skip_pixels_(0), | 436 unpack_skip_pixels_(0), |
436 pack_reverse_row_order_(false), | 437 pack_reverse_row_order_(false), |
437 active_texture_unit_(0), | 438 active_texture_unit_(0), |
438 bound_framebuffer_(0), | 439 bound_framebuffer_(0), |
439 bound_renderbuffer_(0), | 440 bound_renderbuffer_(0), |
440 bound_array_buffer_id_(0), | 441 bound_array_buffer_id_(0), |
441 bound_element_array_buffer_id_(0), | 442 bound_element_array_buffer_id_(0), |
| 443 bound_pixel_unpack_transfer_buffer_id_(0), |
442 client_side_array_id_(0), | 444 client_side_array_id_(0), |
443 client_side_element_array_id_(0), | 445 client_side_element_array_id_(0), |
444 bound_vertex_array_id_(0), | 446 bound_vertex_array_id_(0), |
445 error_bits_(0), | 447 error_bits_(0), |
446 debug_(false), | 448 debug_(false), |
447 use_count_(0), | 449 use_count_(0), |
448 current_query_(NULL), | 450 current_query_(NULL), |
449 error_message_callback_(NULL) { | 451 error_message_callback_(NULL) { |
450 GPU_DCHECK(helper); | 452 GPU_DCHECK(helper); |
451 GPU_DCHECK(transfer_buffer); | 453 GPU_DCHECK(transfer_buffer); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 | 510 |
509 util_.set_num_compressed_texture_formats( | 511 util_.set_num_compressed_texture_formats( |
510 gl_state_.int_state.num_compressed_texture_formats); | 512 gl_state_.int_state.num_compressed_texture_formats); |
511 util_.set_num_shader_binary_formats( | 513 util_.set_num_shader_binary_formats( |
512 gl_state_.int_state.num_shader_binary_formats); | 514 gl_state_.int_state.num_shader_binary_formats); |
513 | 515 |
514 texture_units_.reset( | 516 texture_units_.reset( |
515 new TextureUnit[gl_state_.int_state.max_combined_texture_image_units]); | 517 new TextureUnit[gl_state_.int_state.max_combined_texture_image_units]); |
516 | 518 |
517 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); | 519 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
| 520 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); |
518 | 521 |
519 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 522 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
520 GetIdHandler(id_namespaces::kBuffers)->MakeIds( | 523 GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
521 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); | 524 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); |
522 | 525 |
523 client_side_buffer_helper_.reset(new ClientSideBufferHelper( | 526 client_side_buffer_helper_.reset(new ClientSideBufferHelper( |
524 gl_state_.int_state.max_vertex_attribs, | 527 gl_state_.int_state.max_vertex_attribs, |
525 reserved_ids_[0], | 528 reserved_ids_[0], |
526 reserved_ids_[1])); | 529 reserved_ids_[1])); |
527 #endif | 530 #endif |
528 | 531 |
529 return true; | 532 return true; |
530 } | 533 } |
531 | 534 |
532 GLES2Implementation::~GLES2Implementation() { | 535 GLES2Implementation::~GLES2Implementation() { |
533 // Make sure the queries are finished otherwise we'll delete the | 536 // Make sure the queries are finished otherwise we'll delete the |
534 // shared memory (mapped_memory_) which will free the memory used | 537 // shared memory (mapped_memory_) which will free the memory used |
535 // by the queries. The GPU process when validating that memory is still | 538 // by the queries. The GPU process when validating that memory is still |
536 // shared will fail and abort (ie, it will stop running). | 539 // shared will fail and abort (ie, it will stop running). |
537 Finish(); | 540 Finish(); |
538 query_tracker_.reset(); | 541 query_tracker_.reset(); |
539 | 542 |
540 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 543 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
541 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); | 544 DeleteBuffers(arraysize(reserved_ids_), &reserved_ids_[0]); |
542 #endif | 545 #endif |
| 546 buffer_tracker_.reset(); |
| 547 |
543 // The share group needs to be able to use a command buffer to talk | 548 // The share group needs to be able to use a command buffer to talk |
544 // to service if it's destroyed so set one for it then release the reference. | 549 // to service if it's destroyed so set one for it then release the reference. |
545 // If it's destroyed it will use this GLES2Implemenation. | 550 // If it's destroyed it will use this GLES2Implemenation. |
546 share_group_->SetGLES2ImplementationForDestruction(this); | 551 share_group_->SetGLES2ImplementationForDestruction(this); |
547 share_group_ = NULL; | 552 share_group_ = NULL; |
548 // Make sure the commands make it the service. | 553 // Make sure the commands make it the service. |
549 Finish(); | 554 Finish(); |
550 } | 555 } |
551 | 556 |
552 GLES2CmdHelper* GLES2Implementation::helper() const { | 557 GLES2CmdHelper* GLES2Implementation::helper() const { |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 *params = bound_array_buffer_id_; | 958 *params = bound_array_buffer_id_; |
954 return true; | 959 return true; |
955 } | 960 } |
956 return false; | 961 return false; |
957 case GL_ELEMENT_ARRAY_BUFFER_BINDING: | 962 case GL_ELEMENT_ARRAY_BUFFER_BINDING: |
958 if (share_group_->bind_generates_resource()) { | 963 if (share_group_->bind_generates_resource()) { |
959 *params = bound_element_array_buffer_id_; | 964 *params = bound_element_array_buffer_id_; |
960 return true; | 965 return true; |
961 } | 966 } |
962 return false; | 967 return false; |
| 968 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: |
| 969 *params = bound_pixel_unpack_transfer_buffer_id_; |
| 970 return true; |
963 case GL_ACTIVE_TEXTURE: | 971 case GL_ACTIVE_TEXTURE: |
964 *params = active_texture_unit_ + GL_TEXTURE0; | 972 *params = active_texture_unit_ + GL_TEXTURE0; |
965 return true; | 973 return true; |
966 case GL_TEXTURE_BINDING_2D: | 974 case GL_TEXTURE_BINDING_2D: |
967 if (share_group_->bind_generates_resource()) { | 975 if (share_group_->bind_generates_resource()) { |
968 *params = texture_units_[active_texture_unit_].bound_texture_2d; | 976 *params = texture_units_[active_texture_unit_].bound_texture_2d; |
969 return true; | 977 return true; |
970 } | 978 } |
971 return false; | 979 return false; |
972 case GL_TEXTURE_BINDING_CUBE_MAP: | 980 case GL_TEXTURE_BINDING_CUBE_MAP: |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1605 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { | 1613 GLenum target, GLsizeiptr size, const void* data, GLenum usage) { |
1606 if (size == 0) { | 1614 if (size == 0) { |
1607 return; | 1615 return; |
1608 } | 1616 } |
1609 | 1617 |
1610 if (size < 0) { | 1618 if (size < 0) { |
1611 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); | 1619 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); |
1612 return; | 1620 return; |
1613 } | 1621 } |
1614 | 1622 |
| 1623 if (target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { |
| 1624 GLuint buffer_id = bound_pixel_unpack_transfer_buffer_id_; |
| 1625 if (!buffer_id) { |
| 1626 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); |
| 1627 return; |
| 1628 } |
| 1629 |
| 1630 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| 1631 if (buffer) { |
| 1632 // Free buffer memory, pending the passage of a token. |
| 1633 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
| 1634 |
| 1635 // Remove old buffer. |
| 1636 buffer_tracker_->RemoveBuffer(buffer_id); |
| 1637 } |
| 1638 |
| 1639 // Create new buffer. |
| 1640 buffer = buffer_tracker_->CreateBuffer(buffer_id, size); |
| 1641 GPU_DCHECK(buffer); |
| 1642 if (data) |
| 1643 memcpy(buffer->address(), data, size); |
| 1644 return; |
| 1645 } |
| 1646 |
1615 // If there is no data just send BufferData | 1647 // If there is no data just send BufferData |
1616 if (!data) { | 1648 if (!data) { |
1617 helper_->BufferData(target, size, 0, 0, usage); | 1649 helper_->BufferData(target, size, 0, 0, usage); |
1618 return; | 1650 return; |
1619 } | 1651 } |
1620 | 1652 |
1621 // See if we can send all at once. | 1653 // See if we can send all at once. |
1622 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); | 1654 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
1623 if (!buffer.valid()) { | 1655 if (!buffer.valid()) { |
1624 return; | 1656 return; |
(...skipping 30 matching lines...) Expand all Loading... |
1655 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1687 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
1656 if (size == 0) { | 1688 if (size == 0) { |
1657 return; | 1689 return; |
1658 } | 1690 } |
1659 | 1691 |
1660 if (size < 0) { | 1692 if (size < 0) { |
1661 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "size < 0"); | 1693 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "size < 0"); |
1662 return; | 1694 return; |
1663 } | 1695 } |
1664 | 1696 |
| 1697 if (target == GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { |
| 1698 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| 1699 bound_pixel_unpack_transfer_buffer_id_); |
| 1700 if (!buffer) { |
| 1701 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer"); |
| 1702 return; |
| 1703 } |
| 1704 |
| 1705 int32 end = 0; |
| 1706 int32 buffer_size = buffer->size(); |
| 1707 if (!SafeAddInt32(offset, size, &end) || end > buffer_size) { |
| 1708 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range"); |
| 1709 return; |
| 1710 } |
| 1711 |
| 1712 if (data) |
| 1713 memcpy(static_cast<uint8*>(buffer->address()) + offset, data, size); |
| 1714 return; |
| 1715 } |
| 1716 |
1665 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); | 1717 ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_); |
1666 BufferSubDataHelperImpl(target, offset, size, data, &buffer); | 1718 BufferSubDataHelperImpl(target, offset, size, data, &buffer); |
1667 } | 1719 } |
1668 | 1720 |
1669 void GLES2Implementation::BufferSubDataHelperImpl( | 1721 void GLES2Implementation::BufferSubDataHelperImpl( |
1670 GLenum target, GLintptr offset, GLsizeiptr size, const void* data, | 1722 GLenum target, GLintptr offset, GLsizeiptr size, const void* data, |
1671 ScopedTransferBufferPtr* buffer) { | 1723 ScopedTransferBufferPtr* buffer) { |
1672 GPU_DCHECK(buffer); | 1724 GPU_DCHECK(buffer); |
1673 GPU_DCHECK_GT(size, 0); | 1725 GPU_DCHECK_GT(size, 0); |
1674 | 1726 |
(...skipping 18 matching lines...) Expand all Loading... |
1693 void GLES2Implementation::BufferSubData( | 1745 void GLES2Implementation::BufferSubData( |
1694 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 1746 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
1695 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1747 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
1696 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" | 1748 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData(" |
1697 << GLES2Util::GetStringBufferTarget(target) << ", " | 1749 << GLES2Util::GetStringBufferTarget(target) << ", " |
1698 << offset << ", " << size << ", " | 1750 << offset << ", " << size << ", " |
1699 << static_cast<const void*>(data) << ")"); | 1751 << static_cast<const void*>(data) << ")"); |
1700 BufferSubDataHelper(target, offset, size, data); | 1752 BufferSubDataHelper(target, offset, size, data); |
1701 } | 1753 } |
1702 | 1754 |
| 1755 BufferTracker::Buffer* |
| 1756 GLES2Implementation::GetBoundPixelUnpackTransferBufferIfValid( |
| 1757 const char* function_name, GLuint offset, GLsizei size) |
| 1758 { |
| 1759 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| 1760 bound_pixel_unpack_transfer_buffer_id_); |
| 1761 if (!buffer) { |
| 1762 SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer"); |
| 1763 return NULL; |
| 1764 } |
| 1765 if (buffer->mapped()) { |
| 1766 SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped"); |
| 1767 return NULL; |
| 1768 } |
| 1769 if ((buffer->size() - offset) < static_cast<GLuint>(size)) { |
| 1770 SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large"); |
| 1771 return NULL; |
| 1772 } |
| 1773 return buffer; |
| 1774 } |
| 1775 |
1703 void GLES2Implementation::CompressedTexImage2D( | 1776 void GLES2Implementation::CompressedTexImage2D( |
1704 GLenum target, GLint level, GLenum internalformat, GLsizei width, | 1777 GLenum target, GLint level, GLenum internalformat, GLsizei width, |
1705 GLsizei height, GLint border, GLsizei image_size, const void* data) { | 1778 GLsizei height, GLint border, GLsizei image_size, const void* data) { |
1706 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1779 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
1707 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexImage2D(" | 1780 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexImage2D(" |
1708 << GLES2Util::GetStringTextureTarget(target) << ", " | 1781 << GLES2Util::GetStringTextureTarget(target) << ", " |
1709 << level << ", " | 1782 << level << ", " |
1710 << GLES2Util::GetStringCompressedTextureFormat(internalformat) << ", " | 1783 << GLES2Util::GetStringCompressedTextureFormat(internalformat) << ", " |
1711 << width << ", " << height << ", " << border << ", " | 1784 << width << ", " << height << ", " << border << ", " |
1712 << image_size << ", " | 1785 << image_size << ", " |
1713 << static_cast<const void*>(data) << ")"); | 1786 << static_cast<const void*>(data) << ")"); |
1714 if (width < 0 || height < 0 || level < 0) { | 1787 if (width < 0 || height < 0 || level < 0) { |
1715 SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "dimension < 0"); | 1788 SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "dimension < 0"); |
1716 return; | 1789 return; |
1717 } | 1790 } |
1718 if (height == 0 || width == 0) { | 1791 if (height == 0 || width == 0) { |
1719 return; | 1792 return; |
1720 } | 1793 } |
| 1794 // If there's a pixel unpack buffer bound use it when issuing |
| 1795 // CompressedTexImage2D. |
| 1796 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1797 GLuint offset = ToGLuint(data); |
| 1798 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1799 "glCompressedTexImage2D", offset, image_size); |
| 1800 if (buffer) |
| 1801 helper_->CompressedTexImage2D( |
| 1802 target, level, internalformat, width, height, border, image_size, |
| 1803 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1804 return; |
| 1805 } |
1721 SetBucketContents(kResultBucketId, data, image_size); | 1806 SetBucketContents(kResultBucketId, data, image_size); |
1722 helper_->CompressedTexImage2DBucket( | 1807 helper_->CompressedTexImage2DBucket( |
1723 target, level, internalformat, width, height, border, kResultBucketId); | 1808 target, level, internalformat, width, height, border, kResultBucketId); |
1724 // Free the bucket. This is not required but it does free up the memory. | 1809 // Free the bucket. This is not required but it does free up the memory. |
1725 // and we don't have to wait for the result so from the client's perspective | 1810 // and we don't have to wait for the result so from the client's perspective |
1726 // it's cheap. | 1811 // it's cheap. |
1727 helper_->SetBucketSize(kResultBucketId, 0); | 1812 helper_->SetBucketSize(kResultBucketId, 0); |
1728 } | 1813 } |
1729 | 1814 |
1730 void GLES2Implementation::CompressedTexSubImage2D( | 1815 void GLES2Implementation::CompressedTexSubImage2D( |
1731 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 1816 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
1732 GLsizei height, GLenum format, GLsizei image_size, const void* data) { | 1817 GLsizei height, GLenum format, GLsizei image_size, const void* data) { |
1733 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1818 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
1734 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexSubImage2D(" | 1819 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompressedTexSubImage2D(" |
1735 << GLES2Util::GetStringTextureTarget(target) << ", " | 1820 << GLES2Util::GetStringTextureTarget(target) << ", " |
1736 << level << ", " | 1821 << level << ", " |
1737 << xoffset << ", " << yoffset << ", " | 1822 << xoffset << ", " << yoffset << ", " |
1738 << width << ", " << height << ", " | 1823 << width << ", " << height << ", " |
1739 << GLES2Util::GetStringCompressedTextureFormat(format) << ", " | 1824 << GLES2Util::GetStringCompressedTextureFormat(format) << ", " |
1740 << image_size << ", " | 1825 << image_size << ", " |
1741 << static_cast<const void*>(data) << ")"); | 1826 << static_cast<const void*>(data) << ")"); |
1742 if (width < 0 || height < 0 || level < 0) { | 1827 if (width < 0 || height < 0 || level < 0) { |
1743 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); | 1828 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0"); |
1744 return; | 1829 return; |
1745 } | 1830 } |
| 1831 // If there's a pixel unpack buffer bound use it when issuing |
| 1832 // CompressedTexSubImage2D. |
| 1833 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1834 GLuint offset = ToGLuint(data); |
| 1835 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1836 "glCompressedTexSubImage2D", offset, image_size); |
| 1837 if (buffer) |
| 1838 helper_->CompressedTexSubImage2D( |
| 1839 target, level, xoffset, yoffset, width, height, format, image_size, |
| 1840 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1841 return; |
| 1842 } |
1746 SetBucketContents(kResultBucketId, data, image_size); | 1843 SetBucketContents(kResultBucketId, data, image_size); |
1747 helper_->CompressedTexSubImage2DBucket( | 1844 helper_->CompressedTexSubImage2DBucket( |
1748 target, level, xoffset, yoffset, width, height, format, kResultBucketId); | 1845 target, level, xoffset, yoffset, width, height, format, kResultBucketId); |
1749 // Free the bucket. This is not required but it does free up the memory. | 1846 // Free the bucket. This is not required but it does free up the memory. |
1750 // and we don't have to wait for the result so from the client's perspective | 1847 // and we don't have to wait for the result so from the client's perspective |
1751 // it's cheap. | 1848 // it's cheap. |
1752 helper_->SetBucketSize(kResultBucketId, 0); | 1849 helper_->SetBucketSize(kResultBucketId, 0); |
1753 } | 1850 } |
1754 | 1851 |
1755 namespace { | 1852 namespace { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1807 uint32 size; | 1904 uint32 size; |
1808 uint32 unpadded_row_size; | 1905 uint32 unpadded_row_size; |
1809 uint32 padded_row_size; | 1906 uint32 padded_row_size; |
1810 if (!GLES2Util::ComputeImageDataSizes( | 1907 if (!GLES2Util::ComputeImageDataSizes( |
1811 width, height, format, type, unpack_alignment_, &size, | 1908 width, height, format, type, unpack_alignment_, &size, |
1812 &unpadded_row_size, &padded_row_size)) { | 1909 &unpadded_row_size, &padded_row_size)) { |
1813 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); | 1910 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "image size too large"); |
1814 return; | 1911 return; |
1815 } | 1912 } |
1816 | 1913 |
| 1914 // If there's a pixel unpack buffer bound use it when issuing TexImage2D. |
| 1915 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 1916 GLuint offset = ToGLuint(pixels); |
| 1917 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 1918 "glTexImage2D", offset, size); |
| 1919 if (buffer) |
| 1920 helper_->TexImage2D( |
| 1921 target, level, internalformat, width, height, border, format, type, |
| 1922 buffer->shm_id(), buffer->shm_offset() + offset); |
| 1923 return; |
| 1924 } |
| 1925 |
1817 // If there's no data just issue TexImage2D | 1926 // If there's no data just issue TexImage2D |
1818 if (!pixels) { | 1927 if (!pixels) { |
1819 helper_->TexImage2D( | 1928 helper_->TexImage2D( |
1820 target, level, internalformat, width, height, border, format, type, | 1929 target, level, internalformat, width, height, border, format, type, |
1821 0, 0); | 1930 0, 0); |
1822 return; | 1931 return; |
1823 } | 1932 } |
1824 | 1933 |
1825 // compute the advance bytes per row for the src pixels | 1934 // compute the advance bytes per row for the src pixels |
1826 uint32 src_padded_row_size; | 1935 uint32 src_padded_row_size; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 uint32 temp_size; | 2003 uint32 temp_size; |
1895 uint32 unpadded_row_size; | 2004 uint32 unpadded_row_size; |
1896 uint32 padded_row_size; | 2005 uint32 padded_row_size; |
1897 if (!GLES2Util::ComputeImageDataSizes( | 2006 if (!GLES2Util::ComputeImageDataSizes( |
1898 width, height, format, type, unpack_alignment_, &temp_size, | 2007 width, height, format, type, unpack_alignment_, &temp_size, |
1899 &unpadded_row_size, &padded_row_size)) { | 2008 &unpadded_row_size, &padded_row_size)) { |
1900 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); | 2009 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "size to large"); |
1901 return; | 2010 return; |
1902 } | 2011 } |
1903 | 2012 |
| 2013 // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D. |
| 2014 if (bound_pixel_unpack_transfer_buffer_id_) { |
| 2015 GLuint offset = ToGLuint(pixels); |
| 2016 BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid( |
| 2017 "glTexSubImage2D", offset, temp_size); |
| 2018 if (buffer) |
| 2019 helper_->TexSubImage2D( |
| 2020 target, level, xoffset, yoffset, width, height, format, type, |
| 2021 buffer->shm_id(), buffer->shm_offset() + offset, false); |
| 2022 return; |
| 2023 } |
| 2024 |
1904 // compute the advance bytes per row for the src pixels | 2025 // compute the advance bytes per row for the src pixels |
1905 uint32 src_padded_row_size; | 2026 uint32 src_padded_row_size; |
1906 if (unpack_row_length_ > 0) { | 2027 if (unpack_row_length_ > 0) { |
1907 if (!GLES2Util::ComputeImagePaddedRowSize( | 2028 if (!GLES2Util::ComputeImagePaddedRowSize( |
1908 unpack_row_length_, format, type, unpack_alignment_, | 2029 unpack_row_length_, format, type, unpack_alignment_, |
1909 &src_padded_row_size)) { | 2030 &src_padded_row_size)) { |
1910 SetGLError( | 2031 SetGLError( |
1911 GL_INVALID_VALUE, "glTexImage2D", "unpack row length too large"); | 2032 GL_INVALID_VALUE, "glTexImage2D", "unpack row length too large"); |
1912 return; | 2033 return; |
1913 } | 2034 } |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2410 void GLES2Implementation::BindBufferHelper( | 2531 void GLES2Implementation::BindBufferHelper( |
2411 GLenum target, GLuint buffer) { | 2532 GLenum target, GLuint buffer) { |
2412 // TODO(gman): See note #1 above. | 2533 // TODO(gman): See note #1 above. |
2413 switch (target) { | 2534 switch (target) { |
2414 case GL_ARRAY_BUFFER: | 2535 case GL_ARRAY_BUFFER: |
2415 bound_array_buffer_id_ = buffer; | 2536 bound_array_buffer_id_ = buffer; |
2416 break; | 2537 break; |
2417 case GL_ELEMENT_ARRAY_BUFFER: | 2538 case GL_ELEMENT_ARRAY_BUFFER: |
2418 bound_element_array_buffer_id_ = buffer; | 2539 bound_element_array_buffer_id_ = buffer; |
2419 break; | 2540 break; |
| 2541 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| 2542 bound_pixel_unpack_transfer_buffer_id_ = buffer; |
| 2543 break; |
2420 default: | 2544 default: |
2421 break; | 2545 break; |
2422 } | 2546 } |
2423 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2547 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
2424 // used even though it's marked it as used here. | 2548 // used even though it's marked it as used here. |
2425 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); | 2549 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); |
2426 } | 2550 } |
2427 | 2551 |
2428 void GLES2Implementation::BindFramebufferHelper( | 2552 void GLES2Implementation::BindFramebufferHelper( |
2429 GLenum target, GLuint framebuffer) { | 2553 GLenum target, GLuint framebuffer) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2504 "glDeleteBuffers", "id not created by this context."); | 2628 "glDeleteBuffers", "id not created by this context."); |
2505 return; | 2629 return; |
2506 } | 2630 } |
2507 for (GLsizei ii = 0; ii < n; ++ii) { | 2631 for (GLsizei ii = 0; ii < n; ++ii) { |
2508 if (buffers[ii] == bound_array_buffer_id_) { | 2632 if (buffers[ii] == bound_array_buffer_id_) { |
2509 bound_array_buffer_id_ = 0; | 2633 bound_array_buffer_id_ = 0; |
2510 } | 2634 } |
2511 if (buffers[ii] == bound_element_array_buffer_id_) { | 2635 if (buffers[ii] == bound_element_array_buffer_id_) { |
2512 bound_element_array_buffer_id_ = 0; | 2636 bound_element_array_buffer_id_ = 0; |
2513 } | 2637 } |
| 2638 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { |
| 2639 bound_pixel_unpack_transfer_buffer_id_ = 0; |
| 2640 } |
| 2641 |
| 2642 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); |
| 2643 if (buffer) { |
| 2644 // Free buffer memory, pending the passage of a token. |
| 2645 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
| 2646 // Remove buffer. |
| 2647 buffer_tracker_->RemoveBuffer(buffers[ii]); |
| 2648 } |
2514 } | 2649 } |
2515 } | 2650 } |
2516 | 2651 |
2517 void GLES2Implementation::DeleteBuffersStub( | 2652 void GLES2Implementation::DeleteBuffersStub( |
2518 GLsizei n, const GLuint* buffers) { | 2653 GLsizei n, const GLuint* buffers) { |
2519 helper_->DeleteBuffersImmediate(n, buffers); | 2654 helper_->DeleteBuffersImmediate(n, buffers); |
2520 } | 2655 } |
2521 | 2656 |
2522 | 2657 |
2523 void GLES2Implementation::DeleteFramebuffersHelper( | 2658 void GLES2Implementation::DeleteFramebuffersHelper( |
(...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3473 void GLES2Implementation::TraceBeginCHROMIUM(const char* name) { | 3608 void GLES2Implementation::TraceBeginCHROMIUM(const char* name) { |
3474 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3609 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
3475 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTraceBeginCHROMIUM(" | 3610 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTraceBeginCHROMIUM(" |
3476 << name << ")"); | 3611 << name << ")"); |
3477 | 3612 |
3478 SetBucketAsCString(kResultBucketId, name); | 3613 SetBucketAsCString(kResultBucketId, name); |
3479 helper_->TraceBeginCHROMIUM(kResultBucketId); | 3614 helper_->TraceBeginCHROMIUM(kResultBucketId); |
3480 helper_->SetBucketSize(kResultBucketId, 0); | 3615 helper_->SetBucketSize(kResultBucketId, 0); |
3481 } | 3616 } |
3482 | 3617 |
| 3618 void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { |
| 3619 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3620 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferCHROMIUM(" |
| 3621 << target << ", " << GLES2Util::GetStringEnum(access) << ")"); |
| 3622 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { |
| 3623 SetGLError( |
| 3624 GL_INVALID_ENUM, "glMapBufferCHROMIUM", "invalid target"); |
| 3625 return NULL; |
| 3626 } |
| 3627 if (access != GL_WRITE_ONLY) { |
| 3628 SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode"); |
| 3629 return NULL; |
| 3630 } |
| 3631 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| 3632 bound_pixel_unpack_transfer_buffer_id_); |
| 3633 if (!buffer) { |
| 3634 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); |
| 3635 return NULL; |
| 3636 } |
| 3637 if (buffer->mapped()) { |
| 3638 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped"); |
| 3639 return NULL; |
| 3640 } |
| 3641 buffer->set_mapped(true); |
| 3642 |
| 3643 GPU_DCHECK(buffer->address()); |
| 3644 GPU_CLIENT_LOG(" returned " << buffer->address()); |
| 3645 return buffer->address(); |
| 3646 } |
| 3647 |
| 3648 GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
| 3649 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3650 GPU_CLIENT_LOG( |
| 3651 "[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target << ")"); |
| 3652 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) { |
| 3653 SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target"); |
| 3654 return false; |
| 3655 } |
| 3656 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer( |
| 3657 bound_pixel_unpack_transfer_buffer_id_); |
| 3658 if (!buffer) { |
| 3659 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); |
| 3660 return false; |
| 3661 } |
| 3662 if (!buffer->mapped()) { |
| 3663 SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped"); |
| 3664 return false; |
| 3665 } |
| 3666 buffer->set_mapped(false); |
| 3667 |
| 3668 return true; |
| 3669 } |
| 3670 |
3483 // Include the auto-generated part of this file. We split this because it means | 3671 // Include the auto-generated part of this file. We split this because it means |
3484 // we can easily edit the non-auto generated parts right here in this file | 3672 // we can easily edit the non-auto generated parts right here in this file |
3485 // instead of having to edit some template or the code generator. | 3673 // instead of having to edit some template or the code generator. |
3486 #include "../client/gles2_implementation_impl_autogen.h" | 3674 #include "../client/gles2_implementation_impl_autogen.h" |
3487 | 3675 |
3488 } // namespace gles2 | 3676 } // namespace gles2 |
3489 } // namespace gpu | 3677 } // namespace gpu |
OLD | NEW |